{"id":19588903,"url":"https://github.com/wiiseguy/aqa","last_synced_at":"2025-04-27T12:31:59.292Z","repository":{"id":45618606,"uuid":"339830086","full_name":"Wiiseguy/aqa","owner":"Wiiseguy","description":"Dependency-less Test Runner for Node.js","archived":false,"fork":false,"pushed_at":"2024-07-04T15:00:03.000Z","size":234,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-11T05:54:13.207Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wiiseguy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-17T19:15:14.000Z","updated_at":"2024-07-04T15:00:06.000Z","dependencies_parsed_at":"2023-12-01T15:27:55.175Z","dependency_job_id":"7f77b6e7-c2a9-4daf-8913-1a3db99370c8","html_url":"https://github.com/Wiiseguy/aqa","commit_stats":{"total_commits":169,"total_committers":2,"mean_commits":84.5,"dds":0.00591715976331364,"last_synced_commit":"e1ba4550451b4066ce66af688eb8f2065137b4d5"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wiiseguy%2Faqa","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wiiseguy%2Faqa/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wiiseguy%2Faqa/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wiiseguy%2Faqa/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wiiseguy","download_url":"https://codeload.github.com/Wiiseguy/aqa/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224069367,"owners_count":17250456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T08:16:30.691Z","updated_at":"2024-11-11T08:16:32.154Z","avatar_url":"https://github.com/Wiiseguy.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aqa [![ci](https://github.com/Wiiseguy/aqa/actions/workflows/node.js.yml/badge.svg)](https://github.com/Wiiseguy/aqa/actions/workflows/node.js.yml) [![codecov](https://codecov.io/gh/Wiiseguy/aqa/branch/main/graph/badge.svg?token=O7IF9PWJKP)](https://codecov.io/gh/Wiiseguy/aqa) ![npm](https://img.shields.io/npm/v/aqa)\n\u003e Dependency-less Test Runner for Node.js\n\n**aqa** is a light-weight and **a** **q**uick **a**lternative to [ava](https://github.com/avajs/ava), with a similar API.\n\n\n\u003cbr\u003e\n\n## Installation\n```\nnpm i aqa -D\n```\n## Features\n- **Dependency-free**: No dependencies, leverages many of Node.js modern built-in modules.\n- **Fast**: Runs tests in parallel by default.\n- **Watch mode**: Automatically re-run tests when files change.\n- **Simple**: No configuration needed, just run your tests!\n- **Powerful**: Supports many asserts, async/await, Sourcemaps\n- **Coverage**: Code coverage support via your favorite coverage tool.\n- **TypeScript**: First-class TypeScript support, with type definitions for all assertions.\n- **CI integration**: Easily run tests in CI pipelines. \n- **Reporting**: Generate JUnit and TAP reports.\n\n\u003cbr\u003e\n\n## Usage\n\n### Simple single-file usage\n\n_your.tests.js:_\n```js\nconst test = require('aqa')\nconst myLib = require('./my-lib')\n\ntest('Test our library', t =\u003e {    \n  t.is(myLib.add(1, 1), 2);\n  t.not(myLib.add(2, 2), 3);\n  t.true(myLib.isPrime(3));\n  t.false(myLib.isOdd(2));\n})\n\ntest('Test something async', async t =\u003e {\n  let result = await myLib.asyncAdd(1, 1); \n  t.is(result, 2);\n})\n\n```\n\n`\nnode your.tests.js\n`\n### Integration\nTo run multiple tests and integrate CI testing with your package, you need to change your package.json's `test` in the `scripts` section to `\"aqa\"`:\n```json\n\"scripts\": {\n  \"test\": \"aqa\"\n},\n```\nThen, to run all your tests: `npm run test`\n\nAll files anywhere in your package's directory (and subdirectories, excluding `node_modules` and directories that start with a single `_` ) that match the following patterns will be run: \n```\ntest.js\ntests.js\n*.test.js\n*.tests.js\n*/test-*.js\n*.spec.js\n**/test/*.js\n**/tests/*.js\n**/__tests__/*.js\n```\n\nIf your test files are named differently, for instance *.unit-test.js, you can write your test script like this:\n```json\n\"scripts\": {\n  \"test\": \"aqa *.unit-test.js\"\n},\n```\n\n### Watch mode\nTo automatically run tests whenever you modify your files, **aqa** has a watch mode. If you desire this functionality, add a new script to your package.json:\n```json\n\"scripts\": {\n  \"test\": \"aqa\",\n  \"test:watch\": \"aqa --watch\"\n},\n```\nTo start the watch script, run `npm run test:watch`.\n\nLike with the `test` script, you can watch files other than `*.test.js`:\n```json\n\"test:watch\": \"aqa *.foo.js --watch\"\n```\n\n\u003cbr\u003e\n\n## Coverage\n**aqa** can be easily integrated with coverage tools such as [nyc](https://github.com/istanbuljs/nyc) and [c8](https://github.com/bcoe/c8). \n\nTo enable coverage with [c8](https://github.com/bcoe/c8), add the following to your package.json:\n```jsonc\n\"scripts\": {\n  // Other scripts\n  \"test:coverage\": \"c8 npm test\"\n},\n```\nOr to run tests with [nyc](https://github.com/istanbuljs/nyc):\n```jsonc\n\"scripts\": {\n  // Other scripts\n  \"test:coverage\": \"nyc aqa\"\n},\n```\n\nRunning `test:coverage` will produce something like this:\n```\n--------------|---------|----------|---------|---------|-----------------------\nFile          | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s\n--------------|---------|----------|---------|---------|-----------------------\nAll files     |    99.2 |    96.63 |   98.57 |    99.2 | \n my-lib.js    |   97.74 |    95.18 |   98.55 |   97.74 | 20-21,190-191,231-232\n test.js      |     100 |      100 |     100 |     100 | \n--------------|---------|----------|---------|---------|-----------------------\n```\n\nTo add special reporters such as LCOV and HTML, check the README pages of the code coverage package.\n\n\u003e Note: [c8](https://github.com/bcoe/c8) is recommended, because it uses Node's built-in [V8 coverage tools](https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#node_v8_coveragedir) and it is many times faster than [nyc](https://github.com/istanbuljs/nyc).\n\n\u003cbr\u003e\n\n## API\n### Assertion\nThe callback parameter for `test()` wraps many assertion methods (in this case `t`):\n```js\ntest('Test name', t =\u003e {    \n  // Your assertions\n})\n```\nThese assertion methods are currently supported:\n#### `t.is(actual, expected, message?)`\nAsserts that `actual` is equal to `expected`.\n#### `t.not(actual, notEpected, message?)`\nAsserts that `actual` is **not** equal to `notEpected`.\n#### `t.near(actual, expected, delta, message?)`\nAsserts that `actual` is equal to `expected` within the precision of `delta`.\n#### `t.notNear(actual, expected, delta, message?)`\nAsserts that `actual` is **not** equal to `expected` within the precision of `delta`.\n#### `t.deepEqual(actual, expected, message?)`\nAsserts that `actual` is deeply equal to `expected`. `test.ignore` can be used to skip certain properties, i.e.:\n```js\nlet actual = { a: 3, b: 'ok', c: 7 }\nt.deepEqual(actual, {\n  a: 3,\n  b: 'ok',\n  c: test.ignore\n})\n```\nDifferences are reported with a minus `-` for actual values and plus `+` for expected values.\n\nYou may also use `test.ignoreExtra()` to only assert the given properties in the expected object:\n```js\nlet actual = { a: 3, b: 'ok', c: 7 }\nt.deepEqual(actual, test.ignoreExtra({\n  b: 'ok',\n}))\n```\n#### `t.notDeepEqual(actual, expected, message?)`\nAsserts that `actual` is **not** deeply equal to `expected`.\n#### `t.true(value, message?)`\nAsserts that `value` is true.\n#### `t.false(value, message?)`\nAsserts that `value` is false.\n#### `t.throws(fn, opts?, message?)`\nAsserts that `fn` throws an exception.\n```js\nfunction uhOh() {\n  throw new Error(\"Uh oh.\");\n}\n\nt.throws(_ =\u003e {\n  uhOh();\n})\n```\nYou can also check for specific types of exception. If the exception does not match it, the test will fail:\n```js\nt.throws(_ =\u003e {\n  uhOh();\n}, { instanceOf: TypeError })\n```\n#### `t.throwsAsync(fn, opts?, message?)`\nThe asynchronous version of t.throws(). Note the addition of async/await.\n```js\ntest('Async test', async t =\u003e {\n  await t.throwsAsync(async _ =\u003e {\n    await uhOhAsync();\n  })\n})\n```\nYou can also check for specific types of exception. If the exception does not match it, the test will fail:\n```js\nawait t.throws(async _ =\u003e {\n  await uhOhAsync();\n}, { instanceOf: TypeError })\n```\n#### `t.notThrows(fn, message?)`\nAsserts that `fn` does not throw an exception.\n#### `t.notThrowsAsync(fn, message?)`\nAsserts that async function or Promise `fn` does not throw an exception.\n### Utility methods\n#### `t.log(message, ...arguments?)`\nSimilar to `console.log`, but helps you easily find for which test method you've logged information. \n#### `t.disableLogging()`\nSuppresses any calls to `console.log`, `console.warn`, `console.error`, etc. for the current testcase. Note that logging is enabled again automatically after the testcase has completed.\n\n### Mocking\n(Available in 1.6.8+) **aqa** supports mocking with the `t.mock()` method. This method lets you mock a method on an object or library. Mocked methods are restored automatically after each test.\n\n```js\nconst test = require('aqa')\nconst Http = require('SomeHttpLibrary')\n\ntest('Mocking', async t =\u003e {\n  const mockedGet = t.mock(Http, 'get', async _ =\u003e {\n    return { statusCode: 200, body: 'Hello World!' }\n  })\n\n  const result = await Http.get('https://example.com')\n  t.is(result.statusCode, 200)\n  t.is(result.body, 'Hello World!')\n\n  t.is(mockedGet.calls.length, 1)\n})\n```\t\nIn the example above, we mock the `get` method on the `Http` object. The mocked method returns a promise that resolves to a response object. We then assert that the response object has the expected properties. Finally, we assert that the mocked method was called once.\n\nBy mocking the `get` method here, any other code that imports `SomeHttpLibrary` and calls `Http.get` will also use the mocked method. This is useful for testing code that uses external libraries.\n\n`t.mock()` returns a `Mock` object with the following properties:\n#### `Mock.restore()`\nRestores the mocked method back to its original implementation. If you don't call this method, the mocked method will be restored automatically after each test.\n#### `Mock.calls`\nAn array of all calls to the mocked method. Each call is an array of arguments passed to the mocked method.\n\n#### Global mocking\n(Available in 1.6.9+) **aqa** also supports global mocking via the `test.mock()` method. This method works similarly to `t.mock()`, but it mocks the method globally for all tests in the current file.\n\n```js\nconst test = require('aqa')\nconst Http = require('SomeHttpLibrary')\n\nconst mockedGet = test.mock(Http, 'get', async _ =\u003e {\n  return { statusCode: 200, body: 'Hello World!' }\n})\n\ntest('Mocking', async t =\u003e {\n  let result = await Http.get('https://example.com')\n  t.is(result.statusCode, 200)\n  t.is(result.body, 'Hello World!')\n\n  t.is(mockedGet.calls.length, 1)\n})\n```\t\n\n\n\n### Hooks\n(Available in 1.6.0+) The following hooks are available:\n```js\nconst test = require('aqa')\n\ntest.before(t =\u003e {    \n  // Your set-up and assertions\n  // This is only ran once per test file\n})\n\ntest.after(t =\u003e {    \n  // Your tear-down and assertions\n  // This is only ran once per test file\n})\n\ntest.beforeEach(t =\u003e {    \n  // Your set-up and assertions\n  // This is ran before each test\n})\n\ntest.afterEach(t =\u003e {    \n  // Your tear-down and assertions\n  // This is ran after each test\n})\n```\n\n### Skipping a test file\n(Available in 1.6.7+) You can skip all tests in a file by calling `test.skipFile()`:\n```js\nconst test = require('aqa')\n\ntest.skipFile('Reason for skipping this file here');\n```\n\n### Skipping a test\n(Available in 1.6.9+) You can skip individual tests by calling `test.skip()` instead of the usual `test()`:\n```js\nconst test = require('aqa')\n\ntest('This test will run', t =\u003e {\n  // Your assertions\n})\n\ntest.skip('This test will not run', t =\u003e {\n  // ...\n})\n```\n\n### Solo running tests\n(Available in 1.6.9+) You can run only a single test by calling `test.solo()` instead of the usual `test()`. This will effectively skip all other tests in the file.\n```js\nconst test = require('aqa')\n\ntest('This test will not run', t =\u003e {\n  // ...\n})\n\ntest.solo('Test name', t =\u003e {    \n  // Your assertions\n})\n\ntest('This test will not run either', t =\u003e {\n  // ...\n})\n\n```\nNote: Any defined tests hooks (before, after) will still run as usual.\n\n\u003cbr\u003e\n\n## TypeScript\n(Available in 1.3.7+) To write **aqa** test files TypeScript, you will need to enable source maps in your `tsconfig.json`.\n\n```jsonc\n\"compilerOptions\": {\n  // Can be any other path, but .js files will need to be emitted\n  \"outDir\": \"./dist\",   \n  \"sourceMap\": true,\n  \"module\": \"commonjs\",\n  // other compiler options\n}\n```\nFor an optimal development flow, run the following tasks (add them to `package.json` scripts first):\n- `tsc --watch`\n- `aqa --watch`\n\nNow let's create a file named *your.tests.ts*:\n```ts\nimport test = require('aqa')\nimport myLib from './my-lib'\n\ntest('Should fail', t =\u003e {\n    t.is(myLib.add(1, 1), 3)\n})\n```\n\nThis will fail with something like the following output:\n```\nFAILED:  \"Should fail\"\nD:\\DEV\\YourProject\\tests\\your.tests.ts:6:10 [SourceMap]\n```\n\nNote the source-mapped location. This will allow you to Ctrl+Click on the location in your IDE to easily jump to the original test file.\n\n\u003cbr\u003e\n\n### Source maps\nSource maps are a way to map the original source code to the generated code. This is useful for debugging and development. Languages or tools that compile to JavaScript, like TypeScript, CoffeeScript, ClojureScript, BabelJS, etc., can generate source maps.\nWe've only covered TypeScript here, but if you're using another language that has a compiler that generates source maps, it should work with **aqa**. \n\n\n\u003cbr\u003e\n\n## Reporting\n(Available in 1.6.1+) **aqa** supports reporting test results to a file. The current supported reporters are `junit` and `tap`. To enable it, add the following to your `package.json`:\n```jsonc\n{  \n  \"aqa\": {\n    \"reporter\": \"junit\"\n  }\n}\n```\n### JUnit\nThe `junit` reporter will generate a JUnit XML file for each test file in the `.aqa-output/reports` folder. You can then use this file in your CI/CD pipeline to generate reports.\n\nSee [Config](#config) for more information.\n\n### TAP\nThe `tap` reporter will output the test results in the [TAP version 13](https://testanything.org/) format to the console / stdout. Currently, this report is simplified and does not include stack traces.\n\n\n\n\u003cbr\u003e\n\n## CLI parameters\n**aqa** can be run from the terminal like `npx aqa tests/test-*.js` with the following supported parameters:\n#### `--watch`\nRuns **aqa** in watch mode. See [watch mode](#watch-mode) for more information.\n#### `--verbose`\nAdds verbose logging.\nExample: `aqa --verbose`\n#### `--no-concurrency`\nDisables concurrency. This will run all tests sequentially.\nExample: `aqa --no-concurrency`\n\n\u003cbr\u003e\n\n## Config\n**aqa** will try to check the `package.json` from where it was ran from for a section named `\"aqa\"`.\n\n```jsonc\n{  \n  \"aqa\": {\n    \"verbose\": true,\n    \"concurrency\": true,\n    \"reporter\": \"\", \n    \"reporterOptions\": {\n      \"outputDir\": \"test-results/\" \n    }\n  }\n}\n```\n\nSupported config:\n- `verbose` - If true, enables verbose output. (default = false)\n  - Can also be set via the `AQA_VERBOSE` environment variable.\n- `concurrency` - If false, disables concurrency. (default = true)\n  - Can also be set via the `AQA_CONCURRENCY` environment variable.\n- `reporter` - The reporter to use, can be `junit` or `tap`. Default = \"\" (no reporter)\n  - Can also be set via the `AQA_REPORTER` environment variable.\n- `reporterOptions` - Options for the reporter. \n  - `outputDir` - The output directory for the reporter. Default = \".aqa-output/reports\"\n    - Can also be set via the `AQA_REPORTER_OUTPUT_DIR` environment variable.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiiseguy%2Faqa","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwiiseguy%2Faqa","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwiiseguy%2Faqa/lists"}