{"id":15496432,"url":"https://github.com/mike-north/qunit-decorators","last_synced_at":"2025-04-14T06:37:23.844Z","repository":{"id":32756349,"uuid":"141785265","full_name":"mike-north/qunit-decorators","owner":"mike-north","description":"QUnit decorators for use with ES6 or TypeScript","archived":false,"fork":false,"pushed_at":"2025-04-07T15:32:14.000Z","size":1864,"stargazers_count":4,"open_issues_count":11,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T22:35:39.685Z","etag":null,"topics":["decorators","emberjs","qunit","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/mike-north.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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":"2018-07-21T05:53:45.000Z","updated_at":"2025-04-07T11:36:24.000Z","dependencies_parsed_at":"2023-02-16T12:45:46.005Z","dependency_job_id":"bfc4dc71-ae4b-4588-a160-5a59cb2a2c76","html_url":"https://github.com/mike-north/qunit-decorators","commit_stats":{"total_commits":287,"total_committers":6,"mean_commits":"47.833333333333336","dds":0.5888501742160279,"last_synced_commit":"c519a3daec2e5a0ab00c49d9a62396e0aef7d791"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mike-north%2Fqunit-decorators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mike-north%2Fqunit-decorators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mike-north%2Fqunit-decorators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mike-north%2Fqunit-decorators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mike-north","download_url":"https://codeload.github.com/mike-north/qunit-decorators/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248836291,"owners_count":21169370,"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":["decorators","emberjs","qunit","typescript"],"created_at":"2024-10-02T08:25:13.174Z","updated_at":"2025-04-14T06:37:23.800Z","avatar_url":"https://github.com/mike-north.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# QUnit Decorators\n\nAllow [QUnit](https://qunitjs.com/) tests to be written and organized with [JavaScript](https://github.com/tc39/proposal-decorators) or [TypeScript decorators](https://www.typescriptlang.org/docs/handbook/decorators.html). Inspired by [mocha-typescript](https://github.com/pana-cc/mocha-typescript).\n\n[![Build Status](https://travis-ci.org/mike-north/qunit-decorators.svg?branch=master)](https://travis-ci.org/mike-north/qunit-decorators) [![Version](https://img.shields.io/npm/v/qunit-decorators.svg)](https://www.npmjs.com/package/qunit-decorators) [![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\n\n## Setting this up in your project\n\n```sh\nnpm install --save-dev qunit-decorators\n```\n\nor\n\n```sh\nyarn add -D qunit-decorators\n```\n\n## Writing your tests\n\nWhen using qunit-decorators, you’ll use classes organize modules, and methods for your tests\n\n```ts\nimport { suite, test } from 'qunit-decorators';\n\n@suite // \u003c-- decorate your modules with @suite\nclass UserLoginTests {\n\n  // ↓ decorate your test methods with @test\n  @test 'login without password should fail'(assert: Assert) {\n    let { result } = loginWithoutPassword(); // the thing being tested\n    assert.equal(result, 'ERROR', 'User receives an error'); // ✅\n  }\n  \n  foo() {} // \u003c-- You're free to put other non-test methods on the class too!\n}\n```\n\nIn the example above your test module would get its name from the class (`UserLoginTests`), and it would contain a test that gets its name from the method (`login without password should fail`). If you want to have a method name that's different from the name of the test, you can also pass an argument to these decorators.\n\n_see: [QUnit.module](https://api.qunitjs.com/QUnit/module) and [QUnit.test](https://api.qunitjs.com/QUnit/test)_\n\n\n```ts\nimport { suite, test } from 'qunit-decorators';\n\n@suite('User authentication test suite')\nclass UserLoginTests {\n\n  @test('Missing password case errors as expected')\n  testMethod(assert: Assert) {\n    let { result } = loginWithoutPassword(); // the thing being tested\n    assert.equal(result, 'ERROR', 'User receives an error'); // ✅\n  }\n\n}\n```\n\n### Skipping \u0026 Focusing\n\nSometimes it's useful to temporarily focus on a subset of tests while writing new code. QUnit allows you to focus on a combination of modules and tests within modules.\n\n_see: [QUnit.only](https://api.qunitjs.com/QUnit/only)_\n\n```ts\nimport { suite, test } from 'qunit-decorators';\n\n@suite.only('Working on some new tests')\nclass MyNewTests { ... }\n\n@suite\nclass ExistingFeatureTests {\n\n  @test.only 'Fixing something else too'() { ... }\n\n}\n```\n\nAlternatively, you may choose specific tests or modules to skip in a similar way\n\n_see: [QUnit.skip](https://api.qunitjs.com/QUnit/skip)_\n\n```ts\nimport { suite, test } from 'qunit-decorators';\n\n@suite.skip('Things that take a long time')\nclass SlowTests { ... }\n\n@suite\nclass ExistingFeatureTests {\n\n  @test.skip 'a buggy test I am still working on'() { ... }\n\n}\n```\n\nParticularly while in the middle of a code change, you'll sometimes have tests that won't pass because you haven't gotten to them yet. You may mark these tests with `@test.todo`, and they'll pass as long as at least one assertion fails.\n\n_see: [QUnit.todo](https://api.qunitjs.com/QUnit/todo)_\n\n```ts\nimport { suite, test } from 'qunit-decorators';\n\n@suite\nclass WIPBugFixes {\n\n  @test.todo 'We\\'ll get to this Soon™️'(assert) {\n    assert.ok(false);\n  }\n\n}\n```\n\n### Module Hooks\n\nWhen defining a QUnit suite, you have an opportunity to set up one or more hooks to customize code that runs before or after your tests.\n\n_see: [QUnit.module](https://api.qunitjs.com/QUnit/module)_\n\n* *before* - Runs before the first test.\n* *beforeEach* - Runs before each test.\n* *afterEach* - Runs after each test.\n* *after* -\tRuns after the last test.\n\nThere are a variety of ways you can provide functions for hooks, and qunit-decorators doesn't interfere with their normal capabilities and operation (i.e.,  if you return a promise from a hook, QUnit will wait for that promise to resolve before running other hooks or tests).\n\n\nYou may define hooks as member functions on the module's class\n\n```ts\nimport { suite, test } from 'qunit-decorators';\nimport Pretender from 'pretender';\n\nlet server;\n\n@suite('A better test module')\nclass BetterModule {\n  before() {\n    server = new Pretender();\n  }\n  after() {\n    server.shutdown();\n  }\n  \n  beforeEach() { ... }\n  afterEach() { ... }\n}\n```\nor pass the hooks passed into the `@suite` decorator as an object\n\n```ts\nimport { suite, test } from 'qunit-decorators';\nimport Pretender from 'pretender';\n\nlet server;\nconst myHooks = {\n  before() {\n    // Start intercepting XHR\n    server = new Pretender();\n  },\n  after() {\n    // Restore original XHR\n    server.shutdown();\n  }\n}\n\n@suite('A good test module', myHooks)\nclass GoodModule {\n\n}\n```\nor pass in a callback that receives an object which may be used to register hooks\n\n```ts\nimport { suite, test } from 'qunit-decorators';\nimport Pretender from 'pretender';\n\n@suite('A better test module', hooks =\u003e {\n  let server;\n  hooks.before(() =\u003e {\n    server = new Pretender();\n  });\n  hooks.after(() =\u003e {\n    server.shutdown();\n  });\n})\nclass BetterModule {\n\n}\n```\n---\n\n(c) 2018 LinkedIn\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmike-north%2Fqunit-decorators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmike-north%2Fqunit-decorators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmike-north%2Fqunit-decorators/lists"}