Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
@tapjs/core
Advanced tools
@tapjs/core is a core library for the Test Anything Protocol (TAP) framework, which is used for writing and running tests in JavaScript. It provides a set of tools and utilities to create, manage, and execute tests, making it easier to ensure code quality and reliability.
Basic Test Creation
This feature allows you to create basic tests using the TAP framework. The code sample demonstrates a simple test that checks if 1 + 1 equals 2.
const t = require('@tapjs/core');
t.test('basic test', t => {
t.equal(1 + 1, 2, '1 + 1 should equal 2');
t.end();
});
Asynchronous Testing
This feature supports asynchronous testing, allowing you to test functions that return promises or use async/await. The code sample shows how to test an asynchronous function.
const t = require('@tapjs/core');
t.test('async test', async t => {
const result = await someAsyncFunction();
t.equal(result, expectedValue, 'Async function should return expected value');
t.end();
});
Nested Tests
This feature allows you to create nested tests, which can help organize and structure your test cases better. The code sample demonstrates a parent test containing a child test.
const t = require('@tapjs/core');
t.test('parent test', t => {
t.test('child test', t => {
t.equal(2 * 2, 4, '2 * 2 should equal 4');
t.end();
});
t.end();
});
Mocha is a feature-rich JavaScript test framework running on Node.js and in the browser, making asynchronous testing simple and fun. It provides a variety of interfaces for writing tests, including BDD, TDD, and exports-style. Compared to @tapjs/core, Mocha offers more flexibility in terms of test interfaces and has a larger ecosystem of plugins and integrations.
Jest is a delightful JavaScript testing framework with a focus on simplicity. It works out of the box for most JavaScript projects and provides a rich API for writing tests. Jest includes built-in mocking, assertion, and coverage tools. Compared to @tapjs/core, Jest is more opinionated and comes with more built-in features, making it easier to get started with testing.
AVA is a test runner for Node.js with a concise API, detailed error output, and process isolation. It runs tests concurrently, which can lead to faster test execution. Compared to @tapjs/core, AVA emphasizes simplicity and performance, making it a good choice for projects with a large number of tests.
@tapjs/core
This is the pluggable core of node-tap.
The TestBase
class has the basic flow-control and child-test
aspects of a tap Test
object, but only the t.pass()
and
t.fail()
assertions.
All other assertions and features are added via plugins.
Tap plugins are a function that takes a Test
object and an
options
object, and returns an object that is used as the
extension.
For example, to add a isString
method to all tests, you could
define a plugin like this:
import { TestBase, TapPlugin, AssertionOpts } from '@tapjs/core'
export const plugin: TapPlugin = t => {
return {
isString: (
s: any,
msg: string = 'expect string',
extra: AssertionOpts = {}
) => {
// note: 'this' here is the plugin object
if (typeof s === 'string') {
return t.pass(msg)
} else {
return t.fail(msg, {
...extra,
expect: 'string',
actual: typeof s,
})
}
}
}
The object returned by a plugin can be any sort of thing. If you
want to use a class with private properties, that's totally fine
as well. Whatever type is expected as the second argument will
be combined with the built-in TestBaseOpts
interface, and
required when tests are instantiated.
import { TestBase, TapPlugin, AssertionOpts } from '@tapjs/core'
import { cleanup, render } from '@testing-library/react'
import { ReactElement } from 'react'
import { RenderResult } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
class ReactTest {
#result: RenderResult
constructor(node: ReactElement) {
this.#result = render(node)
}
findByText(text: string) {
return this.#result.findByText(text)
}
// add other helpful methods here...
}
export const plugin: TapPlugin = (t, { node: ReactElement }) => {
return new ReactTest(node)
}
When loaded, this plugin would make it so that every test must
supply a { node: ReactElement }
option, and would have a
t.findByText()
method.
The easiest way to load plugins is by running:
tap plugin add <package or local module>
This will also regenerate the Test class, so types are kept in sync.
Remove plugins with tap plugin remove <plugin>
.
Plugins are specified in the plugins
array of the root tap
config. That is, either .taprc
in the project directory, or
the "tap"
stanza in the package.json
file.
Whenever the plugins
option is changed, you must run tap generate
to generate the Test
class properly. This is done
automatically on demand when running tap
or tap run [...files]
, but its often a good idea to do so before writing
tests so that editor hinting is accurate.
Out of the box, tap comes with the following plugins loaded:
@tapjs/core/plugin/before-each
Adds t.beforeEach(fn)
@tapjs/core/plugin/after-each
Adds t.afterEach(fn)
@tapjs/core/plugin/stdin
Adds t.stdin()
@tapjs/core/plugin/spawn
Adds t.spawn()
@tapjs/asserts
All other assertions, like t.match()
,
t.type()
, t.has()
, and so on.@tapjs/snapshot
Providing the t.matchSnapshot()
method.@tapjs/fixture
Providing the t.testdir()
method.@tapjs/mock
Providing the t.mock()
method.To prevent loading any of these plugins, you can include them
in the plugins
config, prefixed with a !
. For example, if
you wanted to replace t.mock()
with a different mocking plugin,
you could do this:
{
"tap": {
"plugins": ["!@tapjs/mock", "my-mock-plugin"]
}
}
The first plugin in a list that provides a given method or property will be the one that "wins", as far as the object presented in test code is concerned.
However, within a given plugin, it only sees itself and the
TestBase
object it's been given. For example, if returning an
object constructed from a class defined in the plugin, this
will refer to that object, always.
// first-plugin
export const plugin = (t: TestBase) => {
return {
// this is the first plugin to register this value
// so this is what shows up on the Test object
myVal: 4,
getFirstPluginVal() {
return this.myVal // always returns 4
},
// this is the first plugin to register this method
// so this is what shows up on the Test object
getFour() {
return 4
},
}
}
// second-plugin
export const plugin = (t: TestBase) => {
return {
// user will never see this, because first-plugin registered it
myVal: 5,
getSecondPluginValue() {
return this.myVal // always returns 5
},
// overridden, this isn't the 'getFour' that the user will see
getFour() {
return 'four'
},
}
}
Then in the test:
import t from 'tap'
console.log(t.myVal) // 4, not 5
console.log(t.getFour()) // 4, not 'four'
console.log(t.getFirstPluginVal()) // 4
console.log(t.getSecondPluginVal()) // 5
If you need access to the constructed Test
object, you can get
that after the initial plugin load, via t.t
. However, it will
be undefined
until all plugins are done loading.
// my-plugin.ts
export const plugin = (t: TestBase) => {
// here, t.t === undefined
return {
someMethod() {
// here, t.t is the object with all the plugins applied
},
}
}
FAQs
pluggable core of node-tap
The npm package @tapjs/core receives a total of 117,511 weekly downloads. As such, @tapjs/core popularity was classified as popular.
We found that @tapjs/core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.