├── demos ├── bundlers │ ├── favicon.ico │ ├── test │ │ ├── package.json │ │ ├── src.js │ │ ├── .eslintrc.json │ │ ├── import-named.js │ │ ├── import-default.js │ │ ├── require-sub.cjs │ │ └── require-default.cjs │ ├── README.md │ └── package.json ├── testem │ ├── qunit │ ├── testem.json │ ├── add.js │ ├── add.test.js │ ├── package.json │ ├── README.md │ └── test.html ├── grunt-contrib-qunit │ ├── qunit │ ├── package.json │ ├── README.md │ ├── fail-no-tests.html │ ├── pass-basic.html │ ├── fail-assert.html │ ├── Gruntfile.js │ └── fail-uncaught.html ├── nyc │ ├── .gitignore │ ├── src │ │ ├── add.js │ │ └── subtract.js │ ├── index.js │ ├── test │ │ └── add.js │ ├── package.json │ └── README.md ├── karma-qunit │ ├── fail-assert.js │ ├── fail-global-error.js │ ├── pass-config.js │ ├── pass-basic.js │ ├── package.json │ ├── README.md │ └── karma.conf.js ├── q4000-qunit.html ├── qunit-onerror-early.html └── testem.js ├── docs ├── CNAME ├── blog.md ├── favicon.ico ├── img │ ├── logo.png │ ├── logo-qunit@2x.png │ ├── 2011-logo-qunit.png │ ├── 2012-logo-qunit.png │ ├── 2012b-logo-qunit.png │ ├── QUnit-Logo-Large.png │ ├── 2012-logo-qunit@2x.png │ ├── 2012-website-qunit.png │ ├── 2013-website-qunit.png │ ├── 2020-website-qunit.png │ └── 2013-logo-qunit_color_study.png ├── blog │ ├── tag │ │ ├── feature.md │ │ ├── release.md │ │ └── link.md │ └── archive.md ├── resources │ ├── perf-chrome.png │ ├── perf-firefox.png │ ├── 2014-brazil-hacking.jpg │ ├── 2017-qunit-cli-demo.jpg │ ├── 2018-parallel-prototype.jpg │ ├── 2023-speedlify-leaderboard.png │ ├── 2024-qunit-3-alpha-4-demo.png │ ├── 2025-stacktrace-assert-html.png │ ├── 2025-stacktrace-error-after.png │ ├── 2025-stacktrace-error-before.png │ ├── 2025-stacktrace-assert-tap-after.png │ ├── 2025-stacktrace-assert-tap-before.png │ ├── example-index.html │ ├── example-add.html │ ├── calc.js │ └── calc.test.js ├── api │ ├── removed.md │ ├── async.md │ ├── deprecated.md │ ├── extension │ │ ├── index.md │ │ └── QUnit.assert.md │ ├── callbacks │ │ └── index.md │ ├── QUnit │ │ └── index.md │ ├── reporters │ │ └── index.md │ ├── assert │ │ └── index.md │ ├── config │ │ ├── requireExpects.md │ │ ├── failOnZeroTests.md │ │ ├── scrolltop.md │ │ ├── collapse.md │ │ ├── altertitle.md │ │ ├── hidepassed.md │ │ ├── testId.md │ │ └── moduleId.md │ └── index.md ├── _data │ ├── authors.yaml │ ├── sidebar_blog.yml │ ├── sidebar_api.yml │ └── sitenav.yml ├── 404.md ├── Gemfile ├── _posts │ ├── 2017-04-09-project-lead.md │ ├── 2020-09-29-project-lead.md │ ├── 2011-10-06-qunit-1-0-0.md │ ├── 2015-01-20-qunit-1-17-1.md │ ├── 2017-03-19-qunit-2-2-1.md │ ├── 2015-09-29-project-lead.md │ ├── 2018-10-17-qunit-2-7-1.md │ ├── 2023-07-11-eslint-assert-expect.md │ ├── 2015-07-08-qunit-migrate.md │ ├── 2016-04-12-qunit-1-23-1.md │ ├── 2020-10-05-qunit-2-11-3.md │ ├── 2020-08-25-qunit-2-11-1.md │ ├── 2022-10-22-qunit-2-19-3.md │ ├── 2014-12-03-upgrade-guide-2.md │ ├── 2016-05-17-1000-commits.md │ ├── 2020-07-31-speedlify-category.md │ ├── 2019-01-07-qunit-2-9-1.md │ ├── 2021-09-09-qunit-2-17-1.md │ ├── 2022-05-01-qunit-2-19-1.md │ ├── 2017-01-05-qunit-2-1-1.md │ ├── 2025-10-09-qunit-2-24-2.md │ ├── 2025-11-29-qunit-2-24-3.md │ ├── 2017-06-02-qunit-2-3-3.md │ ├── 2014-08-25-brazil-hacking.md │ ├── 2016-02-23-qunit-1-22-0.md │ ├── 2017-04-17-qunit-2-3-2.md │ ├── 2018-08-19-qunit-2-6-2.md │ ├── 2024-08-18-qunit-2-22-0.md │ ├── 2016-07-23-qunit-2-0-1.md │ ├── 2017-03-30-cli-support.md │ ├── 2020-07-04-qunit-2-10-1.md │ ├── 2020-09-09-qunit-2-11-2.md │ ├── 2017-04-10-qunit-2-3-1.md │ ├── 2019-02-21-qunit-2-9-2.md │ ├── 2023-09-15-qunitx.md │ ├── 2018-05-15-qunit-2-6-1.md │ ├── 2012-05-04-qunit-1-6-0.md │ ├── 2021-03-14-qunit-2-14-1.md │ ├── 2012-06-14-qunit-1-8-0.md │ ├── 2024-12-03-qunit-2-23-0.md │ ├── 2013-09-13-wordpress-qunit-for-javascript-unit-tests.md │ ├── 2023-01-23-qunit-2-19-4.md │ ├── 2025-01-22-wdio-qunit-service.md │ ├── 2017-03-29-qunit-2-3-0.md │ ├── 2024-02-15-qunit-2-20-1.md │ ├── 2016-02-01-qunit-1-21-0.md │ ├── 2018-02-27-qunit-2-5-1.md │ ├── 2018-10-11-parallel-prototype.md │ ├── 2022-03-29-qunit-2-18-1.md │ ├── 2019-01-06-qunit-2-9-0.md │ ├── 2025-08-19-sapui5-qunit.md │ ├── 2014-01-31-qunit-1-14-0.md │ ├── 2017-10-21-qunit-2-4-1.md │ ├── 2017-11-06-npm-package.md │ ├── 2016-03-25-qunit-1-23-0.md │ ├── 2013-03-09-javascript-jabber-podcast.md │ ├── 2015-09-01-qunit-1-19-0.md │ ├── 2011-11-24-qunit-1-2-0.md │ ├── 2015-04-03-qunit-1-18-0.md │ ├── 2014-01-04-qunit-1-13-0.md │ ├── 2015-01-19-qunit-1-17-0.md │ ├── 2012-04-04-qunit-1-5-0.md │ ├── 2020-05-02-qunit-2-10-0.md │ ├── 2018-11-02-qunit-2-8-0.md │ ├── 2017-04-09-whats-new-in-qunit-emberconf.md │ ├── 2012-07-11-qunit-1-9-0.md │ ├── 2023-09-23-qunit-2-20-0.md │ ├── 2018-10-10-qunit-2-7-0.md │ ├── 2015-01-12-sitepoint.md │ ├── 2019-10-08-qunit-2-9-3.md │ └── 2025-01-25-qunit-2-24-1.md ├── badge.md ├── _sass │ └── amethyst-variables.scss └── plugins.md ├── test ├── cli │ └── fixtures │ │ ├── .gitignore │ │ ├── no-tests.js │ │ ├── syntax-error.js │ │ ├── test │ │ ├── extension.txt │ │ ├── extension.ts │ │ ├── first.js │ │ ├── nested │ │ │ └── second.js │ │ ├── extension.cjs │ │ └── extension.mjs │ │ ├── assert-expect-no-assertions.js │ │ ├── no-tests-failOnZeroTests.js │ │ ├── node_modules │ │ └── require-dep │ │ │ ├── index.js │ │ │ ├── module.js │ │ │ └── package.json │ │ ├── hanging-test.js │ │ ├── assert-expect-failure.js │ │ ├── glob │ │ ├── not-a.js │ │ ├── a-test.js │ │ └── sub │ │ │ └── nested-test.js │ │ ├── config-requireExpects.js │ │ ├── basic-one.js │ │ ├── too-many-done-calls.js │ │ ├── inception.tap.txt │ │ ├── config-noglobals-add.js │ │ ├── _load-filenotfound.tap.txt │ │ ├── config-noglobals-ignored.js │ │ ├── npm-reporter │ │ ├── package.json │ │ └── index.js │ │ ├── config-module.tap.txt │ │ ├── sourcemap │ │ ├── source.min.js │ │ ├── source.js │ │ └── source.min.js.map │ │ ├── _load-single-file.tap.txt │ │ ├── config-noglobals-remove.js │ │ ├── done-after-timeout.js │ │ ├── async-module-error-promise.js │ │ ├── _load-glob.tap.txt │ │ ├── only-test.tap.txt │ │ ├── uncaught-error-callbacks-begin.js │ │ ├── uncaught-error-callbacks-done.js │ │ ├── async-module-error-thenable.js │ │ ├── no-tests-failOnZeroTests.tap.txt │ │ ├── zero-assertions.tap.txt │ │ ├── basic-fail.js │ │ ├── perf-mark.tap.txt │ │ ├── basic-two.js │ │ ├── hooks-global-context.tap.txt │ │ ├── only-module-then-test.tap.txt │ │ ├── config-filter-string.tap.txt │ │ ├── config-noglobals-ignored.tap.txt │ │ ├── filter-modulename-insensitive.tap.txt │ │ ├── assert-throws-failure.js │ │ ├── _load-dir.tap.txt │ │ ├── filter-modulename.tap.txt │ │ ├── uncaught-error-in-hook.js │ │ ├── async-module-error.js │ │ ├── config-filter-regex-exclude.tap.txt │ │ ├── config-filter-regex.tap.txt │ │ ├── config-testTimeout.js │ │ ├── pending-async-after-timeout.js │ │ ├── uncaught-error-callback-testStart.tap.txt │ │ ├── _load-default.tap.txt │ │ ├── memory-leak-test-object.tap.txt │ │ ├── module-nested.tap.txt │ │ ├── zero-assertions.js │ │ ├── config-testId.tap.txt │ │ ├── _load-multiple-files.tap.txt │ │ ├── drooling-extra-done-outside.js │ │ ├── uncaught-error-callback-moduleDone.tap.txt │ │ ├── drooling-extra-done.js │ │ ├── hanging-test.tap.txt │ │ ├── config-testTimeout.tap.txt │ │ ├── uncaught-error-after-assert-async.js │ │ ├── timeout.tap.txt │ │ ├── config-noglobals-add.tap.txt │ │ ├── config-noglobals-remove.tap.txt │ │ ├── memory-leak-module-closure-filtered.tap.txt │ │ ├── pending-async-after-timeout.tap.txt │ │ ├── uncaught-error-callback-testStart.js │ │ ├── require-module-and-script.tap.txt │ │ ├── uncaught-error-callback-moduleDone.js │ │ ├── config-moduleId.tap.txt │ │ ├── done-after-timeout.tap.txt │ │ ├── no-tests.tap.txt │ │ ├── only-test-only-module-mix.tap.txt │ │ ├── test-if.tap.txt │ │ ├── _load-dir-file-glob.tap.txt │ │ ├── config-notrycatch-test-rejection.js │ │ ├── memory-leak-module-closure-unfiltered.tap.txt │ │ ├── seed.tap.txt │ │ ├── config-module.js │ │ ├── drooling-done.js │ │ ├── config-filter-string.js │ │ ├── only-module-flat.tap.txt │ │ ├── _sourcemap.tap.txt │ │ ├── assert-expect-failure.tap.txt │ │ ├── config-notrycatch-hook-rejection.js │ │ ├── timeout.js │ │ ├── callbacks-rejected.tap.txt │ │ ├── assert-throws-failure.tap.txt │ │ ├── only-test.js │ │ ├── async-test-throw.js │ │ ├── config-requireExpects.tap.txt │ │ ├── event-runEnd-memory.tap.txt │ │ ├── assert-expect-no-assertions.tap.txt │ │ ├── config-filter-regex-exclude.js │ │ ├── config-notrycatch-hook-rejection.tap.txt │ │ ├── config-testTimeout-invalid.js │ │ ├── uncaught-error-callbacks-done.tap.txt │ │ ├── config-notrycatch-test-rejection.tap.txt │ │ ├── uncaught-error-in-hook.tap.txt │ │ ├── uncaught-error-callbacks-begin.tap.txt │ │ ├── unhandled-rejection.js │ │ ├── preconfig-flat.tap.txt │ │ ├── only-module-then-test.js │ │ ├── drooling-done.tap.txt │ │ ├── config-filter-regex.js │ │ ├── syntax-error.tap.txt │ │ ├── too-many-done-calls.tap.txt │ │ ├── config-testTimeout-invalid.tap.txt │ │ ├── perf-mark.js │ │ ├── drooling-extra-done.tap.txt │ │ ├── only-module.tap.txt │ │ ├── uncaught-error-after-assert-async.tap.txt │ │ ├── callbacks-promises.tap.txt │ │ ├── module-nested.js │ │ ├── drooling-extra-done-outside.tap.txt │ │ ├── event-runEnd-memory.js │ │ ├── async-module-error.tap.txt │ │ ├── only-module-flat.js │ │ ├── assert-failure.js │ │ ├── callbacks-rejected.js │ │ ├── async-test-throw.tap.txt │ │ ├── inception.js │ │ ├── async-module-error-promise.tap.txt │ │ ├── async-module-error-thenable.tap.txt │ │ ├── unhandled-rejection.tap.txt │ │ ├── each-array-labels.js │ │ └── test-if.js ├── dynamic-import │ ├── sum.mjs │ ├── bar.js │ ├── foo.js │ └── index.js ├── benchmark │ ├── package.json │ ├── micro.js │ └── micro.html ├── main │ ├── modules-esm.mjs │ ├── callbacks.js │ ├── setTimeout.js │ └── events.js ├── reorderError1.js ├── reorderError2.js ├── perf-mark.html ├── reorder.html ├── webWorker.html ├── seed.html ├── startError.html ├── urlparams-filter.html ├── urlparams-module.html ├── urlparams-testId.html ├── perf-clear-marks.html ├── urlparams-moduleId.html ├── dynamic-import.html ├── module-skip.html ├── module-todo.html ├── browser-runner │ ├── amd.js │ ├── window-onerror.html │ ├── config-fixture-null.html │ ├── config-fixture-string.html │ ├── autostart.js │ ├── amd.html │ ├── config-fixture-null.js │ ├── window-onerror-preexisting-handler.html │ └── config-fixture-string.js ├── reporter-urlparams.html ├── only-each.html ├── events-filters.html ├── events-in-test.html ├── perf-clear-marks.js ├── preconfig-flat-testId.js ├── sandboxed-iframe--contents.html ├── urlparams-module.js ├── only-each.js ├── webWorker.js ├── preconfig-object.js ├── logs.html ├── preconfig-flat-testId.html ├── urlparams-testId.js ├── preconfig-object.html ├── node │ ├── storage.js │ └── storage-2.js ├── seed.js ├── preconfig-flat.html ├── urlparams-filter.js ├── perf-mark.js ├── preconfig-flat.js ├── sandboxed-iframe.js ├── urlparams-moduleId.js └── webWorker-worker.js ├── src ├── core │ ├── promise.js │ ├── version.js │ ├── qunit-commonjs.js │ ├── reporters.js │ ├── qunit-wrapper-bundler-require.js │ ├── hooks.js │ ├── logger.js │ └── qunit-wrapper-nodejs-module.js └── cli │ └── require-from-cwd.js ├── CODE_OF_CONDUCT.md ├── .gitattributes ├── .gitignore ├── SECURITY.md ├── .editorconfig ├── .github └── workflows │ ├── reproducible.yaml │ ├── spider-check.yaml │ └── typesense.yaml ├── docsearch.config.json └── .eslintrc.base.js /demos/bundlers/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | qunitjs.com 2 | -------------------------------------------------------------------------------- /demos/testem/qunit: -------------------------------------------------------------------------------- 1 | ../../qunit -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/qunit: -------------------------------------------------------------------------------- 1 | ../../qunit -------------------------------------------------------------------------------- /test/cli/fixtures/.gitignore: -------------------------------------------------------------------------------- 1 | /abcd 2 | /efgh 3 | -------------------------------------------------------------------------------- /demos/bundlers/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module" 3 | } 4 | -------------------------------------------------------------------------------- /docs/blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: posts 3 | title: QUnit Blog 4 | --- 5 | -------------------------------------------------------------------------------- /test/cli/fixtures/no-tests.js: -------------------------------------------------------------------------------- 1 | // This test file has no tests! 2 | -------------------------------------------------------------------------------- /demos/nyc/.gitignore: -------------------------------------------------------------------------------- 1 | /.nyc_output/ 2 | /coverage/ 3 | /node_modules/ 4 | -------------------------------------------------------------------------------- /test/cli/fixtures/syntax-error.js: -------------------------------------------------------------------------------- 1 | varIsNotDefined; // eslint-disable-line 2 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /docs/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/logo.png -------------------------------------------------------------------------------- /demos/bundlers/test/src.js: -------------------------------------------------------------------------------- 1 | export function add (a, b) { 2 | return a + b; 3 | } 4 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/extension.txt: -------------------------------------------------------------------------------- 1 | Directory scan should not load TXT by default. 2 | -------------------------------------------------------------------------------- /demos/testem/testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "test.html" 4 | } 5 | -------------------------------------------------------------------------------- /docs/blog/tag/feature.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: posts-tag 3 | tag: feature 4 | title: Feature 5 | --- 6 | -------------------------------------------------------------------------------- /docs/blog/tag/release.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: posts-tag 3 | tag: release 4 | title: Release 5 | --- 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/assert-expect-no-assertions.js: -------------------------------------------------------------------------------- 1 | QUnit.test('no assertions', () => { 2 | }); 3 | -------------------------------------------------------------------------------- /demos/nyc/src/add.js: -------------------------------------------------------------------------------- 1 | function add (a, b) { 2 | return a + b; 3 | } 4 | 5 | module.exports = add; 6 | -------------------------------------------------------------------------------- /docs/img/logo-qunit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/logo-qunit@2x.png -------------------------------------------------------------------------------- /test/cli/fixtures/no-tests-failOnZeroTests.js: -------------------------------------------------------------------------------- 1 | // no tests 2 | QUnit.config.failOnZeroTests = false; 3 | -------------------------------------------------------------------------------- /test/cli/fixtures/node_modules/require-dep/index.js: -------------------------------------------------------------------------------- 1 | console.log( "required require-dep/index.js" ); 2 | -------------------------------------------------------------------------------- /docs/img/2011-logo-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2011-logo-qunit.png -------------------------------------------------------------------------------- /docs/img/2012-logo-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2012-logo-qunit.png -------------------------------------------------------------------------------- /docs/img/2012b-logo-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2012b-logo-qunit.png -------------------------------------------------------------------------------- /docs/img/QUnit-Logo-Large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/QUnit-Logo-Large.png -------------------------------------------------------------------------------- /docs/resources/perf-chrome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/perf-chrome.png -------------------------------------------------------------------------------- /test/cli/fixtures/node_modules/require-dep/module.js: -------------------------------------------------------------------------------- 1 | console.log( "required require-dep/module.js" ); 2 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/extension.ts: -------------------------------------------------------------------------------- 1 | throw new Error('Directory scan should not load TS by default.'); 2 | -------------------------------------------------------------------------------- /test/dynamic-import/sum.mjs: -------------------------------------------------------------------------------- 1 | function sum (a, b) { 2 | return a + b; 3 | } 4 | 5 | export default sum; 6 | -------------------------------------------------------------------------------- /docs/img/2012-logo-qunit@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2012-logo-qunit@2x.png -------------------------------------------------------------------------------- /docs/img/2012-website-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2012-website-qunit.png -------------------------------------------------------------------------------- /docs/img/2013-website-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2013-website-qunit.png -------------------------------------------------------------------------------- /docs/img/2020-website-qunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2020-website-qunit.png -------------------------------------------------------------------------------- /docs/resources/perf-firefox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/perf-firefox.png -------------------------------------------------------------------------------- /src/core/promise.js: -------------------------------------------------------------------------------- 1 | import _Promise from '../../lib/promise-polyfill.js'; 2 | 3 | export default _Promise; 4 | -------------------------------------------------------------------------------- /test/cli/fixtures/hanging-test.js: -------------------------------------------------------------------------------- 1 | QUnit.test('hanging', function (assert) { 2 | assert.async(); 3 | }); 4 | -------------------------------------------------------------------------------- /demos/testem/add.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | function add (a, b) { 4 | return a + b; 5 | } 6 | -------------------------------------------------------------------------------- /demos/nyc/src/subtract.js: -------------------------------------------------------------------------------- 1 | function substract (a, b) { 2 | return a - b; 3 | } 4 | 5 | module.exports = substract; 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/node_modules/require-dep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "name": "require-dep" 4 | } 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | This project adheres to the [OpenJS Foundation Code of Conduct](https://code-of-conduct.openjsf.org/). 2 | -------------------------------------------------------------------------------- /demos/karma-qunit/fail-assert.js: -------------------------------------------------------------------------------- 1 | QUnit.test('example', function (assert) { 2 | assert.true(false, 'some message'); 3 | }); 4 | -------------------------------------------------------------------------------- /docs/img/2013-logo-qunit_color_study.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/img/2013-logo-qunit_color_study.png -------------------------------------------------------------------------------- /docs/resources/2014-brazil-hacking.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2014-brazil-hacking.jpg -------------------------------------------------------------------------------- /docs/resources/2017-qunit-cli-demo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2017-qunit-cli-demo.jpg -------------------------------------------------------------------------------- /test/benchmark/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "qunit": "file:../.." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /docs/resources/2018-parallel-prototype.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2018-parallel-prototype.jpg -------------------------------------------------------------------------------- /docs/api/removed.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: removed 4 | title: Removed methods 5 | redirect_from: 6 | - "/removed/" 7 | --- 8 | -------------------------------------------------------------------------------- /docs/resources/2023-speedlify-leaderboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2023-speedlify-leaderboard.png -------------------------------------------------------------------------------- /docs/resources/2024-qunit-3-alpha-4-demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2024-qunit-3-alpha-4-demo.png -------------------------------------------------------------------------------- /docs/blog/tag/link.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: posts-tag 3 | tag: link 4 | title: Linked 5 | amethyst: 6 | exclude_tag_from_recent: true 7 | --- 8 | -------------------------------------------------------------------------------- /docs/resources/2025-stacktrace-assert-html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2025-stacktrace-assert-html.png -------------------------------------------------------------------------------- /docs/resources/2025-stacktrace-error-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2025-stacktrace-error-after.png -------------------------------------------------------------------------------- /docs/resources/2025-stacktrace-error-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2025-stacktrace-error-before.png -------------------------------------------------------------------------------- /test/cli/fixtures/assert-expect-failure.js: -------------------------------------------------------------------------------- 1 | QUnit.test('failing test', assert => { 2 | assert.expect(2); 3 | assert.true(true); 4 | }); 5 | -------------------------------------------------------------------------------- /docs/api/async.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: async 4 | title: Async control 5 | redirect_from: 6 | - "/category/async-control/" 7 | --- 8 | -------------------------------------------------------------------------------- /test/benchmark/micro.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | require('qunit'); 4 | require('./micro-fixture.js'); 5 | require('./micro-bench.js'); 6 | -------------------------------------------------------------------------------- /docs/api/deprecated.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: deprecated 4 | title: Deprecated methods 5 | redirect_from: 6 | - "/deprecated/" 7 | --- 8 | -------------------------------------------------------------------------------- /docs/resources/2025-stacktrace-assert-tap-after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2025-stacktrace-assert-tap-after.png -------------------------------------------------------------------------------- /docs/resources/2025-stacktrace-assert-tap-before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jquery/qunit/HEAD/docs/resources/2025-stacktrace-assert-tap-before.png -------------------------------------------------------------------------------- /docs/api/extension/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: extension 4 | title: Extension interface 5 | redirect_from: 6 | - "/extension/" 7 | --- 8 | -------------------------------------------------------------------------------- /src/core/version.js: -------------------------------------------------------------------------------- 1 | // Expose the current QUnit version 2 | // Replaced by /rollup.config.js using /build/dist-replace.js 3 | export default '@VERSION'; 4 | -------------------------------------------------------------------------------- /test/cli/fixtures/glob/not-a.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Not-A', function () { 2 | QUnit.test('1', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/first.js: -------------------------------------------------------------------------------- 1 | QUnit.module('First', function () { 2 | QUnit.test('1', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/dynamic-import/bar.js: -------------------------------------------------------------------------------- 1 | QUnit.module('bar', function () { 2 | QUnit.test('example', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/dynamic-import/foo.js: -------------------------------------------------------------------------------- 1 | QUnit.module('foo', function () { 2 | QUnit.test('example', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-requireExpects.js: -------------------------------------------------------------------------------- 1 | QUnit.config.requireExpects = true; 2 | 3 | QUnit.test('passing test', assert => { 4 | assert.true(true); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/glob/a-test.js: -------------------------------------------------------------------------------- 1 | QUnit.module('A-Test', function () { 2 | QUnit.test('derp', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/basic-one.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Single', function () { 2 | QUnit.test('has a test', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/nested/second.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Second', function () { 2 | QUnit.test('1', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /demos/nyc/index.js: -------------------------------------------------------------------------------- 1 | const add = require('./src/add.js'); 2 | const subtract = require('./src/subtract.js'); 3 | 4 | module.exports = { 5 | add, 6 | subtract 7 | }; 8 | -------------------------------------------------------------------------------- /docs/_data/authors.yaml: -------------------------------------------------------------------------------- 1 | jzaefferer: Jörn Zaefferer 2 | jamesmgreene: James M. Greene 3 | leobalter: Leo Balter 4 | trentmwillis: Trent Willis 5 | krinkle: Timo Tijhof 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/too-many-done-calls.js: -------------------------------------------------------------------------------- 1 | QUnit.test('Test A', assert => { 2 | assert.ok(true); 3 | const done = assert.async(); 4 | done(); 5 | done(); 6 | }); 7 | -------------------------------------------------------------------------------- /demos/karma-qunit/fail-global-error.js: -------------------------------------------------------------------------------- 1 | QUnit.test('example', function (assert) { 2 | // eslint-disable-next-line no-undef 3 | boom(); 4 | assert.true(true); 5 | }); 6 | -------------------------------------------------------------------------------- /demos/testem/add.test.js: -------------------------------------------------------------------------------- 1 | /* global add */ 2 | QUnit.module('add', () => { 3 | QUnit.test('two numbers', assert => { 4 | assert.equal(add(1, 2), 3); 5 | }); 6 | }); 7 | -------------------------------------------------------------------------------- /test/cli/fixtures/glob/sub/nested-test.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Nested-Test', function () { 2 | QUnit.test('herp', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/extension.cjs: -------------------------------------------------------------------------------- 1 | QUnit.module('Extension CJS', function () { 2 | QUnit.test('example', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/test/extension.mjs: -------------------------------------------------------------------------------- 1 | QUnit.module('Extension MJS', function () { 2 | QUnit.test('example', function (assert) { 3 | assert.true(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /docs/api/callbacks/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: callbacks 4 | title: Callback events 5 | redirect_from: 6 | - "/callbacks/" 7 | - "/category/callbacks/" 8 | --- 9 | -------------------------------------------------------------------------------- /docs/404.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Page not found 4 | permalink: /404.html 5 | --- 6 | 7 |

It seems we can't find what you're looking for.

8 | -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | ruby RUBY_VERSION 3 | 4 | # To apply changes, run `bundle update`. 5 | gem "jekyll-theme-amethyst", "2.11.0", group: :jekyll_plugins 6 | -------------------------------------------------------------------------------- /test/cli/fixtures/inception.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "inception.js"] 2 | 3 | TAP version 13 4 | ok 1 inception 5 | 1..1 6 | # pass 1 7 | # skip 0 8 | # todo 0 9 | # fail 0 10 | -------------------------------------------------------------------------------- /test/dynamic-import/index.js: -------------------------------------------------------------------------------- 1 | QUnit.config.autostart = false; 2 | 3 | Promise.all([ 4 | import('./foo.js'), 5 | import('./bar.js') 6 | ]).then(function () { 7 | QUnit.start(); 8 | }); 9 | -------------------------------------------------------------------------------- /demos/bundlers/test/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es2020": true 4 | }, 5 | "parserOptions": { 6 | "ecmaVersion": 2020, 7 | "sourceType": "module" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-add.js: -------------------------------------------------------------------------------- 1 | QUnit.config.noglobals = true; 2 | 3 | QUnit.test('adds global var', assert => { 4 | global.dummyGlobal = 'hello'; 5 | assert.true(true); 6 | }); 7 | -------------------------------------------------------------------------------- /demos/nyc/test/add.js: -------------------------------------------------------------------------------- 1 | const add = require('../index.js').add; 2 | 3 | QUnit.module('add', () => { 4 | QUnit.test('two numbers', assert => { 5 | assert.equal(add(1, 2), 3); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /demos/testem/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "testem": "3.13.0" 5 | }, 6 | "scripts": { 7 | "test": "testem -l 'Headless Firefox' ci" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-filenotfound.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load file not found 2 | # command: ["qunit","does-not-exist.js"] 3 | 4 | # stderr 5 | No files were found matching: does-not-exist.js 6 | 7 | # exit code: 1 -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-ignored.js: -------------------------------------------------------------------------------- 1 | QUnit.config.noglobals = true; 2 | 3 | QUnit.test('adds global var', assert => { 4 | global['qunit-test-output-dummy'] = 'hello'; 5 | assert.true(true); 6 | }); 7 | -------------------------------------------------------------------------------- /test/cli/fixtures/npm-reporter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "name": "npm-reporter", 4 | "private": true, 5 | "keywords": [ 6 | "qunit-plugin", 7 | "js-reporter" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /test/main/modules-esm.mjs: -------------------------------------------------------------------------------- 1 | import sum from '../dynamic-import/sum.mjs'; 2 | 3 | QUnit.module('modules [esm]', () => { 4 | QUnit.test('example', assert => { 5 | assert.equal(5, sum(2, 3)); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /src/cli/require-from-cwd.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function requireFromCWD (mod) { 4 | const resolvedPath = require.resolve(mod, { paths: [process.cwd()] }); 5 | return require(resolvedPath); 6 | }; 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # JS and HTML files must always use LF for tools to work 5 | *.js eol=lf 6 | *.tap.txt eol=lf 7 | *.json eol=lf 8 | *.html eol=lf 9 | -------------------------------------------------------------------------------- /demos/karma-qunit/pass-config.js: -------------------------------------------------------------------------------- 1 | QUnit.test('set config', function (assert) { 2 | assert.strictEqual(QUnit.config.testTimeout, 1991, 'testTimeout'); 3 | assert.strictEqual(QUnit.config.fooBar, 'xyz', 'fooBar'); 4 | }); 5 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-module.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.module 2 | # command: ["qunit","config-module.js"] 3 | 4 | TAP version 13 5 | ok 1 Module B > Test B 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/sourcemap/source.min.js: -------------------------------------------------------------------------------- 1 | QUnit.module("Example",function(){QUnit.test("good",function(assert){assert.true(!0)}),QUnit.test("bad",function(assert){assert.true(!1)})}); 2 | //# sourceMappingURL=source.min.js.map -------------------------------------------------------------------------------- /docs/_data/sidebar_blog.yml: -------------------------------------------------------------------------------- 1 | - type: recent 2 | title: Recent blog posts 3 | expand: true 4 | 5 | - type: tags 6 | title: Tags 7 | expand: true 8 | 9 | - type: archive 10 | title: Archives 11 | expand: true 12 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "grunt": "1.6.1", 5 | "grunt-contrib-qunit": "10.1.1" 6 | }, 7 | "scripts": { 8 | "test": "grunt" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-single-file.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load single file 2 | # command: ["qunit","basic-one.js"] 3 | 4 | TAP version 13 5 | ok 1 Single > has a test 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-remove.js: -------------------------------------------------------------------------------- 1 | QUnit.config.noglobals = true; 2 | 3 | global.dummyGlobal = 'hello'; 4 | 5 | QUnit.test('deletes global var', assert => { 6 | delete global.dummyGlobal; 7 | assert.true(true); 8 | }); 9 | -------------------------------------------------------------------------------- /test/cli/fixtures/done-after-timeout.js: -------------------------------------------------------------------------------- 1 | QUnit.test('times out before scheduled done is called', assert => { 2 | assert.timeout(10); 3 | const done = assert.async(); 4 | assert.true(true); 5 | setTimeout(done, 100); 6 | }); 7 | -------------------------------------------------------------------------------- /docs/_posts/2017-04-09-project-lead.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Welcome Trent Willis as project lead" 4 | author: leobalter 5 | tags: 6 | - link 7 | --- 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/_posts/2020-09-29-project-lead.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Welcome Timo Tijhof as project lead" 4 | author: trentmwillis 5 | tags: 6 | - link 7 | --- 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error-promise.js: -------------------------------------------------------------------------------- 1 | QUnit.module('module manually returning a promise', function () { 2 | QUnit.test('has a test', function (assert) { 3 | assert.true(true); 4 | }); 5 | return Promise.resolve(1); 6 | }); 7 | -------------------------------------------------------------------------------- /docs/api/QUnit/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: main 4 | title: Main methods 5 | redirect_from: 6 | - "/QUnit/" 7 | - "/category/test/" 8 | --- 9 | 10 | If you're new to QUnit, check out [Getting Started](../../intro.md)! 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-glob.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load glob pattern 2 | # command: ["qunit","glob/**/*-test.js"] 3 | 4 | TAP version 13 5 | ok 1 A-Test > derp 6 | ok 2 Nested-Test > herp 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/only-test.tap.txt: -------------------------------------------------------------------------------- 1 | # name: test.only() 2 | # command: ["qunit","only-test.js"] 3 | 4 | TAP version 13 5 | ok 1 run this test 6 | ok 2 all tests with only run 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callbacks-begin.js: -------------------------------------------------------------------------------- 1 | QUnit.begin(() => { 2 | throw new Error('No dice'); 3 | }); 4 | 5 | QUnit.module('module1', () => { 6 | QUnit.test('test1', assert => { 7 | assert.true(true); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callbacks-done.js: -------------------------------------------------------------------------------- 1 | QUnit.done(() => { 2 | throw new Error('No dice'); 3 | }); 4 | 5 | QUnit.module('module1', () => { 6 | QUnit.test('test1', assert => { 7 | assert.true(true); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error-thenable.js: -------------------------------------------------------------------------------- 1 | QUnit.module('module manually returning a thenable', function () { 2 | QUnit.test('has a test', function (assert) { 3 | assert.true(true); 4 | }); 5 | return { then: function () {} }; 6 | }); 7 | -------------------------------------------------------------------------------- /test/cli/fixtures/no-tests-failOnZeroTests.tap.txt: -------------------------------------------------------------------------------- 1 | # name: no tests and config.failOnZeroTests=false 2 | # command: ["qunit", "no-tests-failOnZeroTests.js"] 3 | 4 | TAP version 13 5 | 1..0 6 | # pass 0 7 | # skip 0 8 | # todo 0 9 | # fail 0 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/zero-assertions.tap.txt: -------------------------------------------------------------------------------- 1 | # name: test with zero assertions 2 | # command: ["qunit", "zero-assertions.js"] 3 | 4 | TAP version 13 5 | ok 1 Zero assertions > has a test 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/basic-fail.js: -------------------------------------------------------------------------------- 1 | QUnit.test('foo', function (assert) { 2 | assert.true(true); 3 | }); 4 | QUnit.test('bar', function (assert) { 5 | assert.true(false); 6 | }); 7 | QUnit.test('baz', function (assert) { 8 | assert.true(true); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/perf-mark.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "perf-mark.js"] 2 | # env: { "qunit_config_reporters_perf": true } 3 | 4 | TAP version 13 5 | ok 1 foo 6 | ok 2 bar 7 | ok 3 getEntries 8 | 1..3 9 | # pass 3 10 | # skip 0 11 | # todo 0 12 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/sourcemap/source.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Example', function () { 2 | QUnit.test('good', function (assert) { 3 | assert.true(true); 4 | }); 5 | 6 | QUnit.test('bad', function (assert) { 7 | assert.true(false); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/README.md: -------------------------------------------------------------------------------- 1 | # QUnit ♥️ Grunt 2 | 3 | See also . 4 | 5 | ```bash 6 | npm test 7 | ``` 8 | 9 | ``` 10 | Running "qunit:example" (qunit) task 11 | Testing test/example.html ..OK 12 | ``` 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/sourcemap/source.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["sourcemap/source.js"],"names":["QUnit","module","test","assert","true"],"mappings":"AAAAA,MAAMC,OAAQ,UAAW,WACxBD,MAAME,KAAM,OAAQ,SAAUC,QAC7BA,OAAOC,MAAM,KAGdJ,MAAME,KAAM,MAAO,SAAUC,QAC5BA,OAAOC,MAAM"} -------------------------------------------------------------------------------- /test/cli/fixtures/basic-two.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Double', function () { 2 | QUnit.test('has a test', function (assert) { 3 | assert.true(true); 4 | }); 5 | 6 | QUnit.test('has another test', function (assert) { 7 | assert.true(true); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/hooks-global-context.tap.txt: -------------------------------------------------------------------------------- 1 | # name: QUnit.hooks context 2 | # command: ["qunit", "hooks-global-context.js"] 3 | 4 | TAP version 13 5 | ok 1 A > A1 6 | ok 2 A > AB > AB1 7 | ok 3 B 8 | 1..3 9 | # pass 3 10 | # skip 0 11 | # todo 0 12 | # fail 0 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-module-then-test.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module.only() followed by test 2 | # command: ["qunit", "only-module-then-test.js"] 3 | 4 | TAP version 13 5 | ok 1 module A > module B > test B 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-string.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.filter with a string 2 | # command: ["qunit","config-filter-string.js"] 3 | 4 | TAP version 13 5 | ok 1 filter > foo test 6 | ok 2 filter > bar test 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-ignored.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.noglobals and add ignored DOM global 2 | # command: ["qunit", "config-noglobals-ignored.js"] 3 | 4 | TAP version 13 5 | ok 1 adds global var 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/filter-modulename-insensitive.tap.txt: -------------------------------------------------------------------------------- 1 | # name: --module selects a module (case-insensitive) 2 | # command: ["qunit", "--module", "seconD", "test/"] 3 | 4 | TAP version 13 5 | ok 1 Second > 1 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /docs/blog/archive.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: posts-archive 3 | title: Archive 4 | --- 5 | 6 | _See also [Meeting notes (2011-2016)](https://meetings.jquery.org/category/testing/) and [Meeting notes: js-reporters (2016)](https://meetings.jquery.org/category/js-reporters/) on meetings.jquery.org._ 7 | -------------------------------------------------------------------------------- /test/cli/fixtures/assert-throws-failure.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Throws match', function () { 2 | QUnit.test('bad', function (assert) { 3 | assert.throws(function () { 4 | throw new Error('Match me with a pattern'); 5 | }, /incorrect pattern/, 'match error'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/reorderError1.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('Test call count - first case'); 3 | QUnit.test.if( 4 | 'does not skip tests after reordering', 5 | !!window.sessionStorage, 6 | function (assert) { 7 | assert.equal(window.totalCount, 3); 8 | } 9 | ); 10 | -------------------------------------------------------------------------------- /test/reorderError2.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('Test call count - second case'); 3 | QUnit.test.if( 4 | 'does not skip tests after reordering', 5 | !!window.sessionStorage, 6 | function (assert) { 7 | assert.equal(window.totalCount, 2); 8 | } 9 | ); 10 | -------------------------------------------------------------------------------- /docs/_posts/2011-10-06-qunit-1-0-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.0.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | First stable release. 10 | 11 | ## See also 12 | 13 | * [Git tag: 1.0.0](https://github.com/qunitjs/qunit/releases/tag/1.0.0) 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-dir.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load a directory 2 | # command: ["qunit","test"] 3 | 4 | TAP version 13 5 | ok 1 Extension CJS > example 6 | ok 2 Extension MJS > example 7 | ok 3 First > 1 8 | ok 4 Second > 1 9 | 1..4 10 | # pass 4 11 | # skip 0 12 | # todo 0 13 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/filter-modulename.tap.txt: -------------------------------------------------------------------------------- 1 | # name: --filter matches module 2 | # command: ["qunit", "--filter", "single", "test", "basic-one.js", "glob/**/*-test.js"] 3 | 4 | TAP version 13 5 | ok 1 Single > has a test 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-in-hook.js: -------------------------------------------------------------------------------- 1 | QUnit.module('contains a hard error in hook', hooks => { 2 | hooks.before(() => { 3 | throw new Error('expected error thrown in hook'); 4 | }); 5 | QUnit.test('contains a hard error', assert => { 6 | assert.true(true); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /demos/karma-qunit/pass-basic.js: -------------------------------------------------------------------------------- 1 | QUnit.test('example 1', function (assert) { 2 | assert.true(true, 'x'); 3 | }); 4 | QUnit.test('example 2', function (assert) { 5 | assert.true(true, 'y'); 6 | }); 7 | QUnit.test('example 3', function (assert) { 8 | assert.true(true, 'z'); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line qunit/no-async-module-callbacks 2 | QUnit.module('module with async callback', async function () { 3 | await Promise.resolve(1); 4 | 5 | QUnit.test('has a test', function (assert) { 6 | assert.true(true); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-regex-exclude.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.filter with inverted regex 2 | # command: ["qunit","config-filter-regex-exclude.js"] 3 | 4 | TAP version 13 5 | ok 1 filter > foo test 6 | ok 2 filter > Bar test 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-regex.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.filter with a regex 2 | # command: ["qunit","config-filter-regex.js"] 3 | 4 | TAP version 13 5 | ok 1 filter > foo test 6 | ok 2 filter > FOO test 7 | ok 3 filter > bar test 8 | 1..3 9 | # pass 3 10 | # skip 0 11 | # todo 0 12 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/config-testTimeout.js: -------------------------------------------------------------------------------- 1 | process.on('unhandledRejection', (reason) => { 2 | console.log('Unhandled Rejection:', reason); 3 | }); 4 | 5 | QUnit.config.testTimeout = 10; 6 | 7 | QUnit.test('slow', () => { 8 | return new Promise(resolve => setTimeout(resolve, 20)); 9 | }); 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/pending-async-after-timeout.js: -------------------------------------------------------------------------------- 1 | // Regression test for https://github.com/qunitjs/qunit/issues/1705 2 | QUnit.test('example', async assert => { 3 | assert.timeout(10); 4 | // eslint-disable-next-line no-unused-vars 5 | const done = assert.async(); 6 | assert.true(true); 7 | }); 8 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callback-testStart.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error in "testStart" callback 2 | # command: ["qunit","uncaught-error-callback-testStart.js"] 3 | 4 | TAP version 13 5 | 6 | # stderr 7 | Error: Process exited before tests finished running 8 | 9 | # exit code: 1 10 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-default.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load "test" directory by default 2 | # command: ["qunit"] 3 | 4 | TAP version 13 5 | ok 1 Extension CJS > example 6 | ok 2 Extension MJS > example 7 | ok 3 First > 1 8 | ok 4 Second > 1 9 | 1..4 10 | # pass 4 11 | # skip 0 12 | # todo 0 13 | # fail 0 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/memory-leak-test-object.tap.txt: -------------------------------------------------------------------------------- 1 | # name: memory leak test-object 2 | # command: ["node", "--expose-gc", "../../../bin/qunit.js", "memory-leak-test-object.js"] 3 | 4 | TAP version 13 5 | ok 1 test-object > example test 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/module-nested.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module() nested with interrupted executeNow 2 | # command: ["qunit", "module-nested.js"] 3 | 4 | TAP version 13 5 | ok 1 module 1 > test in module 1 6 | ok 2 module 3 > test in module 3 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/zero-assertions.js: -------------------------------------------------------------------------------- 1 | QUnit.module('Zero assertions', function () { 2 | QUnit.test('has a test', function (assert) { 3 | assert.expect(0); 4 | 5 | // A test may expect zero assertions if its main purpose 6 | // is to ensure there are no no run-time exceptions. 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /demos/testem/README.md: -------------------------------------------------------------------------------- 1 | # QUnit ♥️ Testem 2 | 3 | See also . 4 | 5 | ```bash 6 | npm test 7 | ``` 8 | 9 | ``` 10 | ok 1 Firefox - [0 ms] - add: two numbers 11 | 12 | 1..1 13 | # tests 1 14 | # pass 1 15 | # skip 0 16 | # todo 0 17 | # fail 0 18 | 19 | # ok 20 | ``` 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-testId.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.testId 2 | # command: ["qunit","config-testId.js"] 3 | 4 | TAP version 13 5 | ok 1 test 2 6 | ok 2 module A > module B > test 1 7 | ok 3 module A > module C > test 2 8 | ok 4 module D > test 1 9 | 1..4 10 | # pass 4 11 | # skip 0 12 | # todo 0 13 | # fail 0 -------------------------------------------------------------------------------- /test/cli/fixtures/_load-multiple-files.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load multiple files 2 | # command: ["qunit","basic-one.js","basic-two.js"] 3 | 4 | TAP version 13 5 | ok 1 Single > has a test 6 | ok 2 Double > has a test 7 | ok 3 Double > has another test 8 | 1..3 9 | # pass 3 10 | # skip 0 11 | # todo 0 12 | # fail 0 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-extra-done-outside.js: -------------------------------------------------------------------------------- 1 | QUnit.test('extra done scheduled outside any test', assert => { 2 | assert.timeout(10); 3 | const done = assert.async(); 4 | assert.true(true); 5 | 6 | // Later, boom! 7 | setTimeout(done, 100); 8 | 9 | // Passing, end of test 10 | done(); 11 | }); 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callback-moduleDone.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error in "moduleDone" callback 2 | # command: ["qunit","uncaught-error-callback-moduleDone.js"] 3 | 4 | TAP version 13 5 | ok 1 module1 > test1 6 | 7 | # stderr 8 | Error: Process exited before tests finished running 9 | 10 | # exit code: 1 11 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/fail-no-tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/_posts/2015-01-20-qunit-1-17-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.17.1 Released" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * HTML Reporter: Fix missing toolbar bug. 12 | 13 | ## See also 14 | 15 | * [Git tag: 1.17.1](https://github.com/qunitjs/qunit/releases/tag/1.17.1) 16 | -------------------------------------------------------------------------------- /docs/_posts/2017-03-19-qunit-2-2-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.2.1 Released" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Core: Fix sessionStorage feature detection. 12 | 13 | ## See also 14 | 15 | * [Git tag: 2.2.1](https://github.com/qunitjs/qunit/releases/tag/2.2.1) 16 | -------------------------------------------------------------------------------- /demos/karma-qunit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "dependencies": { 4 | "karma": "^6.4.2", 5 | "karma-chrome-launcher": "^3.2.0", 6 | "karma-firefox-launcher": "2.1.3", 7 | "karma-qunit": "^4.2.0", 8 | "qunit": "file:../.." 9 | }, 10 | "scripts": { 11 | "test": "karma start --no-colors" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-extra-done.js: -------------------------------------------------------------------------------- 1 | QUnit.config.reorder = false; 2 | 3 | let done; 4 | 5 | QUnit.test('Test A', assert => { 6 | assert.ok(true); 7 | done = assert.async(); 8 | 9 | // Passing. 10 | done(); 11 | }); 12 | 13 | QUnit.test('Test B', assert => { 14 | assert.ok(true); 15 | 16 | // Boom 17 | done(); 18 | }); 19 | -------------------------------------------------------------------------------- /test/perf-mark.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | perf-mark 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/reorder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | reorder 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/hanging-test.tap.txt: -------------------------------------------------------------------------------- 1 | # name: test that hangs 2 | # command: ["qunit", "hanging-test.js"] 3 | 4 | TAP version 13 5 | not ok 1 hanging 6 | --- 7 | message: Test took longer than 3000ms; test timed out. 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/webWorker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | webWorker 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/npm-reporter/index.js: -------------------------------------------------------------------------------- 1 | function NPMReporter (runner) { 2 | runner.on('runEnd', this.onRunEnd); 3 | } 4 | 5 | NPMReporter.init = function (runner) { 6 | return new NPMReporter(runner); 7 | }; 8 | 9 | NPMReporter.prototype.onRunEnd = function () { 10 | console.log('Run ended!'); 11 | }; 12 | 13 | module.exports = NPMReporter; 14 | -------------------------------------------------------------------------------- /test/seed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | seed 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/startError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | startError 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/urlparams-filter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /demos/q4000-qunit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | q4000 on QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-testTimeout.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.testTimeout 2 | # command: ["qunit", "config-testTimeout.js"] 3 | 4 | TAP version 13 5 | not ok 1 slow 6 | --- 7 | message: Test took longer than 10ms; test timed out. 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/urlparams-module.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/urlparams-testId.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.nyc_output/ 2 | /__codeorigin/ 3 | /coverage/ 4 | /demos/*/package-lock.json 5 | /demos/*/node_modules/ 6 | /demos/*/tmp/ 7 | /docs/.jekyll-cache/ 8 | /docs/_site/ 9 | /docs/Gemfile.lock 10 | /test/benchmark/package-lock.json 11 | /test/benchmark/node_modules/ 12 | /node_modules/ 13 | /qunit/ 14 | /temp/ 15 | /.eslintcache 16 | /package-lock.json 17 | -------------------------------------------------------------------------------- /test/perf-clear-marks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | perf-clear-marks 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/urlparams-moduleId.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/_posts/2015-09-29-project-lead.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Welcome Leo Balter as project lead" 4 | author: jzaefferer 5 | tags: 6 | - link 7 | --- 8 | 9 | From [Twitter](https://twitter.com/leobalter/status/648903145200992257): 10 | 11 | > I am proud to be officially the new #QUnit dev lead. Looking forward to make it a better test tool for everyone! 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-after-assert-async.js: -------------------------------------------------------------------------------- 1 | QUnit.test('contains a hard error after using assert.async()', assert => { 2 | assert.async(); 3 | assert.true(true); 4 | throw new Error('expected error thrown in test'); 5 | 6 | // the "done" callback from `assert.async` should be called later, 7 | // but the hard-error prevents the test from reaching that 8 | }); 9 | -------------------------------------------------------------------------------- /test/dynamic-import.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/module-skip.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | module-skip 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/module-todo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | module-todo 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /demos/bundlers/test/import-named.js: -------------------------------------------------------------------------------- 1 | import { QUnit, assert, test } from 'qunit'; 2 | import { add } from './src.js'; 3 | 4 | (globalThis.TEST_OBJECTS || (globalThis.TEST_OBJECTS = {})).import_named = QUnit; 5 | 6 | QUnit.hello_import_named = assert.hello_import_named = 'import-named'; 7 | 8 | test('import-named', function (assert) { 9 | assert.equal(add(2, 3), 5); 10 | }); 11 | -------------------------------------------------------------------------------- /test/cli/fixtures/timeout.tap.txt: -------------------------------------------------------------------------------- 1 | # name: two tests with one timeout 2 | # command: ["qunit", "timeout.js"] 3 | 4 | TAP version 13 5 | not ok 1 timeout > first 6 | --- 7 | message: Test took longer than 10ms; test timed out. 8 | severity: failed 9 | ... 10 | ok 2 timeout > second 11 | 1..2 12 | # pass 1 13 | # skip 0 14 | # todo 0 15 | # fail 1 16 | 17 | # exit code: 1 18 | -------------------------------------------------------------------------------- /demos/bundlers/test/import-default.js: -------------------------------------------------------------------------------- 1 | import QUnit from 'qunit'; 2 | import { add } from './src.js'; 3 | 4 | (globalThis.TEST_OBJECTS || (globalThis.TEST_OBJECTS = {})).import_default = QUnit; 5 | 6 | QUnit.hello_import_default = QUnit.assert.hello_import_default = 'import-default'; 7 | 8 | QUnit.test('import-default', function (assert) { 9 | assert.equal(add(2, 3), 5); 10 | }); 11 | -------------------------------------------------------------------------------- /demos/bundlers/test/require-sub.cjs: -------------------------------------------------------------------------------- 1 | const QUnit = require('qunit').QUnit; 2 | const { add } = require('./src.js'); 3 | 4 | (globalThis.TEST_OBJECTS || (globalThis.TEST_OBJECTS = {})).require_sub = QUnit; 5 | 6 | QUnit.hello_require_sub = QUnit.assert.hello_require_sub = 'require-sub'; 7 | 8 | QUnit.test('require-sub', function (assert) { 9 | assert.equal(add(2, 3), 5); 10 | }); 11 | -------------------------------------------------------------------------------- /src/core/qunit-commonjs.js: -------------------------------------------------------------------------------- 1 | /* global module, exports */ 2 | import QUnit from './qunit.js'; 3 | 4 | // For Node.js 5 | if (typeof module !== 'undefined' && module && module.exports) { 6 | module.exports = QUnit; 7 | } 8 | 9 | // For CommonJS with exports, but without module.exports, like Rhino 10 | if (typeof exports !== 'undefined' && exports) { 11 | exports.QUnit = QUnit; 12 | } 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-add.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.noglobals and add a global 2 | # command: ["qunit", "config-noglobals-add.js"] 3 | 4 | TAP version 13 5 | not ok 1 adds global var 6 | --- 7 | message: "Introduced global variable(s): dummyGlobal" 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/browser-runner/amd.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | 3 | QUnit.module('AMD autostart', { 4 | after: function (assert) { 5 | assert.true(true, 'after hook ran'); 6 | } 7 | }); 8 | 9 | QUnit.test('Prove the test run started as expected', function (assert) { 10 | assert.expect(2); 11 | assert.strictEqual(window.beginData.totalTests, 1, 'Should have expected 1 test'); 12 | }); 13 | -------------------------------------------------------------------------------- /test/reporter-urlparams.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | reporter-urlparams 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /demos/karma-qunit/README.md: -------------------------------------------------------------------------------- 1 | # QUnit ♥️ Karma 2 | 3 | See also and . 4 | 5 | ```bash 6 | npm test 7 | ``` 8 | 9 | ``` 10 | INFO [karma-server]: Karma server started 11 | INFO [launcher]: Starting browser FirefoxHeadless 12 | INFO [Firefox]: Connected on socket 13 | ... 14 | Firefox: Executed 3 of 3 SUCCESS 15 | ``` 16 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-noglobals-remove.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.noglobals and remove a global 2 | # command: ["qunit","config-noglobals-remove.js"] 3 | 4 | TAP version 13 5 | not ok 1 deletes global var 6 | --- 7 | message: "Deleted global variable(s): dummyGlobal" 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/memory-leak-module-closure-filtered.tap.txt: -------------------------------------------------------------------------------- 1 | # name: memory leak module-closure filtered 2 | # command: ["node", "--expose-gc", "../../../bin/qunit.js", "--filter", "!child", "memory-leak-module-closure.js"] 3 | 4 | TAP version 13 5 | ok 1 module-closure > example test 6 | ok 2 module-closure check > memory release 7 | 1..2 8 | # pass 2 9 | # skip 0 10 | # todo 0 11 | # fail 0 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/pending-async-after-timeout.tap.txt: -------------------------------------------------------------------------------- 1 | # name: test with pending async after timeout 2 | # command: ["qunit", "pending-async-after-timeout.js"] 3 | 4 | TAP version 13 5 | not ok 1 example 6 | --- 7 | message: Test took longer than 10ms; test timed out. 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callback-testStart.js: -------------------------------------------------------------------------------- 1 | QUnit.testStart(details => { 2 | throw new Error('No dice for ' + details.name); 3 | }); 4 | 5 | QUnit.module('module1', () => { 6 | QUnit.test('test1', assert => { 7 | assert.true(true); 8 | }); 9 | }); 10 | 11 | QUnit.module('module2', () => { 12 | QUnit.test('test2', assert => { 13 | assert.true(true); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/only-each.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | only-each 6 | 7 | 8 | 9 | 10 | 11 |
12 |
test markup
13 | 14 | 15 | -------------------------------------------------------------------------------- /demos/bundlers/test/require-default.cjs: -------------------------------------------------------------------------------- 1 | const QUnit = require('qunit'); 2 | const { add } = require('./src.js'); 3 | 4 | (globalThis.TEST_OBJECTS || (globalThis.TEST_OBJECTS = {})).require_default = QUnit; 5 | 6 | QUnit.hello_require_default = QUnit.assert.hello_require_default = 'require-default'; 7 | 8 | QUnit.test('require-default', function (assert) { 9 | assert.equal(add(2, 3), 5); 10 | }); 11 | -------------------------------------------------------------------------------- /src/core/reporters.js: -------------------------------------------------------------------------------- 1 | import ConsoleReporter from './reporters/ConsoleReporter.js'; 2 | import PerfReporter from './reporters/PerfReporter.js'; 3 | import TapReporter from './reporters/TapReporter.js'; 4 | import HtmlReporter from './reporters/HtmlReporter.js'; 5 | 6 | export default { 7 | console: ConsoleReporter, 8 | perf: PerfReporter, 9 | tap: TapReporter, 10 | html: HtmlReporter 11 | }; 12 | -------------------------------------------------------------------------------- /test/browser-runner/window-onerror.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | window-onerror (no pre-existing handler) 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /test/cli/fixtures/require-module-and-script.tap.txt: -------------------------------------------------------------------------------- 1 | # name: --require loads dependency and script 2 | # command: ["qunit","basic-one.js","--require","require-dep","--require","./node_modules/require-dep/module.js"] 3 | 4 | required require-dep/index.js 5 | required require-dep/module.js 6 | TAP version 13 7 | ok 1 Single > has a test 8 | 1..1 9 | # pass 1 10 | # skip 0 11 | # todo 0 12 | # fail 0 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callback-moduleDone.js: -------------------------------------------------------------------------------- 1 | QUnit.moduleDone(details => { 2 | throw new Error('No dice for ' + details.name); 3 | }); 4 | 5 | QUnit.module('module1', () => { 6 | QUnit.test('test1', assert => { 7 | assert.true(true); 8 | }); 9 | }); 10 | 11 | QUnit.module('module2', () => { 12 | QUnit.test('test2', assert => { 13 | assert.true(true); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /test/events-filters.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | events-filters 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /test/events-in-test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | events-in-test 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 | 14 | 15 | -------------------------------------------------------------------------------- /test/perf-clear-marks.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('urlParams performance mark module', function () { 3 | QUnit.test("shouldn't fail if performance marks are cleared", function (assert) { 4 | // Optional feature available in IE10+ and Safari 10+ 5 | // eslint-disable-next-line compat/compat 6 | performance.clearMarks(); 7 | 8 | assert.true(true); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | ## Supported versions 4 | 5 | The [latest release](https://qunitjs.com/#current-release) of QUnit is supported with security updates. 6 | 7 | ## Reporting a vulnerability 8 | 9 | If you discover a vulnerability, we would like to know about it so we can take steps to address it as quickly as possible. 10 | 11 | E-mail your findings to security@jquery.com. Thanks! 12 | -------------------------------------------------------------------------------- /demos/bundlers/README.md: -------------------------------------------------------------------------------- 1 | # QUnit ♥️ Rollup & Webpack 2 | 3 | See also and . 4 | 5 | ```bash 6 | npm run build 7 | npm test 8 | ``` 9 | 10 | ``` 11 | Running "qunit:all" (qunit) task 12 | Testing http://localhost:8000/test.html .OK 13 | >> passed test "example" 14 | >> 1 test completed in 0ms, with 0 failed, 0 skipped, and 0 todo. 15 | 16 | Done. 17 | ``` 18 | -------------------------------------------------------------------------------- /demos/nyc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "nyc": "15.1.0", 5 | "qunit": "file:../.." 6 | }, 7 | "scripts": { 8 | "test": "nyc qunit" 9 | }, 10 | "nyc": { 11 | "exclude": [ 12 | "test/" 13 | ], 14 | "report-dir": "coverage/", 15 | "reporter": [ 16 | "text", 17 | "html", 18 | "lcov" 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/preconfig-flat-testId.js: -------------------------------------------------------------------------------- 1 | QUnit.test('test 1', function (assert) { 2 | assert.true(false); 3 | }); 4 | 5 | QUnit.test('test 2', function (assert) { 6 | assert.true(true, 'run test 2'); 7 | assert.deepEqual( 8 | QUnit.config.testId, 9 | ['94e5e740'], 10 | 'QUnit.config.testId' 11 | ); 12 | }); 13 | 14 | QUnit.test('test 3', function (assert) { 15 | assert.true(false); 16 | }); 17 | -------------------------------------------------------------------------------- /test/sandboxed-iframe--contents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | sandboxed-iframe-contents 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/_posts/2018-10-17-qunit-2-7-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.7.1 Released" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * Core: Avoid breaking tests if the browser throws an error from `performance.measure`. (Gabriel Csapo) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.7.1](https://github.com/qunitjs/qunit/releases/tag/2.7.1) 18 | -------------------------------------------------------------------------------- /docs/_posts/2023-07-11-eslint-assert-expect.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: The value and benefit of assert.expect()" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | I started a thread to review our recommendations around `assert.expect()`: 10 | 11 | [The value and benefit of assert.expect() - Ember Discuss](https://discuss.emberjs.com/t/the-value-and-benefit-of-assert-expect/20145) 12 | 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-moduleId.tap.txt: -------------------------------------------------------------------------------- 1 | # name: config.moduleId 2 | # command: ["qunit", "config-moduleId.js"] 3 | 4 | TAP version 13 5 | ok 1 module A scoped > module C nested > test C1 6 | ok 2 module D scoped > test D1 7 | ok 3 module D scoped > module E nested > test E1 8 | ok 4 module D scoped > test D2 9 | ok 5 module F flat > test F1 10 | 1..5 11 | # pass 5 12 | # skip 0 13 | # todo 0 14 | # fail 0 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/done-after-timeout.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.async() handled after timeout 2 | # command: ["qunit","done-after-timeout.js"] 3 | 4 | TAP version 13 5 | not ok 1 times out before scheduled done is called 6 | --- 7 | message: Test took longer than 10ms; test timed out. 8 | severity: failed 9 | ... 10 | 1..1 11 | # pass 0 12 | # skip 0 13 | # todo 0 14 | # fail 1 15 | 16 | # exit code: 1 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/no-tests.tap.txt: -------------------------------------------------------------------------------- 1 | # name: no tests 2 | # command: ["qunit", "no-tests.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: "Error: No tests were run." 8 | severity: failed 9 | stack: | 10 | Error: No tests were run. 11 | ... 12 | Bail out! Error: No tests were run. 13 | 1..1 14 | # pass 0 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 20 | -------------------------------------------------------------------------------- /test/urlparams-module.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | if (!location.search) { 3 | location.replace('?module=Foo'); 4 | } 5 | 6 | QUnit.module('Foo'); 7 | 8 | QUnit.test('config parsed', function (assert) { 9 | assert.strictEqual(QUnit.config.module, 'Foo', 'parsed config'); 10 | }); 11 | 12 | QUnit.module('Bar'); 13 | 14 | QUnit.test('Bar test', function (assert) { 15 | assert.true(false); 16 | }); 17 | -------------------------------------------------------------------------------- /docs/_posts/2015-07-08-qunit-migrate.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: QUnit Migrate by Amanpreet Singh" 4 | author: jzaefferer 5 | tags: 6 | - link 7 | --- 8 | 9 | Amanpreet Singh [wrote](https://twitter.com/apsdehal/status/618855917669453825): 10 | 11 | > If you are messed up with your QUnit code and want to remove deprecated code, you should have a look at 12 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-test-only-module-mix.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "only-test-only-module-mix.js"] 2 | 3 | TAP version 13 4 | not ok 1 global failure 5 | --- 6 | message: "Error: No tests were run." 7 | severity: failed 8 | stack: | 9 | Error: No tests were run. 10 | ... 11 | Bail out! Error: No tests were run. 12 | 1..1 13 | # pass 0 14 | # skip 0 15 | # todo 0 16 | # fail 1 17 | 18 | # exit code: 1 19 | -------------------------------------------------------------------------------- /test/cli/fixtures/test-if.tap.txt: -------------------------------------------------------------------------------- 1 | # name: no tests 2 | # command: ["qunit", "test-if.js"] 3 | 4 | TAP version 13 5 | ok 1 skip me # SKIP 6 | ok 2 keep me 7 | ok 3 regular 8 | ok 4 skip dataset [a] # SKIP 9 | ok 5 skip dataset [b] # SKIP 10 | ok 6 keep dataset [a] 11 | ok 7 keep dataset [b] 12 | ok 8 skip group > skipper # SKIP 13 | ok 9 keep group > keeper 14 | 1..9 15 | # pass 5 16 | # skip 4 17 | # todo 0 18 | # fail 0 19 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/pass-basic.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/_posts/2016-04-12-qunit-1-23-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.23.1 Released: Fix support for Rhino" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Core: Prevents "throws" keyword from breaking Rhino environments. 12 | * Core: Be consistent in function type checks. 13 | 14 | ## See also 15 | 16 | * [Git tag: 1.23.1](https://github.com/qunitjs/qunit/releases/tag/1.23.1) 17 | -------------------------------------------------------------------------------- /docs/_posts/2020-10-05-qunit-2-11-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.11.3 Released: Bug fix" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * CLI: Fix 'qunit' require error on Node 10 if qunit.json exists. [#1484](https://github.com/qunitjs/qunit/issues/1484) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.11.3](https://github.com/qunitjs/qunit/releases/tag/2.11.3) 18 | -------------------------------------------------------------------------------- /docs/api/reporters/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: reporters 4 | title: QUnit.reporters 5 | excerpt: Built-in reporters for TAP, HTML, console, and perf. 6 | amethyst: 7 | # Override inherited "pagetype: navigation" to enable Typesense indexing 8 | pagetype: custom 9 | robots: index 10 | --- 11 | 12 | To create your own reporter, refer to the [QUnit.on()](../callbacks/QUnit.on.md) event emitter and its Reporter API. 13 | -------------------------------------------------------------------------------- /test/cli/fixtures/_load-dir-file-glob.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load mixture of file, directory, and glob 2 | # command: ["qunit","test","basic-one.js","glob/**/*-test.js"] 3 | 4 | TAP version 13 5 | ok 1 Single > has a test 6 | ok 2 A-Test > derp 7 | ok 3 Nested-Test > herp 8 | ok 4 Extension CJS > example 9 | ok 5 Extension MJS > example 10 | ok 6 First > 1 11 | ok 7 Second > 1 12 | 1..7 13 | # pass 7 14 | # skip 0 15 | # todo 0 16 | # fail 0 17 | -------------------------------------------------------------------------------- /docs/_posts/2020-08-25-qunit-2-11-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.11.1 Released: Even faster CLI startup" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * CLI: Improve startup performance by using `tiny-glob`. [#1476](https://github.com/qunitjs/qunit/pull/1476) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.11.1](https://github.com/qunitjs/qunit/releases/tag/2.11.1) 18 | -------------------------------------------------------------------------------- /docs/_posts/2022-10-22-qunit-2-19-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.19.3 Released: Bug fix" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * Assert: Restore how deepEqual treats imposter objects. (Timo Tijhof) [#1706](https://github.com/qunitjs/qunit/issues/1706) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.19.3](https://github.com/qunitjs/qunit/releases/tag/2.19.3) 18 | -------------------------------------------------------------------------------- /docs/_posts/2014-12-03-upgrade-guide-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Upgrade Guide" 4 | author: jzaefferer 5 | tags: 6 | - link 7 | --- 8 | 9 | And we've published the upgrade guide for 2.x: 10 | 11 | 12 | 13 | All the new APIs are already in 1.16, you can migrate now. 14 | 15 | ------- 16 | 17 | _Originally published on [Twitter](https://twitter.com/qunitjs/status/540199370168496129)._ 18 | -------------------------------------------------------------------------------- /docs/_posts/2016-05-17-1000-commits.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: 1000 Commits Milestone!" 4 | author: leobalter 5 | tags: 6 | - link 7 | --- 8 | 9 | Maybe the stars are not aligned, but QUnit just got its issue #1000 fixed by the commit #1000. It means something 10 | 11 | ------- 12 | 13 | _Originally published on [Twitter](https://twitter.com/qunitjs/status/732620820049235968)._ 14 | -------------------------------------------------------------------------------- /src/core/qunit-wrapper-bundler-require.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | // In a single bundler invocation, if different parts or dependencies 4 | // of a project mix ESM and CJS, avoid a split-brain state by making 5 | // sure both import and re-use the same instance via this wrapper. 6 | // 7 | // Bundlers generally allow requiring an ESM file from CommonJS. 8 | const { QUnit } = require('./esm/qunit.module.js'); 9 | module.exports = QUnit; 10 | -------------------------------------------------------------------------------- /test/browser-runner/config-fixture-null.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | config-fixture-null 6 | 7 | 8 | 9 | 10 | 11 |
12 |
test markup
13 | 14 | 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-notrycatch-test-rejection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | process.on('unhandledRejection', (reason) => { 4 | console.log('FOUND Unhandled Rejection:', reason); 5 | }); 6 | 7 | QUnit.config.testTimeout = 1000; 8 | QUnit.config.notrycatch = true; 9 | 10 | QUnit.module('example', function () { 11 | QUnit.test('returns a rejected promise', function () { 12 | return Promise.reject('bad things happen'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/memory-leak-module-closure-unfiltered.tap.txt: -------------------------------------------------------------------------------- 1 | # name: memory leak module-closure unfiltered 2 | # command: ["node", "--expose-gc", "../../../bin/qunit.js", "memory-leak-module-closure.js"] 3 | 4 | TAP version 13 5 | ok 1 module-closure > example test 6 | ok 2 module-closure > example child module > example child module test 7 | ok 3 module-closure check > memory release 8 | 1..3 9 | # pass 3 10 | # skip 0 11 | # todo 0 12 | # fail 0 -------------------------------------------------------------------------------- /test/only-each.js: -------------------------------------------------------------------------------- 1 | QUnit.module.only('test.each.only', function () { 2 | QUnit.test("don't run", function (assert) { assert.true(false); }); 3 | QUnit.test.only.each('test.each.only', [[1, 2, 3], [1, 1, 2]], function (assert, data) { 4 | assert.strictEqual(data[0] + data[1], data[2]); 5 | }); 6 | QUnit.test.only.each('test.each.only 1D', [1, [], 'some'], function (assert, value) { 7 | assert.true(Boolean(value)); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/fail-assert.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/browser-runner/config-fixture-string.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | config-fixture-string 6 | 7 | 8 | 9 | 10 | 11 |
12 |
test markup
13 | 14 | 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/seed.tap.txt: -------------------------------------------------------------------------------- 1 | # name: --seed value 2 | # command: ["qunit", "--seed", "s33d", "test", "basic-one.js", "glob/**/*-test.js"] 3 | 4 | Running tests with seed: s33d 5 | TAP version 13 6 | ok 1 Second > 1 7 | ok 2 Extension MJS > example 8 | ok 3 Nested-Test > herp 9 | ok 4 Extension CJS > example 10 | ok 5 A-Test > derp 11 | ok 6 First > 1 12 | ok 7 Single > has a test 13 | 1..7 14 | # pass 7 15 | # skip 0 16 | # todo 0 17 | # fail 0 18 | -------------------------------------------------------------------------------- /docs/_posts/2020-07-31-speedlify-category.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Speedlify for Testing Tools" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | Speedlify wrote on [Twitter](https://twitter.com/speedlify/status/1289252992231776259): 10 | 11 | > At the request of @TimoTijhof we created a category for Front-end Testing Tools: 12 | > 13 | > 14 | > 15 | > @qunitjs is the runaway winner so far! 16 | -------------------------------------------------------------------------------- /src/core/hooks.js: -------------------------------------------------------------------------------- 1 | import config from './config.js'; 2 | 3 | function makeAddGlobalHook (hookName) { 4 | return function addGlobalHook (callback) { 5 | if (!config._globalHooks[hookName]) { 6 | config._globalHooks[hookName] = []; 7 | } 8 | config._globalHooks[hookName].push(callback); 9 | }; 10 | } 11 | 12 | export default { 13 | beforeEach: makeAddGlobalHook('beforeEach'), 14 | afterEach: makeAddGlobalHook('afterEach') 15 | }; 16 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-module.js: -------------------------------------------------------------------------------- 1 | QUnit.config.module = 'MODULE b'; 2 | 3 | QUnit.module('Module A', () => { 4 | QUnit.test('Test A', assert => { 5 | assert.true(false); 6 | }); 7 | }); 8 | 9 | QUnit.module('Module B', () => { 10 | QUnit.test('Test B', assert => { 11 | assert.true(true); 12 | }); 13 | }); 14 | 15 | QUnit.module('Module C', () => { 16 | QUnit.test('Test C', assert => { 17 | assert.true(false); 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-done.js: -------------------------------------------------------------------------------- 1 | QUnit.config.reorder = false; 2 | 3 | let done; 4 | 5 | QUnit.test('Test A', assert => { 6 | assert.ok(true); 7 | done = assert.async(); 8 | throw new Error('this is an intentional error'); 9 | }); 10 | 11 | QUnit.test('Test B', assert => { 12 | assert.ok(true); 13 | 14 | // This bad call is silently ignored because "Test A" already failed 15 | // and we cancelled the async pauses. 16 | done(); 17 | }); 18 | -------------------------------------------------------------------------------- /docs/_posts/2019-01-07-qunit-2-9-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.9.1 Released: Fix the CLI" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * Release: Restore missing files that were accidentally missing in the 2.9.0 npm package. [#1368](https://github.com/qunitjs/qunit/pull/1368) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.9.1](https://github.com/qunitjs/qunit/releases/tag/2.9.1) 18 | -------------------------------------------------------------------------------- /demos/testem/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testem 5 | 6 | 7 | 8 | 9 | 10 | 14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/_posts/2021-09-09-qunit-2-17-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.17.1 Released: Bug fix" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * HTML Reporter: Fix `display: none` regression with the "global failure" message. (Timo Tijhof) [#1651](https://github.com/qunitjs/qunit/issues/1651) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.17.1](https://github.com/qunitjs/qunit/releases/tag/2.17.1) 18 | -------------------------------------------------------------------------------- /docs/_posts/2022-05-01-qunit-2-19-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.19.1 Released: Bug fix" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * HTML Reporter: Restore float-clear for narrow viewports. [87c90ce2e0](https://github.com/qunitjs/qunit/commit/87c90ce2e0eb03f3d10b8cec07c0ac9b3709b0d7) 14 | 15 | ## See also 16 | 17 | * [Git tag: 2.19.1](https://github.com/qunitjs/qunit/releases/tag/2.19.1) 18 | -------------------------------------------------------------------------------- /test/webWorker.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('Web Worker'); 3 | 4 | QUnit.test('main tests', function (assert) { 5 | assert.timeout(10000); 6 | var done = assert.async(); 7 | // eslint-disable-next-line compat/compat -- Test skipped in IE9 8 | var worker = new Worker('webWorker-worker.js'); 9 | 10 | worker.onmessage = function (event) { 11 | assert.equal(event.data.status, 'passed', 'runEnd.status'); 12 | done(); 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-string.js: -------------------------------------------------------------------------------- 1 | // case-insensitive string that looks like a regex but isn't, inverted 2 | QUnit.config.filter = '!foo|bar'; 3 | 4 | QUnit.module('filter'); 5 | 6 | QUnit.test('foo test', function (assert) { 7 | assert.true(true); 8 | }); 9 | 10 | QUnit.test('bar test', function (assert) { 11 | assert.true(true); 12 | }); 13 | 14 | QUnit.test('foo|bar test', function (assert) { 15 | assert.true(false, "'foo|bar' is excluded"); 16 | }); 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-module-flat.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "only-module-flat.js"] 2 | 3 | TAP version 13 4 | not ok 1 module B > test B # TODO 5 | --- 6 | message: not implemented yet 7 | severity: todo 8 | actual : false 9 | expected: true 10 | stack: | 11 | at /qunit/test/cli/fixtures/only-module-flat.js:8:14 12 | ... 13 | ok 2 module B > test C # SKIP 14 | ok 3 module B > test D 15 | 1..3 16 | # pass 1 17 | # skip 1 18 | # todo 1 19 | # fail 0 20 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | charset = utf-8 10 | trim_trailing_whitespace = true 11 | insert_final_newline = true 12 | 13 | [demos/grunt-contrib-qunit.js] 14 | trim_trailing_whitespace = false 15 | [demos/nyc.js] 16 | trim_trailing_whitespace = false 17 | [test/cli/TapReporter.js] 18 | trim_trailing_whitespace = false 19 | 20 | [*.css] 21 | indent_style = tab 22 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 'use strict'; 3 | module.exports = function (grunt) { 4 | grunt.loadNpmTasks('grunt-contrib-qunit'); 5 | 6 | grunt.initConfig({ 7 | qunit: { 8 | pass: ['pass-*.html'], 9 | 'fail-assert': 'fail-assert.html', 10 | 'fail-no-tests': 'fail-no-tests.html', 11 | 'fail-uncaught': 'fail-uncaught.html' 12 | } 13 | }); 14 | 15 | grunt.registerTask('default', ['qunit:pass']); 16 | }; 17 | -------------------------------------------------------------------------------- /test/browser-runner/autostart.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.start(); 3 | 4 | QUnit.module('autostart'); 5 | 6 | QUnit.test('Prove the test run started as expected', function (assert) { 7 | var delay = window.times.runStarted - window.times.autostartOff; 8 | assert.pushResult({ 9 | result: delay >= 1000, 10 | actual: delay, 11 | message: 'delay' 12 | }); 13 | assert.strictEqual(window.beginData.totalTests, 1, 'Should have expected 1 test'); 14 | }); 15 | -------------------------------------------------------------------------------- /demos/bundlers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "devDependencies": { 4 | "@rollup/plugin-commonjs": "^26.0.1", 5 | "@rollup/plugin-node-resolve": "^15.2.3", 6 | "grunt": "1.6.1", 7 | "grunt-contrib-connect": "^5.0.0", 8 | "grunt-contrib-qunit": "10.1.1", 9 | "qunit": "file:../..", 10 | "rollup": "^4.18.0", 11 | "webpack": "^5.92.0" 12 | }, 13 | "scripts": { 14 | "build": "node build.mjs", 15 | "test": "grunt test" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /docs/_posts/2017-01-05-qunit-2-1-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.1.1 Released" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * All: Remove deprecated 1.x features. 12 | * Assert: Deprecate `assert.push()`. 13 | * Core: `QUnit.start()` no longer requires calling `QUnit.load()` first. 14 | * HTML Reporter: Add an "Abort" button. 15 | 16 | ## See also 17 | 18 | * [Git tag: 2.1.1](https://github.com/qunitjs/qunit/releases/tag/2.1.1) 19 | -------------------------------------------------------------------------------- /docs/_posts/2025-10-09-qunit-2-24-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.24.2 Released: Bug fix" 4 | author: krinkle 5 | excerpt: Another TAP compliance fix. 6 | tags: 7 | - release 8 | --- 9 | 10 | ### Fixed 11 | 12 | * CLI: Fix TAP compliance for colon in unquoted YAML diag. [dbc02fb9fe](https://github.com/qunitjs/qunit/commit/dbc02fb9fe001a4544b04a6d1b5db2a1a1f6fa7b) 13 | 14 | ## See also 15 | 16 | * [Git tag: 2.24.2](https://github.com/qunitjs/qunit/releases/tag/2.24.2) 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/_sourcemap.tap.txt: -------------------------------------------------------------------------------- 1 | # name: normal trace with native source map applied 2 | # command: ["qunit","sourcemap/source.js"] 3 | 4 | TAP version 13 5 | ok 1 Example > good 6 | not ok 2 Example > bad 7 | --- 8 | message: failed 9 | severity: failed 10 | actual : false 11 | expected: true 12 | stack: | 13 | at /qunit/test/cli/fixtures/sourcemap/source.js:7:16 14 | ... 15 | 1..2 16 | # pass 1 17 | # skip 0 18 | # todo 0 19 | # fail 1 20 | 21 | # exit code: 1 -------------------------------------------------------------------------------- /test/cli/fixtures/assert-expect-failure.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.expect() different count 2 | # command: ["qunit", "assert-expect-failure.js"] 3 | 4 | TAP version 13 5 | not ok 1 failing test 6 | --- 7 | message: Expected 2 assertions, but 1 were run 8 | severity: failed 9 | stack: | 10 | at /qunit/test/cli/fixtures/assert-expect-failure.js:1:7 11 | at internal 12 | ... 13 | 1..1 14 | # pass 0 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 20 | -------------------------------------------------------------------------------- /test/preconfig-object.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('QUnit.config [preconfigured]'); 3 | 4 | QUnit.test('config', function (assert) { 5 | assert.strictEqual(QUnit.config.maxDepth, 5, 'maxDepth default'); 6 | assert.false(QUnit.config.autostart, 'autostart override'); 7 | assert.false(QUnit.config.reorder, 'reorder override'); 8 | }); 9 | 10 | window.addEventListener('load', function () { 11 | setTimeout(function () { 12 | QUnit.start(); 13 | }, 1); 14 | }); 15 | -------------------------------------------------------------------------------- /demos/grunt-contrib-qunit/fail-uncaught.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | QUnit 6 | 7 | 8 | 9 |
10 | 11 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/core/logger.js: -------------------------------------------------------------------------------- 1 | import { console } from './globals.js'; 2 | 3 | // Support IE 9: No console object, unless the developer tools are not open. 4 | 5 | // Support IE 9: Function#bind is supported, but no console.log.bind(). 6 | 7 | // Support: SpiderMonkey (mozjs 68+) 8 | // The console object has a log method, but no warn method. 9 | 10 | export default { 11 | warn: console 12 | ? Function.prototype.bind.call(console.warn || console.log, console) 13 | : function () {} 14 | }; 15 | -------------------------------------------------------------------------------- /test/logs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | logs 6 | 7 | 8 | 12 | 13 | 14 | 15 |
16 |
test markup
17 | 18 | 19 | -------------------------------------------------------------------------------- /test/main/callbacks.js: -------------------------------------------------------------------------------- 1 | QUnit.module('callbacks', function () { 2 | QUnit.test('QUnit.testDone [failure]', function (assert) { 3 | assert.throws(function () { 4 | QUnit.testDone(undefined); 5 | }, TypeError, 'undefined callback'); 6 | 7 | assert.throws(function () { 8 | QUnit.testDone(null); 9 | }, TypeError, 'null callback'); 10 | 11 | assert.throws(function () { 12 | QUnit.testDone('banana'); 13 | }, TypeError, 'string callback'); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /docs/_posts/2025-11-29-qunit-2-24-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.24.3 Released: Bug fix" 4 | author: krinkle 5 | excerpt: Yet another TAP compliance fix. 6 | tags: 7 | - release 8 | --- 9 | 10 | ### Fixed 11 | 12 | * CLI: Fix TAP compliance for test plan when using `QUnit.test.only()`. [4b87bc6aa5](https://github.com/qunitjs/qunit/commit/4b87bc6aa54afdcbb4e2c0c8c5ed277b68171507) 13 | 14 | ## See also 15 | 16 | * [Git tag: 2.24.3](https://github.com/qunitjs/qunit/releases/tag/2.24.3) 17 | -------------------------------------------------------------------------------- /test/preconfig-flat-testId.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | preconfig-flat-testId 6 | 7 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/api/assert/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: group 3 | group: assert 4 | title: Assertions 5 | amethyst: 6 | robots: index 7 | redirect_from: 8 | - "/assert/" 9 | - "/QUnit.assert/" 10 | - "/category/assert/" 11 | --- 12 | 13 | To define additional assertion methods, refer to the [`QUnit.assert`](../extension/QUnit.assert.md) extension page. 14 | 15 | You can think of these as the JavaScript equivalent of assert methods you might find in xUnit-style frameworks such as SUnit, JUnit, RUnit, and PHPUnit. 16 | -------------------------------------------------------------------------------- /docs/resources/example-index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | QUnit 5 | 6 | 7 |
8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-notrycatch-hook-rejection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | process.on('unhandledRejection', (reason) => { 4 | console.log('FOUND Unhandled Rejection:', reason); 5 | }); 6 | 7 | QUnit.config.testTimeout = 1000; 8 | QUnit.config.notrycatch = true; 9 | 10 | QUnit.module('example', function (hooks) { 11 | hooks.beforeEach(() => { 12 | return Promise.reject('bad things happen'); 13 | }); 14 | 15 | QUnit.test('passing test', assert => { 16 | assert.true(true); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/cli/fixtures/timeout.js: -------------------------------------------------------------------------------- 1 | QUnit.module('timeout', function () { 2 | // This should fail 3 | QUnit.test('first', function (assert) { 4 | assert.timeout(10); 5 | 6 | return new Promise(resolve => setTimeout(resolve, 20)); 7 | }); 8 | 9 | // Runner should recover and still run and pass this test 10 | QUnit.test('second', function (assert) { 11 | return new Promise(resolve => setTimeout(resolve, 20)) 12 | .then(() => { 13 | assert.true(true); 14 | }); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/urlparams-testId.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | if (!location.search) { 3 | location.replace('?testId=94e5e740'); 4 | } 5 | 6 | QUnit.test('test 1', function (assert) { 7 | assert.true(false); 8 | }); 9 | 10 | QUnit.test('test 2', function (assert) { 11 | assert.true(true, 'run global test 2'); 12 | assert.deepEqual( 13 | QUnit.config.testId, 14 | ['94e5e740'], 15 | 'parsed config' 16 | ); 17 | }); 18 | 19 | QUnit.test('test 3', function (assert) { 20 | assert.true(false); 21 | }); 22 | -------------------------------------------------------------------------------- /docs/_posts/2017-06-02-qunit-2-3-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.3.3 Released: Web Workers support" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Added 12 | 13 | * Core: Support running in Web Worker threads. (Marten Schilstra) [#1171](https://github.com/qunitjs/qunit/pull/1171) 14 | 15 | ### Changed 16 | 17 | * CLI: Prefer local version of QUnit. 18 | 19 | ## See also 20 | 21 | * [Git tag: 2.3.3](https://github.com/qunitjs/qunit/releases/tag/2.3.3) 22 | -------------------------------------------------------------------------------- /test/preconfig-object.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | preconfig-object 6 | 7 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /docs/_posts/2014-08-25-brazil-hacking.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: QUnit Hacking in Brazil" 4 | image: /resources/2014-brazil-hacking.jpg 5 | author: jzaefferer 6 | tags: 7 | - link 8 | --- 9 | 10 | Boaz Sender wrote on [Twitter](https://twitter.com/BoazSender/status/503946938668957696) after [BrazilJS](https://2014.braziljs.org/en) in Rio de Janeiro: 11 | 12 | > .@bassistance & @leobalter closing bugs on @qunitjs. 13 | > 14 | > 15 | -------------------------------------------------------------------------------- /test/cli/fixtures/callbacks-rejected.tap.txt: -------------------------------------------------------------------------------- 1 | # name: rejection from callbacks 2 | # command: ["qunit", "callbacks-rejected.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: "Error: begin" 8 | severity: failed 9 | stack: | 10 | Error: begin 11 | at /qunit/test/cli/fixtures/callbacks-rejected.js:8:25 12 | at qunit.js 13 | at internal 14 | ... 15 | Bail out! Error: begin 16 | 17 | # stderr 18 | Error: Process exited before tests finished running 19 | 20 | # exit code: 1 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/assert-throws-failure.tap.txt: -------------------------------------------------------------------------------- 1 | # name: report assert.throws() failures properly 2 | # command: ["qunit", "assert-throws-failure.js"] 3 | 4 | TAP version 13 5 | not ok 1 Throws match > bad 6 | --- 7 | message: match error 8 | severity: failed 9 | actual : "Error: Match me with a pattern" 10 | expected: "/incorrect pattern/" 11 | stack: | 12 | at /qunit/test/cli/fixtures/assert-throws-failure.js:3:12 13 | ... 14 | 1..1 15 | # pass 0 16 | # skip 0 17 | # todo 0 18 | # fail 1 19 | 20 | # exit code: 1 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-test.js: -------------------------------------------------------------------------------- 1 | QUnit.test('implicitly skipped test', function (assert) { 2 | assert.true(false, 'test should be skipped'); 3 | }); 4 | 5 | QUnit.only('run this test', function (assert) { 6 | assert.true(true, 'only this test should run'); 7 | }); 8 | 9 | QUnit.test('another implicitly skipped test', function (assert) { 10 | assert.true(false, 'test should be skipped'); 11 | }); 12 | 13 | QUnit.only('all tests with only run', function (assert) { 14 | assert.true(true, 'this test should run as well'); 15 | }); 16 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-test-throw.js: -------------------------------------------------------------------------------- 1 | QUnit.test('throw early', async function (_assert) { 2 | throw new Error('boo'); 3 | }); 4 | 5 | QUnit.test('throw late', async function (assert) { 6 | await Promise.resolve(''); 7 | assert.true(true); 8 | throw new Error('boo'); 9 | }); 10 | 11 | // See "bad thenable" in /src/test.js#resolvePromise 12 | QUnit.test('test with bad thenable', function (assert) { 13 | assert.true(true); 14 | return { 15 | then: function () { 16 | throw new Error('boo'); 17 | } 18 | }; 19 | }); 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-requireExpects.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.expect() missing and config.requireExpects=true 2 | # command: ["qunit","config-requireExpects.js"] 3 | 4 | TAP version 13 5 | not ok 1 passing test 6 | --- 7 | message: Expected number of assertions to be defined, but expect() was not called. 8 | severity: failed 9 | stack: | 10 | at /qunit/test/cli/fixtures/config-requireExpects.js:3:7 11 | at internal 12 | ... 13 | 1..1 14 | # pass 0 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 20 | -------------------------------------------------------------------------------- /test/benchmark/micro.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Micro benchmark 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/cli/fixtures/event-runEnd-memory.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "event-runEnd-memory.js"] 2 | 3 | TAP version 13 4 | ok 1 First > A 5 | not ok 2 First > B 6 | --- 7 | message: failed 8 | severity: failed 9 | actual : false 10 | expected: true 11 | stack: | 12 | at /qunit/test/cli/fixtures/event-runEnd-memory.js:15:16 13 | ... 14 | ok 3 Second > C 15 | 1..3 16 | # pass 2 17 | # skip 0 18 | # todo 0 19 | # fail 1 20 | # early runEnd total=3 passed=2 failed=1 21 | # late runEnd total=3 passed=2 failed=1 22 | 23 | # exit code: 1 24 | -------------------------------------------------------------------------------- /test/node/storage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | _store: Object.create(null), 3 | setItem: function (key, value) { 4 | this._store[key] = value; 5 | }, 6 | getItem: function (key) { 7 | return key in this._store ? this._store[key] : null; 8 | }, 9 | removeItem: function (key) { 10 | if (key in this._store) { 11 | delete this._store[key]; 12 | } 13 | }, 14 | key: function (i) { 15 | return Object.keys(this._store)[i]; 16 | }, 17 | get length () { 18 | return Object.keys(this._store).length; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /docs/_posts/2016-02-23-qunit-1-22-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.22.0 Released" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: New [`assert.pushResult()`](https://qunitjs.com/api/assert/pushResult/) method. (YongWoo Jeon) [#920](https://github.com/qunitjs/qunit/pull/920) 12 | * Assert: Extend Assert methods to QUnit for backwards compatibility. 13 | * HTML Reporter: Escape setUrl output. 14 | 15 | ## See also 16 | 17 | * [Git tag: 1.22.0](https://github.com/qunitjs/qunit/releases/tag/1.22.0) 18 | -------------------------------------------------------------------------------- /test/cli/fixtures/assert-expect-no-assertions.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.expect() no assertions 2 | # command: ["qunit", "assert-expect-no-assertions.js"] 3 | 4 | TAP version 13 5 | not ok 1 no assertions 6 | --- 7 | message: Expected at least one assertion, but none were run - call expect(0) to accept zero assertions. 8 | severity: failed 9 | stack: | 10 | at /qunit/test/cli/fixtures/assert-expect-no-assertions.js:1:7 11 | at internal 12 | ... 13 | 1..1 14 | # pass 0 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-regex-exclude.js: -------------------------------------------------------------------------------- 1 | // regular expression (case-sensitive), inverted 2 | QUnit.config.filter = '!/Foo|bar/'; 3 | 4 | QUnit.module('filter'); 5 | 6 | QUnit.test('foo test', function (assert) { 7 | assert.true(true); 8 | }); 9 | 10 | QUnit.test('Foo test', function (assert) { 11 | assert.true(false, 'Foo is excluded'); 12 | }); 13 | 14 | QUnit.test('bar test', function (assert) { 15 | assert.true(false, 'bar is excluded'); 16 | }); 17 | 18 | QUnit.test('Bar test', function (assert) { 19 | assert.true(true); 20 | }); 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-notrycatch-hook-rejection.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "config-notrycatch-hook-rejection.js"] 2 | 3 | TAP version 13 4 | FOUND Unhandled Rejection: bad things happen 5 | not ok 1 example > passing test 6 | --- 7 | message: "global failure: bad things happen" 8 | severity: failed 9 | stack: | 10 | at internal 11 | ... 12 | --- 13 | message: Test took longer than 1000ms; test timed out. 14 | severity: failed 15 | ... 16 | 1..1 17 | # pass 0 18 | # skip 0 19 | # todo 0 20 | # fail 1 21 | 22 | # exit code: 1 23 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-testTimeout-invalid.js: -------------------------------------------------------------------------------- 1 | QUnit.test('invalid [undefined]', function (assert) { 2 | QUnit.config.testTimeout = undefined; 3 | setTimeout(assert.async(), 7); 4 | assert.true(true); 5 | }); 6 | 7 | QUnit.test('invalid [null]', function (assert) { 8 | QUnit.config.testTimeout = null; 9 | setTimeout(assert.async(), 7); 10 | assert.true(true); 11 | }); 12 | 13 | QUnit.test('invalid [string]', function (assert) { 14 | QUnit.config.testTimeout = '9412'; 15 | setTimeout(assert.async(), 7); 16 | assert.true(true); 17 | }); 18 | -------------------------------------------------------------------------------- /docs/_posts/2017-04-17-qunit-2-3-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.3.2 Released: Bug fixes" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * HTML Reporter: Add specific diff for number types instead of str-diff. (Adrian Leonhard) [#1155](https://github.com/qunitjs/qunit/issues/1155) 12 | * Core: Fix bug calling hooks with skipped tests. (Ben Demboski) [#1156](https://github.com/qunitjs/qunit/issues/1156) 13 | 14 | ## See also 15 | 16 | * [Git tag: 2.3.2](https://github.com/qunitjs/qunit/releases/tag/2.3.2) 17 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callbacks-done.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error in "done" callback 2 | # command: ["qunit", "uncaught-error-callbacks-done.js"] 3 | 4 | TAP version 13 5 | ok 1 module1 > test1 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | Bail out! Error: No dice 12 | --- 13 | message: "Error: No dice" 14 | severity: failed 15 | stack: | 16 | Error: No dice 17 | at /qunit/test/cli/fixtures/uncaught-error-callbacks-done.js:2:9 18 | at qunit.js 19 | at internal 20 | ... 21 | 22 | # exit code: 1 23 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-notrycatch-test-rejection.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "config-notrycatch-test-rejection.js"] 2 | 3 | TAP version 13 4 | FOUND Unhandled Rejection: bad things happen 5 | not ok 1 example > returns a rejected promise 6 | --- 7 | message: "global failure: bad things happen" 8 | severity: failed 9 | stack: | 10 | at internal 11 | ... 12 | --- 13 | message: Test took longer than 1000ms; test timed out. 14 | severity: failed 15 | ... 16 | 1..1 17 | # pass 0 18 | # skip 0 19 | # todo 0 20 | # fail 1 21 | 22 | # exit code: 1 23 | -------------------------------------------------------------------------------- /docs/_data/sidebar_api.yml: -------------------------------------------------------------------------------- 1 | - group: main 2 | expand: initial 3 | initial: /api/ 4 | 5 | - group: assert 6 | 7 | - group: callbacks 8 | 9 | - group: async 10 | # These pages are all in at least one other group. 11 | # It exists for discoverability, but we don't need 12 | # to highlight its pages in two places. 13 | expand: false 14 | 15 | - title: Configuration 16 | group: config 17 | 18 | - title: Reporters 19 | group: reporters 20 | 21 | - group: extension 22 | 23 | - group: deprecated 24 | expand: false 25 | 26 | - group: removed 27 | expand: false 28 | -------------------------------------------------------------------------------- /docs/_posts/2018-08-19-qunit-2-6-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.6.2 Released" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * Assert: Remove redundant return statement from `assert.pushResult()`. (Ger Hobbelt) [#1298](https://github.com/qunitjs/qunit/pull/1298) 14 | * CLI: Update `fsevents` extension for Node 10 compatibility. (Tobias Bieniek) [#1295](https://github.com/qunitjs/qunit/pull/1295) 15 | 16 | ## See also 17 | 18 | * [Git tag: 2.6.2](https://github.com/qunitjs/qunit/releases/tag/2.6.2) 19 | -------------------------------------------------------------------------------- /docs/_posts/2024-08-18-qunit-2-22-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.22.0 Released: Add test.if" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Introduce `test.if()` and `module.if()` functions to facilitate conditional skipping. 10 | 11 | ## Changelog 12 | 13 | ### Added 14 | 15 | * Core: Add [`QUnit.test.if()`](https://qunitjs.com/api/QUnit/test.if/) and `QUnit.module.if()`. (Timo Tijhof) [#1772](https://github.com/qunitjs/qunit/pull/1772) 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.22.0](https://github.com/qunitjs/qunit/releases/tag/2.22.0) 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-in-hook.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error in hook 2 | # command: ["qunit", "uncaught-error-in-hook.js"] 3 | 4 | TAP version 13 5 | not ok 1 contains a hard error in hook > contains a hard error 6 | --- 7 | message: "before failed on contains a hard error: expected error thrown in hook" 8 | severity: failed 9 | stack: | 10 | Error: expected error thrown in hook 11 | at /qunit/test/cli/fixtures/uncaught-error-in-hook.js:3:11 12 | ... 13 | 1..1 14 | # pass 0 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 20 | -------------------------------------------------------------------------------- /docs/_posts/2016-07-23-qunit-2-0-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.0.1 Released" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Core: Prevent multiple "begin" events from calling `QUnit.load()`. 12 | * Core: Use callback-based pause/resume for better multi-pause isolation. 13 | * HTML Reporter: Fix apply/reset button visibility. 14 | * Core: Ensure runtime for skipped tests is 0. 15 | * Dump: New parser for `Symbol` type. 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.0.1](https://github.com/qunitjs/qunit/releases/tag/2.0.1) 20 | -------------------------------------------------------------------------------- /docs/_posts/2017-03-30-cli-support.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: We have CLI support!" 4 | image: /resources/2017-qunit-cli-demo.jpg 5 | author: trentmwillis 6 | tags: 7 | - link 8 | --- 9 | 10 | We have CLI support! 11 | 12 | * [QUnit 2.3.0 Released: QUnit CLI]({% post_url 2017-03-29-qunit-2-3-0 %}) 13 | * 14 | 15 |
16 | 17 | ------- 18 | 19 | _Originally published on [Twitter](https://twitter.com/qunitjs/status/847161403517620224)._ 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-callbacks-begin.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error in "begin" callback 2 | # command: ["qunit", "uncaught-error-callbacks-begin.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: "Error: No dice" 8 | severity: failed 9 | stack: | 10 | Error: No dice 11 | at /qunit/test/cli/fixtures/uncaught-error-callbacks-begin.js:2:9 12 | at qunit.js 13 | at internal 14 | ... 15 | Bail out! Error: No dice 16 | 17 | # stderr 18 | Error: Process exited before tests finished running 19 | 20 | # exit code: 1 21 | -------------------------------------------------------------------------------- /demos/karma-qunit/karma.conf.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | module.exports = function (config) { 4 | config.set({ 5 | browsers: [ 6 | 'FirefoxHeadless' 7 | ], 8 | client: process.env.KARMA_QUNIT_CONFIG 9 | ? { 10 | qunit: { 11 | testTimeout: 1991, 12 | fooBar: 'xyz' 13 | } 14 | } 15 | : {}, 16 | frameworks: ['qunit'], 17 | files: [ 18 | process.env.KARMA_FILES || 'pass-basic.js' 19 | ], 20 | autoWatch: false, 21 | singleRun: true, 22 | reporters: ['dots'] 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /docs/_posts/2020-07-04-qunit-2-10-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.10.1 Released: Bug fix" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | A quick fix for unscoped button CSS that could previously interfere with a UI test. Thanks XhmikosR for reporting and investigating! 10 | 11 | ## Changelog 12 | 13 | ### Fixed 14 | 15 | * HTML Reporter: Scope QUnit UI button style to not affect `#qunit-fixture`. (XhmikosR) [#1437](https://github.com/qunitjs/qunit/issues/1437) 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.10.1](https://github.com/qunitjs/qunit/releases/tag/2.10.1) 20 | -------------------------------------------------------------------------------- /docs/badge.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Tested with QUnit Badge 4 | --- 5 | 6 |

Use the following markup to embed a "Tested with QUnit" badge in your documentation.

7 | 8 | [![Tested with QUnit](./testedwith.svg)](/) 9 | 10 | Copy the Markdown snippet, and e.g. paste above the title your README. 11 | 12 | ```md 13 | [![Tested with QUnit](https://qunitjs.com/testedwith.svg)](https://qunitjs.com/) 14 | ``` 15 | 16 | HTML version: 17 | 18 | ```html 19 | Tested with QUnit 20 | ``` 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/unhandled-rejection.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | QUnit.module('Unhandled Rejections', function () { 4 | QUnit.test('test passes just fine, but has a rejected promise', function (assert) { 5 | assert.true(true); 6 | 7 | const done = assert.async(); 8 | 9 | Promise.resolve().then(function () { 10 | throw new Error('Error thrown in non-returned promise!'); 11 | }); 12 | 13 | // prevent test from exiting before unhandled rejection fires 14 | setTimeout(done, 10); 15 | }); 16 | 17 | Promise.reject(new Error('outside of a test context')); 18 | }); 19 | -------------------------------------------------------------------------------- /docs/_posts/2020-09-09-qunit-2-11-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.11.2 Released: Improve TAP output" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Improved TAP output alignment. Thanks @rwjblue! 10 | 11 | ## Changelog 12 | 13 | ### Fixed 14 | 15 | * CLI: Align `actual` whitespace with `expected` in TapReporter. (Robert Jackson) [js-reporters/js-reporters#107](https://github.com/js-reporters/js-reporters/pull/107) [#1481](https://github.com/qunitjs/qunit/pull/1481) 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.11.2](https://github.com/qunitjs/qunit/releases/tag/2.11.2) 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/preconfig-flat.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "preconfig-flat.js"] 2 | # env: { "qunit_config_filter": "!foobar", "qunit_config_seed": "dummyfirstyes", "qunit_config_testtimeout": 7, "qunit_config_altertitle": "true", "qunit_config_noglobals": 1, "qunit_config_notrycatch": "false" } 3 | 4 | Running tests with seed: dummyfirstyes 5 | TAP version 13 6 | ok 1 dummy 7 | not ok 2 slow 8 | --- 9 | message: Test took longer than 7ms; test timed out. 10 | severity: failed 11 | ... 12 | ok 3 config 13 | 1..3 14 | # pass 2 15 | # skip 0 16 | # todo 0 17 | # fail 1 18 | 19 | # exit code: 1 -------------------------------------------------------------------------------- /docs/_posts/2017-04-10-qunit-2-3-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.3.1 Released: Bug fixes" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: Allow assertions after async. 12 | * Assert: Throw if async callback invoked after test finishes. 13 | * Core: Ensure assertions occur while test is running. 14 | * Core: Fix test instance memory leak. [#1138](https://github.com/qunitjs/qunit/issues/1138) 15 | * Core: Slim assertions after reporting them. 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.3.1](https://github.com/qunitjs/qunit/releases/tag/2.3.1) 20 | -------------------------------------------------------------------------------- /docs/_posts/2019-02-21-qunit-2-9-2.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.9.2 Released: Bug fixes" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | A few bug fixes. 10 | 11 | ## Changelog 12 | 13 | ### Fixed 14 | 15 | * Core: Ensure semaphores are balanced when timeout occurs. (Steve Calvert) [#1376](https://github.com/qunitjs/qunit/pull/1376) 16 | * HTML Reporter: Avoid inline styles to support CSP without `unsafe-inline`. (jelhan) [#1369](https://github.com/qunitjs/qunit/pull/1369) 17 | 18 | ## See also 19 | 20 | * [Git tag: 2.9.2](https://github.com/qunitjs/qunit/releases/tag/2.9.2) 21 | -------------------------------------------------------------------------------- /.github/workflows/reproducible.yaml: -------------------------------------------------------------------------------- 1 | name: Reproducible builds 2 | on: 3 | # Once a week on Monday at 00:30 UTC 4 | schedule: 5 | - cron: '30 0 * * 1' 6 | # Or manually 7 | workflow_dispatch: 8 | 9 | jobs: 10 | run: 11 | name: Verify releases 12 | if: ${{ github.repository == 'qunitjs/qunit' }} # skip noisy cron on forks 13 | runs-on: ubuntu-22.04 14 | steps: 15 | - uses: actions/checkout@v4 16 | 17 | - name: Use Node.js 18 18 | uses: actions/setup-node@v4 19 | with: 20 | node-version: 18.x 21 | 22 | - run: node build/reproducible-builds.js 23 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-module-then-test.js: -------------------------------------------------------------------------------- 1 | // https://github.com/qunitjs/qunit/issues/1645 2 | QUnit.module('module A', function () { 3 | QUnit.test('test A1', function (assert) { 4 | assert.true(false, 'not run'); 5 | }); 6 | 7 | QUnit.module.only('module B', function () { 8 | QUnit.test('test B', function (assert) { 9 | assert.true(true, 'run'); 10 | }); 11 | }); 12 | 13 | QUnit.test.only('test A2', function (assert) { 14 | assert.true(false, 'not run'); 15 | }); 16 | 17 | QUnit.test('test A3', function (assert) { 18 | assert.true(false, 'not run'); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/seed.js: -------------------------------------------------------------------------------- 1 | QUnit.config.seed = '7x9'; 2 | 3 | var lastTest = ''; 4 | 5 | QUnit.module('QUnit.config.seed'); 6 | 7 | QUnit.test('1', function (assert) { 8 | assert.equal(lastTest, '2', 'runs third'); 9 | lastTest = '1'; 10 | }); 11 | 12 | QUnit.test('2', function (assert) { 13 | assert.equal(lastTest, '3', 'runs second'); 14 | lastTest = '2'; 15 | }); 16 | 17 | QUnit.test('3', function (assert) { 18 | assert.equal(lastTest, '', 'runs first'); 19 | lastTest = '3'; 20 | }); 21 | 22 | QUnit.test('4', function (assert) { 23 | assert.equal(lastTest, '1', 'runs last'); 24 | lastTest = '4'; 25 | }); 26 | -------------------------------------------------------------------------------- /docs/_posts/2023-09-15-qunitx.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: QUnitX" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | Check out QUnitX by [@izelnakri](https://ruby.social/@izelnakri): 10 | 11 | 12 | 13 | It is is the only universal JS/TS test framework that is fast, flexible, zero dependency, and can run your test files interchangably in Node.js, browser, or Deno environments! 14 | 15 | ------- 16 | 17 | _Originally published on [Mastodon](https://fosstodon.org/@qunit/111072681670530624) and [Twitter](https://twitter.com/qunitjs/status/1702885994222190739)._ 18 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-done.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.async() handled after fail in other test 2 | # command: ["qunit", "drooling-done.js"] 3 | 4 | TAP version 13 5 | not ok 1 Test A 6 | --- 7 | message: |+ 8 | Died on test #2: this is an intentional error 9 | at /qunit/test/cli/fixtures/drooling-done.js:5:7 10 | at internal 11 | severity: failed 12 | stack: | 13 | Error: this is an intentional error 14 | at /qunit/test/cli/fixtures/drooling-done.js:8:9 15 | ... 16 | ok 2 Test B 17 | 1..2 18 | # pass 1 19 | # skip 0 20 | # todo 0 21 | # fail 1 22 | 23 | # exit code: 1 24 | 25 | -------------------------------------------------------------------------------- /docs/_posts/2018-05-15-qunit-2-6-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.6.1 Released: Bug fixes" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | Minor bug fixes and memory leaks plugged! 10 | 11 | ## Changelog 12 | 13 | ### Fixed 14 | 15 | * Core: Ensure module and test callbacks are released for GC. (Robert Jackson) [#1279](https://github.com/qunitjs/qunit/pull/1279) 16 | * HTML Reporter: Disable autocomplete on module search input. (Christian) [#1277](https://github.com/qunitjs/qunit/pull/1277) 17 | 18 | ## See also 19 | 20 | * [Git tag: 2.6.1](https://github.com/qunitjs/qunit/releases/tag/2.6.1) 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-filter-regex.js: -------------------------------------------------------------------------------- 1 | // regular expression (case-insensitive) 2 | QUnit.config.filter = '/foo|bar/i'; 3 | 4 | QUnit.module('filter'); 5 | 6 | QUnit.test('foo test', function (assert) { 7 | assert.true(true); 8 | }); 9 | 10 | QUnit.test('FOO test', function (assert) { 11 | assert.true(true); 12 | }); 13 | 14 | QUnit.test('boo test', function (assert) { 15 | assert.true(false, 'boo does not match'); 16 | }); 17 | 18 | QUnit.test('bar test', function (assert) { 19 | assert.true(true); 20 | }); 21 | 22 | QUnit.test('baz test', function (assert) { 23 | assert.true(false, 'baz does not match'); 24 | }); 25 | -------------------------------------------------------------------------------- /test/cli/fixtures/syntax-error.tap.txt: -------------------------------------------------------------------------------- 1 | # name: load file with syntax error 2 | # command: ["qunit", "syntax-error.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: |+ 8 | Error: Failed to load file syntax-error.js 9 | ReferenceError: varIsNotDefined is not defined 10 | severity: failed 11 | stack: | 12 | ReferenceError: varIsNotDefined is not defined 13 | at /qunit/test/cli/fixtures/syntax-error.js:1:1 14 | at internal 15 | ... 16 | Bail out! Error: Failed to load file syntax-error.js 17 | 1..2 18 | # pass 0 19 | # skip 0 20 | # todo 0 21 | # fail 2 22 | 23 | # exit code: 1 24 | -------------------------------------------------------------------------------- /test/preconfig-flat.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | preconfig-flat 6 | 7 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /test/browser-runner/amd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | amd 6 | 7 | 8 | 9 | 10 | 11 |
12 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /test/browser-runner/config-fixture-null.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('QUnit.config [fixture=null]'); 3 | 4 | QUnit.config.reorder = false; 5 | QUnit.config.fixture = null; 6 | 7 | QUnit.test('make dirty', function (assert) { 8 | assert.strictEqual(QUnit.config.fixture, null); 9 | 10 | var fixture = document.querySelector('#qunit-fixture'); 11 | fixture.textContent = 'dirty'; 12 | }); 13 | 14 | QUnit.test('find dirty', function (assert) { 15 | assert.strictEqual(QUnit.config.fixture, null); 16 | 17 | var fixture = document.querySelector('#qunit-fixture'); 18 | assert.strictEqual(fixture.textContent, 'dirty'); 19 | }); 20 | -------------------------------------------------------------------------------- /test/main/setTimeout.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | // eslint-disable-next-line no-undef 3 | var global = typeof globalThis !== 'undefined' ? globalThis : window; 4 | QUnit.module('Support for mocked setTimeout', { 5 | beforeEach: function () { 6 | this.setTimeout = global.setTimeout; 7 | global.setTimeout = function () {}; 8 | }, 9 | 10 | afterEach: function () { 11 | global.setTimeout = this.setTimeout; 12 | } 13 | }); 14 | 15 | QUnit.test('test one', function (assert) { 16 | assert.true(true); 17 | }); 18 | 19 | QUnit.test('test two', function (assert) { 20 | assert.true(true); 21 | }); 22 | }()); 23 | -------------------------------------------------------------------------------- /docs/_posts/2012-05-04-qunit-1-6-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.6.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Addons/Composite: Double clicking on composite test rows opens individual test page. 12 | * Core: Only check for an `exports` object to detect a CommonJS environment, fixes compat with RequireJS. [#237](https://github.com/qunitjs/qunit/issues/237) 13 | * HTML Reporter: Prefix test-output id and ignore that in noglobals check. [#212](https://github.com/qunitjs/qunit/issues/212) 14 | 15 | ## See also 16 | 17 | * [Git tag: 1.6.0](https://github.com/qunitjs/qunit/releases/tag/1.6.0) 18 | -------------------------------------------------------------------------------- /test/cli/fixtures/too-many-done-calls.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.async() handled too often 2 | # command: ["qunit", "too-many-done-calls.js"] 3 | 4 | TAP version 13 5 | not ok 1 Test A 6 | --- 7 | message: |+ 8 | Died on test #2: Tried to release async pause that was already released. 9 | > Test: Test A [async #1] 10 | at /qunit/test/cli/fixtures/too-many-done-calls.js:1:7 11 | at internal 12 | severity: failed 13 | stack: | 14 | Error: Tried to release async pause that was already released. 15 | > Test: Test A [async #1] 16 | ... 17 | 1..1 18 | # pass 0 19 | # skip 0 20 | # todo 0 21 | # fail 1 22 | 23 | # exit code: 1 24 | -------------------------------------------------------------------------------- /docs/api/config/requireExpects.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.requireExpects 4 | excerpt: Fail tests that don't specify how many assertions they expect. 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/requireExpects/" 9 | version_added: "1.7.0" 10 | --- 11 | 12 | Fail tests that don't specify how many assertions they expect. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`boolean`
default`false`
24 | 25 | Enabling this option will cause tests to fail if they don't call [`assert.expect()`](../assert/expect.md). 26 | -------------------------------------------------------------------------------- /test/cli/fixtures/config-testTimeout-invalid.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "config-testTimeout-invalid.js"] 2 | 3 | TAP version 13 4 | ok 1 invalid [undefined] 5 | ok 2 invalid [null] 6 | ok 3 invalid [string] 7 | 1..3 8 | # pass 3 9 | # skip 0 10 | # todo 0 11 | # fail 0 12 | 13 | # stderr 14 | QUnit.config.testTimeout was set to an an invalid value (undefined). Using default. https://qunitjs.com/api/config/testTimeout/ 15 | QUnit.config.testTimeout was set to an an invalid value (null). Using default. https://qunitjs.com/api/config/testTimeout/ 16 | QUnit.config.testTimeout was set to an an invalid value (string). Using default. https://qunitjs.com/api/config/testTimeout/ 17 | -------------------------------------------------------------------------------- /test/node/storage-2.js: -------------------------------------------------------------------------------- 1 | var mockStorage = require('./storage.js'); 2 | 3 | QUnit.module('Storage #2', function () { 4 | QUnit.test('clears all qunit-test-* items after a successful run', function (assert) { 5 | assert.strictEqual( 6 | mockStorage.getItem('should-not-remove'), 7 | true, 8 | 'state was persisted from last test' 9 | ); 10 | assert.strictEqual( 11 | mockStorage.getItem('qunit-test-should-remove'), 12 | null, 13 | 'removed first test' 14 | ); 15 | assert.strictEqual( 16 | mockStorage.getItem('qunit-test-should-also-remove'), 17 | null, 18 | 'removed second test' 19 | ); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /docs/_posts/2021-03-14-qunit-2-14-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.14.1 Released: Bug fixes" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Thanks Edward (@eaf4)! 10 | 11 | ## Changelog 12 | 13 | ### Changed 14 | 15 | * CLI: Upgrade `commander` to 7.1.0. (Timo Tijhof) [#1564](https://github.com/qunitjs/qunit/issues/1564) 16 | 17 | ### Fixed 18 | 19 | * Core: Restore strict mode compatibility (Edward Faulkner) [#1558](https://github.com/qunitjs/qunit/pull/1558) 20 | * HTML Reporter: Check for undefined `testItem` in testDone callback. (Timo Tijhof) 21 | 22 | ## See also 23 | 24 | * [Git tag: 2.14.1](https://github.com/qunitjs/qunit/releases/tag/2.14.1) 25 | -------------------------------------------------------------------------------- /docs/_posts/2012-06-14-qunit-1-8-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.8.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: Avoid global eval error from `assert.raises()` being reported as global exception in IE. [#257](https://github.com/qunitjs/qunit/issues/257) 12 | * Core: Reset config.current at the right time. [#260](https://github.com/qunitjs/qunit/issues/260) 13 | * HTML Reporter: Improve window.onerror handling. 14 | * HTML Reporter: New `module` url parameter. [#252](https://github.com/qunitjs/qunit/issues/252) 15 | 16 | ## See also 17 | 18 | * [Git tag: 1.8.0](https://github.com/qunitjs/qunit/releases/tag/1.8.0) 19 | -------------------------------------------------------------------------------- /test/cli/fixtures/perf-mark.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | 3 | QUnit.config.reorder = false; 4 | 5 | QUnit.test('foo', function (assert) { 6 | assert.true(true); 7 | }); 8 | 9 | QUnit.test('bar', function (assert) { 10 | assert.true(true); 11 | }); 12 | 13 | QUnit.test('getEntries', function (assert) { 14 | const entries = performance.getEntriesByType('measure') 15 | .filter(function (entry) { 16 | return entry.name.indexOf('QUnit') === 0; 17 | }) 18 | .map(function (entry) { 19 | return entry.toJSON(); 20 | }); 21 | 22 | assert.propContains(entries, [ 23 | { name: 'QUnit Test: foo' }, 24 | { name: 'QUnit Test: bar' } 25 | ]); 26 | }); 27 | -------------------------------------------------------------------------------- /docs/_posts/2024-12-03-qunit-2-23-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.23.0 Released: Automatic labels" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Your data can now directly serve as its own label for test cases, because [`QUnit.test.each()`](https://qunitjs.com/api/QUnit/test.each/) now automatically assigns labels to each array item. 10 | 11 | ## Changelog 12 | 13 | ### Added 14 | 15 | * Core: Add automatic labels in [`QUnit.test.each()`](https://qunitjs.com/api/QUnit/test.each/) to simple array values. [#1733](https://github.com/qunitjs/qunit/issues/1733) 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.23.0](https://github.com/qunitjs/qunit/releases/tag/2.23.0) 20 | -------------------------------------------------------------------------------- /docs/resources/example-add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | QUnit 5 | 6 | 7 |
8 |
9 | 10 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-extra-done.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.async() handled again in other test 2 | # command: ["qunit", "drooling-extra-done.js"] 3 | 4 | TAP version 13 5 | ok 1 Test A 6 | not ok 2 Test B 7 | --- 8 | message: |+ 9 | Died on test #2: Unexpected release of async pause during a different test. 10 | > Test: Test A [async #1] 11 | at /qunit/test/cli/fixtures/drooling-extra-done.js:13:7 12 | at internal 13 | severity: failed 14 | stack: | 15 | Error: Unexpected release of async pause during a different test. 16 | > Test: Test A [async #1] 17 | ... 18 | 1..2 19 | # pass 1 20 | # skip 0 21 | # todo 0 22 | # fail 1 23 | 24 | # exit code: 1 25 | -------------------------------------------------------------------------------- /docs/_posts/2013-09-13-wordpress-qunit-for-javascript-unit-tests.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: WordPress starts unit testing with QUnit" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | Aaron Jorbin wrote on the official [Make WordPress](https://make.wordpress.org/core/2013/09/13/javascript-unit-tests-for-core/) blog: 10 | 11 | > Recently WordPress added QUnit as a JavaScript unit testing framework and added its first JavaScript unit tests. I thought I would walk through how to run the tests and how to write tests so that we can increase our JavaScript test coverage. […] 12 | 13 | ## See also 14 | 15 | * [WordPress Trac #25088](https://core.trac.wordpress.org/ticket/25088) 16 | -------------------------------------------------------------------------------- /docs/_posts/2023-01-23-qunit-2-19-4.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.19.4 Released: Bug fix" 4 | author: krinkle 5 | excerpt: Fixes a memory leak. 6 | tags: 7 | - release 8 | --- 9 | 10 | ## Changelog 11 | 12 | ### Fixed 13 | 14 | * Core: Fix memory leak via `config.timeoutHandler` from last async test. (Sergey Astapov) [#1708](https://github.com/qunitjs/qunit/pull/1708) 15 | 16 | ## See also 17 | 18 | * [Git tag: 2.19.4](https://github.com/qunitjs/qunit/releases/tag/2.19.4) 19 | * [QUnit 2.4.0 Released: Fix memory release in assert.deepEqual]({% post_url 2017-07-08-qunit-2-4-0 %}) 20 | * [QUnit 2.3.1 Released: Fix memory leak of test instance]({% post_url 2017-04-10-qunit-2-3-1 %}) 21 | -------------------------------------------------------------------------------- /docs/_sass/amethyst-variables.scss: -------------------------------------------------------------------------------- 1 | // Amethyst theme variables for QUnit 2 | // https://qunitjs.com/brand/ 3 | 4 | // Primary color 5 | // 6 | // Usage: link text color, primary button background. 7 | $color-vibrant: #9c3493; // QUnit Primary Purple (Hue 300) 8 | 9 | // Dark shade 10 | // 11 | // Usage: navigation background, heading text color 12 | $color-accent: #390F39; // QUnit Secondary Purple 13 | 14 | // Bright color 15 | // 16 | // Very close to white, generally within 20 hue points of $color-vibrant, 17 | // and within the following range: `hsl(???, 80-84%, 72-92%)` 18 | // 19 | // Usage: navigation link color, search result highlight background 20 | $color-bright: hsl(300, 80%, 92.2%); 21 | -------------------------------------------------------------------------------- /docs/_posts/2025-01-22-wdio-qunit-service.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: WebdriverIO QUnit Service" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | Mauricio Lauffer demo'ing the new [wdio-qunit-service](https://webdriver.io/docs/wdio-qunit-service/) package: 10 | 11 | > WebdriverIO QUnit Service now supports all sort of QUnit usage in SAP Fiori and UI5 apps! Whatever UI5/QUnit testing method you're using, you can run it with wdio-qunit-service. 12 | All you need is a wdio.conf.js file. Have a look at an example: 13 | > 14 | 15 | (via [@mauriciolauffer on Bluesky](https://bsky.app/profile/mauriciolauffer.bsky.social/post/3lgdbcls73c2s)) 16 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-module.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module.only() nested 2 | # command: ["qunit", "only-module.js"] 3 | 4 | TAP version 13 5 | not ok 1 module B > Only this module should run > a todo test # TODO 6 | --- 7 | message: not implemented yet 8 | severity: todo 9 | actual : false 10 | expected: true 11 | stack: | 12 | at /qunit/test/cli/fixtures/only-module.js:16:18 13 | ... 14 | ok 2 module B > Only this module should run > implicitly skipped test # SKIP 15 | ok 3 module B > Only this module should run > normal test 16 | ok 4 module D > test D 17 | ok 5 module E > module F > test F 18 | ok 6 module E > test E 19 | 1..6 20 | # pass 4 21 | # skip 1 22 | # todo 1 23 | # fail 0 24 | -------------------------------------------------------------------------------- /test/cli/fixtures/uncaught-error-after-assert-async.tap.txt: -------------------------------------------------------------------------------- 1 | # name: uncaught error after assert.async() 2 | # command: ["qunit", "uncaught-error-after-assert-async.js"] 3 | 4 | TAP version 13 5 | not ok 1 contains a hard error after using assert.async() 6 | --- 7 | message: |+ 8 | Died on test #2: expected error thrown in test 9 | at /qunit/test/cli/fixtures/uncaught-error-after-assert-async.js:1:7 10 | at internal 11 | severity: failed 12 | stack: | 13 | Error: expected error thrown in test 14 | at /qunit/test/cli/fixtures/uncaught-error-after-assert-async.js:4:9 15 | ... 16 | 1..1 17 | # pass 0 18 | # skip 0 19 | # todo 0 20 | # fail 1 21 | 22 | # exit code: 1 23 | -------------------------------------------------------------------------------- /docs/_posts/2017-03-29-qunit-2-3-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.3.0 Released: QUnit CLI" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Added 12 | 13 | * CLI: Introduce [QUnit CLI]({% link cli.md %}). (Trent Willis) [#1115](https://github.com/qunitjs/qunit/pull/1115) 14 | * CLI: Add file watching option. 15 | * CLI: Add seed option. 16 | * CLI: Add support for custom reporters. 17 | * HTML Reporter: Display todo tests when `hidepassed` is set. 18 | 19 | ### Changed 20 | 21 | * Core: `Test#pushFailure` now calls `Test#pushResult` internally. 22 | 23 | ## See also 24 | 25 | * [Git tag: 2.3.0](https://github.com/qunitjs/qunit/releases/tag/2.3.0) 26 | -------------------------------------------------------------------------------- /docs/_posts/2024-02-15-qunit-2-20-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.20.1 Released: Bug fixes" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Fix IE compat with `sinon.useFakeTimers`, and fix hanging `assert.async()`. 10 | 11 | Welcome Timmy Willison as QUnit contributor! 12 | 13 | ## Changelog 14 | 15 | ### Fixed 16 | 17 | * Core: Fix compatibility with `sinon.useFakeTimers` in IE 10 and IE 11. (Timmy Willison) [#1738](https://github.com/qunitjs/qunit/pull/1738) 18 | * Core: Fix hanging `assert.async()` after `assert.timeout()`. (Timo Tijhof) [#1705](https://github.com/qunitjs/qunit/issues/1705) 19 | 20 | ## See also 21 | 22 | * [Git tag: 2.20.1](https://github.com/qunitjs/qunit/releases/tag/2.20.1) 23 | -------------------------------------------------------------------------------- /docs/api/config/failOnZeroTests.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.failOnZeroTests 4 | excerpt: Fail the test run if no tests were run. 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/failOnZeroTests/" 9 | version_added: "2.16.0" 10 | --- 11 | 12 | Whether to fail the test run if no tests were run. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`boolean`
default`true`
24 | 25 | By default, it is considered an error if no tests were loaded, or if no tests matched the current filter. 26 | 27 | Set this option to `false` to let an empty test run result in a success instead. 28 | -------------------------------------------------------------------------------- /test/urlparams-filter.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | if (!location.search) { 3 | // regular expression (case-sensitive), inverted 4 | location.replace('?filter=!/Foo|bar/'); 5 | } 6 | 7 | QUnit.module('filter'); 8 | 9 | QUnit.test('config parsed', function (assert) { 10 | assert.strictEqual(QUnit.config.filter, '!/Foo|bar/'); 11 | }); 12 | 13 | QUnit.test('foo test', function (assert) { 14 | assert.true(true); 15 | }); 16 | 17 | QUnit.test('Foo test', function (assert) { 18 | assert.true(false, 'Foo is excluded'); 19 | }); 20 | 21 | QUnit.test('bar test', function (assert) { 22 | assert.true(false, 'bar is excluded'); 23 | }); 24 | 25 | QUnit.test('Bar test', function (assert) { 26 | assert.true(true); 27 | }); 28 | -------------------------------------------------------------------------------- /docs/_posts/2016-02-01-qunit-1-21-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.21.0 Released: Faster deepEqual" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: Improve speed of `assert.deepEqual()` and `QUnit.equiv()`. (Richard Gibson) [#895](https://github.com/qunitjs/qunit/issues/895) 12 | * Assert: Fully support Object-wrapped primitives in `assert.deepEqual()`. 13 | * Assert: Register notOk as a non-negative assertion. 14 | * Core: Improve regular expression comparisons. 15 | * Core: Support filtering by regular expression. 16 | * HTML Reporter: Fix hidden test results under static parents. 17 | 18 | ## See also 19 | 20 | * [Git tag: 1.21.0](https://github.com/qunitjs/qunit/releases/tag/1.21.0) 21 | -------------------------------------------------------------------------------- /docs/api/extension/QUnit.assert.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.assert 4 | excerpt: Namespace for QUnit assertion methods. 5 | groups: 6 | - extension 7 | redirect_from: 8 | - "/config/QUnit.assert/" 9 | - "/extension/QUnit.assert/" 10 | version_added: "1.7.0" 11 | --- 12 | 13 | Namespace for QUnit assertion methods. This object is the prototype for the internal Assert class of which instances are passed as the argument to [`QUnit.test()`](../QUnit/test.md) callbacks. 14 | 15 | This object contains QUnit's [built-in assertion methods](../assert/index.md), and may be extended by plugins to register additional assertion methods. 16 | 17 | See [`assert.pushResult()`](../assert/pushResult.md) for how to create a custom assertion. 18 | -------------------------------------------------------------------------------- /test/browser-runner/window-onerror-preexisting-handler.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | window.onerror with pre-existing handler 6 | 7 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /test/perf-mark.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | 3 | QUnit.config.reorder = false; 4 | 5 | QUnit.test('foo', function (assert) { 6 | assert.true(true); 7 | }); 8 | 9 | QUnit.test('bar', function (assert) { 10 | assert.true(true); 11 | }); 12 | 13 | QUnit.test('getEntries', function (assert) { 14 | // eslint-disable-next-line compat/compat -- Only for IE 10+ and Safari 10+ 15 | var entries = performance.getEntriesByType('measure') 16 | .filter(function (entry) { 17 | return entry.name.indexOf('QUnit') === 0; 18 | }) 19 | .map(function (entry) { 20 | return entry.toJSON(); 21 | }); 22 | 23 | assert.propContains(entries, [ 24 | { name: 'QUnit Test: foo' }, 25 | { name: 'QUnit Test: bar' } 26 | ]); 27 | }); 28 | -------------------------------------------------------------------------------- /test/preconfig-flat.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('QUnit.config [preconfigured]'); 3 | 4 | QUnit.test('config', function (assert) { 5 | assert.strictEqual(QUnit.config.maxDepth, 5, 'maxDepth default'); 6 | assert.false(QUnit.config.autostart, 'autostart'); 7 | assert.strictEqual(QUnit.config.seed, 'd84af39036', 'seed'); 8 | 9 | // readFlatPreconfigBoolean 10 | assert.strictEqual(QUnit.config.altertitle, true, 'altertitle "true"'); 11 | assert.strictEqual(QUnit.config.noglobals, true, 'noglobals "1"'); 12 | assert.strictEqual(QUnit.config.notrycatch, false, 'notrycatch "false"'); 13 | }); 14 | 15 | window.addEventListener('load', function () { 16 | setTimeout(function () { 17 | QUnit.start(); 18 | }, 1); 19 | }); 20 | -------------------------------------------------------------------------------- /test/browser-runner/config-fixture-string.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | QUnit.module('QUnit.config [fixture=string]'); 3 | 4 | QUnit.config.reorder = false; 5 | QUnit.config.fixture = '

Hi there, stranger!

'; 6 | 7 | QUnit.test('example [first]', function (assert) { 8 | var fixture = document.querySelector('#qunit-fixture'); 9 | 10 | assert.strictEqual(fixture.textContent, 'Hi there, stranger!'); 11 | 12 | fixture.querySelector('strong').remove(); 13 | 14 | assert.strictEqual(fixture.textContent, 'Hi , stranger!'); 15 | }); 16 | 17 | QUnit.test('example [second]', function (assert) { 18 | var fixture = document.querySelector('#qunit-fixture'); 19 | assert.strictEqual(fixture.textContent, 'Hi there, stranger!'); 20 | }); 21 | -------------------------------------------------------------------------------- /docs/_posts/2018-02-27-qunit-2-5-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.5.1 Released: Bug fixes" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | Bunch of bug fixes and doc updates; thanks to all who contributed! 😍 10 | 11 | ## Changelog 12 | 13 | ### Changed 14 | 15 | * HTML Reporter: Restore attributes on `#qunit-fixture` between tests. (Robert Jackson) [#1250](https://github.com/qunitjs/qunit/pull/1250) 16 | * Assert: Fail test if using `assert.step()` without `assert.verifySteps()`. 17 | 18 | ### Fixed 19 | 20 | * Core: Release all processing locks when Promise rejects from a test. [#1253](https://github.com/qunitjs/qunit/pull/1253) 21 | 22 | ## See also 23 | 24 | * [Git tag: 2.5.1](https://github.com/qunitjs/qunit/releases/tag/2.5.1) 25 | -------------------------------------------------------------------------------- /test/cli/fixtures/callbacks-promises.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "callbacks-promises.js"] 2 | 3 | TAP version 13 4 | ok 1 module1 > nestedModule1 > test1 5 | ok 2 module1 > test2 6 | ok 3 module1 > nestedModule2 > test3 7 | 1..3 8 | # pass 3 9 | # skip 0 10 | # todo 0 11 | # fail 0 12 | 13 | # stderr 14 | CALLBACK: begin 15 | CALLBACK: begin2 16 | CALLBACK: moduleStart 17 | CALLBACK: moduleStart 18 | CALLBACK: testStart - test1 19 | CALLBACK: testDone - test1 20 | CALLBACK: moduleDone - module1 > nestedModule1 21 | CALLBACK: testStart - test2 22 | CALLBACK: testDone - test2 23 | CALLBACK: moduleStart 24 | CALLBACK: testStart - test3 25 | CALLBACK: testDone - test3 26 | CALLBACK: moduleDone - module1 > nestedModule2 27 | CALLBACK: moduleDone - module1 28 | CALLBACK: done 29 | -------------------------------------------------------------------------------- /test/cli/fixtures/module-nested.js: -------------------------------------------------------------------------------- 1 | // Regression test for https://github.com/qunitjs/qunit/issues/1478 2 | 3 | try { 4 | QUnit.module('module 1', () => { 5 | QUnit.test('test in module 1', assert => { 6 | assert.true(true); 7 | }); 8 | }); 9 | } catch (e) { 10 | // Ignore 11 | } 12 | 13 | try { 14 | QUnit.module('module 2', () => { 15 | // trigger an error in executeNow 16 | undefined(); 17 | 18 | QUnit.test('test in module 2', assert => { 19 | assert.true(true); 20 | }); 21 | }); 22 | } catch (e) { 23 | // Ignore 24 | } 25 | 26 | try { 27 | QUnit.module('module 3', () => { 28 | QUnit.test('test in module 3', assert => { 29 | assert.true(true); 30 | }); 31 | }); 32 | } catch (e) { 33 | // Ignore 34 | } 35 | -------------------------------------------------------------------------------- /test/sandboxed-iframe.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | 3 | window.parent.postMessage('hello', '*'); 4 | 5 | QUnit.on('testEnd', function (testEnd) { 6 | window.parent.postMessage( 7 | 'testEnd: ' + testEnd.name, 8 | '*' 9 | ); 10 | }); 11 | 12 | QUnit.on('runEnd', function (runEnd) { 13 | window.parent.postMessage( 14 | 'runEnd: status=' + runEnd.status + ', total=' + runEnd.testCounts.total, 15 | '*' 16 | ); 17 | }); 18 | 19 | QUnit.module('sandboxed', function () { 20 | QUnit.test('foo', function (assert) { 21 | assert.true(false); 22 | }); 23 | 24 | QUnit.test.only('bar', function (assert) { 25 | assert.true(true); 26 | }); 27 | 28 | QUnit.test.skip('quux', function (assert) { 29 | assert.true(false); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /demos/qunit-onerror-early.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | window-onerror-early 6 | 7 | 8 | 20 | 25 | 26 | 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /docs/_posts/2018-10-11-parallel-prototype.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Parallel testing prototype" 4 | image: /resources/2018-parallel-prototype.jpg 5 | author: trentmwillis 6 | tags: 7 | - link 8 | --- 9 | 10 | > 🎉 The most exciting "boring" demo I've ever recorded! 🎉 11 | > 12 | > Prototyping running tests in parallel in the browser with @qunitjs! 🚗💨 13 | > 14 | > The implementation will also allow Node tests to run in parallel as well, but as a UI engineer FINALLY having this in the browser will be 😍 15 | > 16 | > 17 | 18 | 19 | From Twitter ([archived](https://web.archive.org/web/20181023043044/https://twitter.com/trentmwillis/#:~:text=Prototyping%20running%20tests%20in%20parallel)). -------------------------------------------------------------------------------- /docs/api/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit API 4 | excerpt: API reference documentation for QUnit. 5 | amethyst: 6 | prepend_description_heading: false 7 | redirect_from: 8 | - "/category/all/" 9 | --- 10 | 11 | If you're new to QUnit, check out [Getting Started](../intro.md)! 12 | 13 | QUnit is a powerful, easy-to-use JavaScript unit test suite. QUnit has no dependencies and supports Node.js, SpiderMonkey, and all [major browsers](../intro.md#compatibility). 14 | 15 | 16 | 17 | * [Main methods](./QUnit/) 18 | * [Assertions](./assert/) 19 | * [Callback events](./callbacks/) 20 | * [Configuration options](./config/) 21 | * [Reporters](./reporters/) 22 | * [Extension interface](./extension/) 23 | -------------------------------------------------------------------------------- /test/cli/fixtures/drooling-extra-done-outside.tap.txt: -------------------------------------------------------------------------------- 1 | # name: assert.async() handled outside test 2 | # command: ["qunit","drooling-extra-done-outside.js"] 3 | 4 | TAP version 13 5 | ok 1 extra done scheduled outside any test 6 | 1..1 7 | # pass 1 8 | # skip 0 9 | # todo 0 10 | # fail 0 11 | Bail out! Error: Unexpected release of async pause after tests finished. 12 | --- 13 | message: |+ 14 | Error: Unexpected release of async pause after tests finished. 15 | > Test: extra done scheduled outside any test [async #1] 16 | severity: failed 17 | stack: | 18 | Error: Unexpected release of async pause after tests finished. 19 | > Test: extra done scheduled outside any test [async #1] 20 | at qunit.js 21 | at internal 22 | ... 23 | 24 | # exit code: 1 -------------------------------------------------------------------------------- /docs/_posts/2022-03-29-qunit-2-18-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.18.1 Released: Faster async testing" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | ### Fixed 12 | 13 | * HTML Reporter: Fix source attribution for test definitions. (Phani Rithvij) [#1679](https://github.com/qunitjs/qunit/issues/1679) 14 | * Core: Fix preconfig support in SpiderMonkey and other environments. [0befe2aafe](https://github.com/qunitjs/qunit/commit/0befe2aafe913704db958c472ed6f2a37ec8caaf) 15 | * Core: Improve performance of async pauses with native Map when available. [aa7314b431](https://github.com/qunitjs/qunit/commit/aa7314b431db10d321109c78041747b681e1521c) 16 | 17 | ## See also 18 | 19 | * [Git tag: 2.18.1](https://github.com/qunitjs/qunit/releases/tag/2.18.1) 20 | -------------------------------------------------------------------------------- /test/cli/fixtures/event-runEnd-memory.js: -------------------------------------------------------------------------------- 1 | QUnit.on('runEnd', function (run) { 2 | console.log(`# early runEnd total=${run.testCounts.total} passed=${run.testCounts.passed} failed=${run.testCounts.failed}`); 3 | setTimeout(function () { 4 | QUnit.on('runEnd', function (run) { 5 | console.log(`# late runEnd total=${run.testCounts.total} passed=${run.testCounts.passed} failed=${run.testCounts.failed}`); 6 | }); 7 | }); 8 | }); 9 | 10 | QUnit.module('First', function () { 11 | QUnit.test('A', function (assert) { 12 | assert.true(true); 13 | }); 14 | QUnit.test('B', function (assert) { 15 | assert.true(false); 16 | }); 17 | }); 18 | 19 | QUnit.module('Second', function () { 20 | QUnit.test('C', function (assert) { 21 | assert.true(true); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /docs/resources/calc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * calc.js - An example project to demonstrate QUnit. 3 | * 4 | * @author Timo Tijhof, 2022 5 | * @license 0BSD 6 | * @license Public domain 7 | */ 8 | 9 | /** 10 | * @param {number} a 11 | * @param {number} b 12 | * @return {number} 13 | */ 14 | export function add (a, b) { 15 | return a + b; 16 | } 17 | 18 | /** 19 | * @param {number} a 20 | * @param {number} b 21 | * @return {number} 22 | */ 23 | export function substract (a, b) { 24 | return a - b; 25 | } 26 | 27 | /** 28 | * @param {number} a 29 | * @param {number} b 30 | * @return {number} 31 | */ 32 | export function multiply (a, b) { 33 | return a * b; 34 | } 35 | 36 | /** 37 | * @param {number} x 38 | * @return {number} 39 | */ 40 | export function square (x) { 41 | return x * x; 42 | } 43 | -------------------------------------------------------------------------------- /test/main/events.js: -------------------------------------------------------------------------------- 1 | QUnit.module('events', function () { 2 | QUnit.test('QUnit.on [failure]', function (assert) { 3 | assert.throws(function () { 4 | QUnit.on(null, function () { 5 | assert.step('null called'); 6 | }); 7 | }, /must be a string/, 'null event name'); 8 | 9 | assert.throws(function () { 10 | QUnit.on('banana', function () { 11 | assert.step('banana called'); 12 | }); 13 | }, /not a valid event/, 'unknown event name'); 14 | 15 | assert.throws(function () { 16 | QUnit.on('runStart'); 17 | }, /must be a function/, 'missing callback'); 18 | 19 | assert.throws(function () { 20 | QUnit.on('runStart', null); 21 | }, /must be a function/, 'null callback'); 22 | 23 | assert.verifySteps([]); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /docs/resources/calc.test.js: -------------------------------------------------------------------------------- 1 | import * as calc from './calc.js'; 2 | 3 | QUnit.module('calc', () => { 4 | QUnit.test('add', (assert) => { 5 | assert.equal(calc.add(1, 2), 3); 6 | assert.equal(calc.add(2, 3), 5); 7 | assert.equal(calc.add(5, -1), 4, 'negative'); 8 | }); 9 | 10 | QUnit.test('substract', (assert) => { 11 | assert.equal(calc.substract(3, 2), 1); 12 | assert.equal(calc.substract(5, 3), 2); 13 | assert.equal(calc.substract(5, -1), 6, 'negative'); 14 | }); 15 | 16 | QUnit.test('multiply', (assert) => { 17 | assert.equal(calc.multiply(7, 2), 14); 18 | }); 19 | 20 | QUnit.test('square', (assert) => { 21 | assert.equal(calc.square(5), 25); 22 | assert.equal(calc.square(7), 49); 23 | assert.equal(calc.square(-8), 64, 'negative'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /docs/_posts/2019-01-06-qunit-2-9-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.9.0 Released: Reduce npm dependencies" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | We significantly reduced QUnit's install size by cutting down on dependencies. 10 | 11 | ## Changelog 12 | 13 | ### Fixed 14 | 15 | * Assert: Report errors from `assert.throws()` as strings. [#1333](https://github.com/qunitjs/qunit/issues/1333) 16 | * CLI: Reduce size of the npm package and dependency tree, from 142 dependencies, to 9 dependencies. (Timo Tijhof) [#1342](https://github.com/qunitjs/qunit/issues/1342) 17 | * HTML Reporter: Fix an unescaped `details.source`. (Shlomi Fish) [#1341](https://github.com/qunitjs/qunit/pull/1341) 18 | 19 | ## See also 20 | 21 | * [Git tag: 2.9.0](https://github.com/qunitjs/qunit/releases/tag/2.9.0) 22 | -------------------------------------------------------------------------------- /docsearch.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "index_name": "qunitjs_com", 3 | "start_urls": [ 4 | { "url": "https://qunitjs.com/blog/", "selectors_key": "blog", "page_rank": 1 }, 5 | { "url": "https://qunitjs.com", "page_rank": 20 } 6 | ], 7 | "selectors": { 8 | "lvl0": "h1", 9 | "lvl1": "h2:not(.screen-reader-text)", 10 | "lvl2": "h3:not(.screen-reader-text)", 11 | "lvl3": "h4:not(.screen-reader-text)", 12 | "lvl4": "h5:not(.screen-reader-text)", 13 | "lvl5": "h6:not(.screen-reader-text)", 14 | "text": ".content p, .content li, .content tr, .content pre" 15 | }, 16 | "custom_settings": { 17 | "token_separators": ["_", "-", "."] 18 | }, 19 | "selectors_exclude": [ 20 | ".posts", 21 | "aside.sidebar", 22 | ".toc-wrapper" 23 | ], 24 | "scrape_start_urls": false 25 | } 26 | -------------------------------------------------------------------------------- /docs/_posts/2025-08-19-sapui5-qunit.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: Use QUnit to test your SAPUI5 applications" 4 | author: krinkle 5 | tags: 6 | - link 7 | --- 8 | 9 | Ansgar Lichter wrote [How to use latest QUnit and Sinon to test your SAPUI5 applications](https://community.sap.com/t5/technology-blog-posts-by-sap/how-to-use-latest-qunit-and-sinon-to-test-your-sapui5-applications/ba-p/14156476) on the SAP Technology Blog: 10 | 11 | > In this post, we'll walk you through a setup that allows you to integrate the latest versions of Sinon and QUnit into your SAPUI5 project, unlocking its latest features, superior type-safety, and a much-improved developer experience. Let's get started! […] 12 | 13 | (via [@scntechblogs.marianzeis.de on Bluesky](https://bsky.app/profile/scntechblogs.marianzeis.de/post/3lwqmys6cvz27)) 14 | -------------------------------------------------------------------------------- /docs/_posts/2014-01-31-qunit-1-14-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.14.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Addons: Remove last remnants. 12 | * Assert: `assert.throws()` now supports comparing to Error instances. 13 | * Assert: `assert.throws()` now supports comparing to error strings. 14 | * Core: Add config property for disabling default scroll-to-top. 15 | * Core: Add support for "select one" dropdowns to `QUnit.config.urlConfig`. 16 | * Core: Cache window.clearTimeout in case it gets mocked. 17 | * Core: Run multiple tests by test number. 18 | * HTML Reporter: Removing some redundant CSS code. 19 | * Release: Set main property to qunit/qunit.js. 20 | 21 | ## See also 22 | 23 | * [Git tag: 1.14.0](https://github.com/qunitjs/qunit/releases/tag/1.14.0) 24 | -------------------------------------------------------------------------------- /docs/_posts/2017-10-21-qunit-2-4-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.4.1 Released: CLI Improvements" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | Lots of minor fixes and improvements to the CLI! 10 | 11 | ## Changelog 12 | 13 | * CLI: Add slight debounce to restarting tests on file watching. 14 | * CLI: Catch file load failures and report as failing tests. 15 | * CLI: Clear require cache of watched files between runs. 16 | * CLI: List available reporters when option is specified with no value. 17 | * CLI: Properly support watching files added after first run. 18 | * Core: Provide descriptive feedback when missing `QUnit.test()` callback. 19 | * HTML Reporter: Fix regression in error reporting. 20 | 21 | ## See also 22 | 23 | * [Git tag: 2.4.1](https://github.com/qunitjs/qunit/releases/tag/2.4.1) 24 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module() with async function 2 | # command: ["qunit","async-module-error.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: |+ 8 | Error: Failed to load file async-module-error.js 9 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 10 | severity: failed 11 | stack: | 12 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 13 | at /qunit/test/cli/fixtures/async-module-error.js:2:7 14 | at internal 15 | ... 16 | Bail out! Error: Failed to load file async-module-error.js 17 | 1..2 18 | # pass 0 19 | # skip 0 20 | # todo 0 21 | # fail 2 22 | 23 | # exit code: 1 24 | -------------------------------------------------------------------------------- /docs/api/config/scrolltop.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.scrolltop 4 | excerpt: Scroll to the top of the page after the test run. 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/scrolltop/" 9 | version_added: "1.14.0" 10 | --- 11 | 12 | In browser environments, scroll to the top of the page after the tests are done. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`boolean`
default`true`
24 | 25 | By default, QUnit scrolls the browser to the top of the page when tests are done. This reverses any programmatic scrolling performed by the application or its tests. 26 | 27 | Set this option to `false` to disable this behaviour, and thus leave the page in its final scroll position. 28 | -------------------------------------------------------------------------------- /docs/_posts/2017-11-06-npm-package.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: 'QUnit is now "qunit" on NPM' 4 | author: trentmwillis 5 | tags: 6 | - link 7 | --- 8 | 9 |

IMPORTANT: QUnit is now being published as "qunit" on NPM! Previously, we were publishing as "qunitjs".

10 | 11 | The old "qunit" package was a CLI tool that came into existence prior to a built-in CLI. That package is now published as "node-qunit". 12 | 13 | Transitioning should be simple. If you are using `qunitjs@2.4.1` you just need to drop the "js"; we have republished 2.4.1 as `qunit@2.4.1`. 14 | 15 | We hope this will help fix some confusion over package names moving forward :) 16 | 17 | 18 | 19 | ------- 20 | 21 | _Originally published on [Twitter](https://twitter.com/qunitjs/status/927346245437308928)._ 22 | -------------------------------------------------------------------------------- /docs/_posts/2016-03-25-qunit-1-23-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.23.0 Released" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Core: Move URL parameter handling to HTML Reporter. 12 | * Core: Reintroduce `QUnit.config.module`. 13 | * Core: Stop splitting URL parameter values by commas. 14 | * Core: New `moduleId`-based filtering. 15 | * Core: Introduce `QUnit.config.seed` for running tests in pseudo-random order. 16 | * Dump: Fix asymmetrical function dump argument spacing. 17 | * HTML Reporter: Fix escaping of diffs. 18 | * HTML Reporter: Add message explaining missing diff. 19 | * HTML Reporter: Fix hidepassed element check. 20 | * Assert: Treat "Set" and "Map" types as unordered in `QUnit.equiv`. 21 | 22 | ## See also 23 | 24 | * [Git tag: 1.23.0](https://github.com/qunitjs/qunit/releases/tag/1.23.0) 25 | -------------------------------------------------------------------------------- /docs/_posts/2013-03-09-javascript-jabber-podcast.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: JavaScript Jabber podcast" 4 | author: jzaefferer 5 | tags: 6 | - link 7 | --- 8 | 9 | JsJabber episode #50 in which I talk about QUnit with Charles, Joe and Jamison. 10 | 11 | 12 | 13 | * [Listen on YouTube](https://www.youtube.com/watch?v=g9ykvSI0gjg) 14 | * [Listen on Overcast](https://overcast.fm/+ABHmqorVYHk) 15 | * [Show Notes and Transcript](https://topenddevs.com/podcasts/javascript-jabber/episodes/050-jsj-qunit-with-jorn-zaefferer) 16 | -------------------------------------------------------------------------------- /.github/workflows/spider-check.yaml: -------------------------------------------------------------------------------- 1 | name: spider-check 2 | on: 3 | # Once a week on Friday at 00:00 4 | schedule: 5 | - cron: '0 0 * * 5' 6 | # Or manually 7 | workflow_dispatch: 8 | 9 | jobs: 10 | spider-check: 11 | if: ${{ github.repository_owner == 'qunitjs' }} # skip on forks 12 | runs-on: ubuntu-latest 13 | env: 14 | # Site address to crawl 15 | # 16 | # Example: 17 | # - https://example.org 18 | # - https://example.github.io/ 19 | # - https://example.github.io/my-project/ 20 | MY_SITE: https://qunitjs.com 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - name: Run hydra-link-checker 25 | run: | 26 | curl -O https://raw.githubusercontent.com/jquery/hydra-link-checker/v2.0.0/hydra.py 27 | python3 hydra.py "$MY_SITE" --config build/hydra-config.json 28 | -------------------------------------------------------------------------------- /docs/plugins.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Plugins 4 | redirect_from: 5 | - "/addons/" 6 | --- 7 | 8 |

Plugins can extend, enhance, and modify QUnit itself; as well as the developer experience of using QUnit.

9 | 10 |
    11 | {% assign _plugins = site.data.plugins | sort: "date" | reverse -%} 12 | {%- for plugin in _plugins -%} 13 |
  • 14 |

    {{ plugin.name }}

    15 |

    {{ plugin.description }}

    16 |
  • 17 | {% endfor %} 18 |
19 | 20 | Plugins are sometimes known as QUnit addons. 21 | 22 | _Note: This list is automatically generated from npm packages using the [**qunit-plugin** keyword](https://www.npmjs.com/search?q=keywords:qunit-plugin)._ 23 | -------------------------------------------------------------------------------- /docs/api/config/collapse.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.collapse 4 | excerpt: Collapse the details of failing tests after the first one (HTML Reporter). 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/collapse/" 9 | version_added: "1.0.0" 10 | --- 11 | 12 | In the HTML Reporter, collapse the details of failing tests after the first one. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`boolean`
default`true`
24 | 25 | By default, the [HTML Reporter](../../browser.md) collapses consecutive failing tests showing only the details for the first failed test. The other tests can be expanded manually with a single click on the test title. 26 | 27 | Set this option to `false` to expand the details for all failing tests. 28 | -------------------------------------------------------------------------------- /test/cli/fixtures/only-module-flat.js: -------------------------------------------------------------------------------- 1 | QUnit.module('module A'); 2 | QUnit.test('test A', function (assert) { 3 | assert.true(false, 'this test should not run'); 4 | }); 5 | 6 | QUnit.module.only('module B'); 7 | QUnit.todo('test B', function (assert) { 8 | assert.true(false, 'not implemented yet'); 9 | }); 10 | QUnit.skip('test C', function (assert) { 11 | assert.true(false, 'test should be skipped'); 12 | }); 13 | QUnit.test('test D', function (assert) { 14 | assert.true(true, 'this test should run'); 15 | }); 16 | 17 | QUnit.module('module C'); 18 | QUnit.todo('test E', function (assert) { 19 | assert.true(false, 'not implemented yet'); 20 | }); 21 | QUnit.skip('test F', function (assert) { 22 | assert.true(false, 'test should be skipped'); 23 | }); 24 | QUnit.test('test G', function (assert) { 25 | assert.true(false, 'this test should not run'); 26 | }); 27 | -------------------------------------------------------------------------------- /src/core/qunit-wrapper-nodejs-module.js: -------------------------------------------------------------------------------- 1 | // In a single Node.js process, if different parts or dependencies 2 | // of a project mix ESM and CJS, avoid a split-brain state by making 3 | // sure both import and re-use the same instance via this wrapper. 4 | // 5 | // Node.js 12+ can import a CommonJS file from ESM. 6 | import QUnit from '../qunit.js'; 7 | 8 | export const { 9 | assert, 10 | begin, 11 | config, 12 | diff, 13 | done, 14 | dump, 15 | equiv, 16 | hooks, 17 | is, 18 | isLocal, 19 | log, 20 | module, 21 | moduleDone, 22 | moduleStart, 23 | objectType, 24 | on, 25 | only, 26 | onUncaughtException, 27 | pushFailure, 28 | reporters, 29 | skip, 30 | stack, 31 | start, 32 | test, 33 | testDone, 34 | testStart, 35 | todo, 36 | urlParams, 37 | version 38 | } = QUnit; 39 | 40 | export { QUnit }; 41 | 42 | export default QUnit; 43 | -------------------------------------------------------------------------------- /test/cli/fixtures/assert-failure.js: -------------------------------------------------------------------------------- 1 | // For passing tests, see /test/main/assert.js 2 | // 3 | // TODO: After we migrate running of tests in browsers to use TAP, 4 | // merge these two files and verify them by TAP output instead of 5 | // by boolean passing (akin to what we do with Node.js already). 6 | 7 | QUnit.module('assert', function () { 8 | QUnit.test('true [failure]', function (assert) { 9 | assert.true(false); 10 | }); 11 | 12 | QUnit.test('false [failure]', function (assert) { 13 | assert.false(true); 14 | }); 15 | 16 | QUnit.test('closeTo [failure]', function (assert) { 17 | assert.closeTo(1, 2, 0); 18 | assert.closeTo(1, 2, 1); 19 | assert.closeTo(2, 7, 1); 20 | 21 | assert.closeTo(7, 7.3, 0.1); 22 | assert.closeTo(7, 7.3, 0.2); 23 | assert.closeTo(2011, 2013, 1); 24 | 25 | assert.closeTo(20.7, 20.1, 0.1); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /docs/_posts/2015-09-01-qunit-1-19-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.19.0 Released: ES6 Map and Set" 4 | author: leobalter 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: Add support for ES6 Map and Set to equiv for `assert.deepEqual()`. (Toh Chee Chuan) [#833](https://github.com/qunitjs/qunit/issues/833) 12 | * Core: New `QUnit.stack()` method. [#801](https://github.com/qunitjs/qunit/pull/801) 13 | * Core: Release module hooks to avoid memory leaks. (Stefan Penner) [#841](https://github.com/qunitjs/qunit/issues/841) 14 | * Dump: Escape backslash when quoting strings. 15 | * HTML Reporter: Avoid readyState issue with PhantomJS. 16 | * HTML Reporter: HTML reporter enhancements for negative asserts. 17 | * HTML Reporter: Show diff only when it helps. 18 | 19 | ## See also 20 | 21 | * [Git tag: 1.19.0](https://github.com/qunitjs/qunit/releases/tag/1.19.0) 22 | -------------------------------------------------------------------------------- /docs/_posts/2011-11-24-qunit-1-2-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.2.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | Support in `deepEqual` for comparing null objects via object literals, and various bug fixes. 10 | 11 | ## Changelog 12 | 13 | * Assert: Allow [`deepEqual`](https://qunitjs.com/api/assert/deepEqual/) to test objects with null prototype against object literals. (Domenic Denicola) [#170](https://github.com/qunitjs/qunit/pull/170) 14 | * Core: Fix IE8 "Member not found" error. (Jimmy Mabey) [#154](https://github.com/qunitjs/qunit/issues/154) 15 | * Core: Fix internal `start()` call to use `QUnit.start()`, since global is not exported in CommonJS runtimes, such as Node.js. (Antoine Musso) [#168](https://github.com/qunitjs/qunit/pull/168) 16 | 17 | ## See also 18 | 19 | * [Git tag: 1.2.0](https://github.com/qunitjs/qunit/releases/tag/1.2.0) 20 | 21 | -------------------------------------------------------------------------------- /test/cli/fixtures/callbacks-rejected.js: -------------------------------------------------------------------------------- 1 | let caught = []; 2 | 3 | QUnit.on('error', function (e) { 4 | caught.push(e.message); 5 | }); 6 | 7 | QUnit.begin(function () { 8 | return Promise.reject(new Error('begin')); 9 | }); 10 | 11 | QUnit.moduleStart(function () { 12 | return Promise.reject(new Error('moduleStart')); 13 | }); 14 | 15 | QUnit.testStart(function () { 16 | return Promise.reject(new Error('testStart')); 17 | }); 18 | 19 | QUnit.done(function () { 20 | setTimeout(function () { 21 | console.log('Caught errors from ' + caught.join(', ')); 22 | }, 100); 23 | }); 24 | 25 | QUnit.done(function () { 26 | return Promise.reject(new Error('done')); 27 | }); 28 | 29 | QUnit.test('one', function (assert) { 30 | assert.ok(true); 31 | }); 32 | 33 | QUnit.module('example', function () { 34 | QUnit.test('two', function (assert) { 35 | assert.ok(true); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /docs/_posts/2015-04-03-qunit-1-18-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.18.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: New `assert.notOk()` for asserting falsy values. [#745](https://github.com/qunitjs/qunit/pull/745) 12 | * Core: Expose Dump `maxDepth` property. 13 | * Core: Expose QUnit version as `QUnit.version` property. 14 | * Dump: Fix .name/.property doublettes. 15 | * HTML Reporter: New diff using Google's Diff-Patch-Match library. 16 | * HTML Reporter: Make it more obvious why diff is suppressed. 17 | * HTML Reporter: Change display text for bad tests. 18 | * HTML Reporter: Fix checkbox and select handling in IE <9. 19 | * HTML Reporter: Fix test filter without any module. 20 | * HTML Reporter: Retain failed tests numbers. 21 | 22 | ## See also 23 | 24 | * [Git tag: 1.18.0](https://github.com/qunitjs/qunit/releases/tag/1.18.0) 25 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-test-throw.tap.txt: -------------------------------------------------------------------------------- 1 | # command: ["qunit", "async-test-throw.js"] 2 | 3 | TAP version 13 4 | not ok 1 throw early 5 | --- 6 | message: "Promise rejected during \"throw early\": boo" 7 | severity: failed 8 | stack: | 9 | Error: boo 10 | at /qunit/test/cli/fixtures/async-test-throw.js:2:9 11 | ... 12 | not ok 2 throw late 13 | --- 14 | message: "Promise rejected during \"throw late\": boo" 15 | severity: failed 16 | stack: | 17 | Error: boo 18 | at /qunit/test/cli/fixtures/async-test-throw.js:8:9 19 | ... 20 | not ok 3 test with bad thenable 21 | --- 22 | message: "Promise rejected during \"test with bad thenable\": boo" 23 | severity: failed 24 | stack: | 25 | Error: boo 26 | at /qunit/test/cli/fixtures/async-test-throw.js:16:13 27 | ... 28 | 1..3 29 | # pass 0 30 | # skip 0 31 | # todo 0 32 | # fail 3 33 | 34 | # exit code: 1 35 | -------------------------------------------------------------------------------- /docs/_posts/2014-01-04-qunit-1-13-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.13.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * All: The Grand QUnit Split of 2013. (Timo Tijhof) 12 | * Assert: Remove `raises()`, deprecated in 2012. 13 | * Core: Add runtime property to testDone, deprecate duration. 14 | * Core: Only export to the variable that we check for. 15 | * Core: Properly check for existence of document. 16 | * Core: Remove triggerEvent, which isn't used or documented anywhere. 17 | * Core: Silence addEvent in non-browser env. 18 | * HTML Reporter: Use `id` function for selection elements in two places that were not using it. [#463](https://github.com/qunitjs/qunit/issues/463) 19 | * Release: Add bower.json. [#461](https://github.com/qunitjs/qunit/issues/461) 20 | 21 | ## See also 22 | 23 | * [Git tag: 1.13.0](https://github.com/qunitjs/qunit/releases/tag/1.13.0) 24 | -------------------------------------------------------------------------------- /docs/_posts/2015-01-19-qunit-1-17-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.17.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | This release fixes a few regressions in the HTML Reporter, includes a new UI element (filter tests), and even better CommonJS support. 10 | 11 | ## Changelog 12 | 13 | * Core: Support Node.js export parity with CommonJS. (James M. Greene) [#709](https://github.com/qunitjs/qunit/pull/709) 14 | * HTML Reporter: Add the filter field. (Leo Balter) [#651](https://github.com/qunitjs/qunit/issues/651) 15 | * HTML Reporter: Don't hide skipped tests. 16 | * HTML Reporter: Fix regression for old markup. 17 | * HTML Reporter: Prevent XSS attacks. 18 | * HTML Reporter: QUnit.url is now a private function in the HTML Reporter. 19 | * HTML Reporter: Url params can be set by code. 20 | 21 | ## See also 22 | 23 | * [Git tag: 1.17.0](https://github.com/qunitjs/qunit/releases/tag/1.17.0) 24 | -------------------------------------------------------------------------------- /test/cli/fixtures/inception.js: -------------------------------------------------------------------------------- 1 | const outerQUnit = globalThis.QUnit; 2 | delete globalThis.QUnit; 3 | const myQUnit = require('../../../src/cli/require-qunit')(); 4 | globalThis.QUnit = outerQUnit; 5 | 6 | const data = []; 7 | myQUnit.on('runStart', function () { 8 | data.push('runStart'); 9 | }); 10 | myQUnit.on('testEnd', function () { 11 | data.push('testEnd'); 12 | }); 13 | myQUnit.on('runEnd', function () { 14 | data.push('runEnd'); 15 | }); 16 | 17 | myQUnit.module('example', function () { 18 | myQUnit.test('a', function (assert) { 19 | assert.true(true, 'message'); 20 | }); 21 | }); 22 | 23 | const myQunitRun = new Promise(resolve => { 24 | myQUnit.on('runEnd', resolve); 25 | }); 26 | 27 | myQUnit.start(); 28 | 29 | QUnit.test('inception', async function (assert) { 30 | await myQunitRun; 31 | 32 | assert.deepEqual(data, [ 33 | 'runStart', 34 | 'testEnd', 35 | 'runEnd' 36 | ]); 37 | }); 38 | -------------------------------------------------------------------------------- /docs/_posts/2012-04-04-qunit-1-5-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.5.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Addons/JUnitLogger: Add `results` data to `QUnit.jUnitReport` callback argument. The function accepts one argument shaped as `{ xml: ' 15 | 16 | type 17 | `boolean` 18 | 19 | 20 | default 21 | `true` 22 | 23 | 24 | 25 | By default, QUnit updates `document.title` to insert a checkmark or cross symbol to indicate whether the test run passed or failed. This helps quickly spot from the tab bar whether a run passed, without opening it. 26 | 27 | If you're integration-testing code that makes changes to `document.title`, or otherwise conflicts with this feature, you can disable it. 28 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error-promise.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module() with promise return value 2 | # command: ["qunit","async-module-error-promise.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: |+ 8 | Error: Failed to load file async-module-error-promise.js 9 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 10 | severity: failed 11 | stack: | 12 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 13 | at /qunit/test/cli/fixtures/async-module-error-promise.js:1:7 14 | at internal 15 | ... 16 | Bail out! Error: Failed to load file async-module-error-promise.js 17 | ok 2 module manually returning a promise > has a test 18 | 1..2 19 | # pass 1 20 | # skip 0 21 | # todo 0 22 | # fail 1 23 | 24 | # exit code: 1 25 | -------------------------------------------------------------------------------- /demos/nyc/README.md: -------------------------------------------------------------------------------- 1 | # QUnit ♥️ Istanbul 2 | 3 | See also . 4 | 5 | ```bash 6 | npm test 7 | ``` 8 | 9 | ``` 10 | TAP version 13 11 | ok 1 add > two numbers 12 | 1..1 13 | # pass 1 14 | # skip 0 15 | # todo 0 16 | # fail 0 17 | --------------|---------|----------|---------|---------|------------------- 18 | File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 19 | --------------|---------|----------|---------|---------|------------------- 20 | All files | 85.71 | 100 | 50 | 85.71 | 21 | nyc | 100 | 100 | 100 | 100 | 22 | index.js | 100 | 100 | 100 | 100 | 23 | nyc/src | 75 | 100 | 50 | 75 | 24 | add.js | 100 | 100 | 100 | 100 | 25 | subtract.js | 50 | 100 | 0 | 50 | 2 26 | --------------|---------|----------|---------|---------|------------------- 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/_posts/2017-04-09-whats-new-in-qunit-emberconf.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: What's New in QUnit - EmberConf 2017" 4 | author: trentmwillis 5 | tags: 6 | - link 7 | --- 8 | 9 | _What's New in QUnit_ by Trent Willis at EmberConf 2017. 10 | 11 | 12 | 13 | * [Watch on YouTube](https://www.youtube.com/watch?v=8SzNe0gy_mY) 14 | * [Confreaks TV - EmberConf 2017](https://web.archive.org/web/20201001071317/https://confreaks.tv/videos/emberconf2017-minitalk-what-s-new-in-qunit) (archived) 15 | 16 | ------- 17 | 18 | _Originally published on [Twitter](https://twitter.com/qunitjs/status/851070473370836992)._ 19 | -------------------------------------------------------------------------------- /test/cli/fixtures/async-module-error-thenable.tap.txt: -------------------------------------------------------------------------------- 1 | # name: module() with promise return value 2 | # command: ["qunit","async-module-error-thenable.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: |+ 8 | Error: Failed to load file async-module-error-thenable.js 9 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 10 | severity: failed 11 | stack: | 12 | TypeError: QUnit.module() callback must not be async. For async module setup, use hooks. https://qunitjs.com/api/QUnit/module/#hooks 13 | at /qunit/test/cli/fixtures/async-module-error-thenable.js:1:7 14 | at internal 15 | ... 16 | Bail out! Error: Failed to load file async-module-error-thenable.js 17 | ok 2 module manually returning a thenable > has a test 18 | 1..2 19 | # pass 1 20 | # skip 0 21 | # todo 0 22 | # fail 1 23 | 24 | # exit code: 1 25 | -------------------------------------------------------------------------------- /test/urlparams-moduleId.js: -------------------------------------------------------------------------------- 1 | /* eslint-env browser */ 2 | if (!location.search) { 3 | location.replace('?moduleId=4dea3fbe&moduleId=9bf7d15c'); 4 | } 5 | 6 | QUnit.test('global test', function (assert) { 7 | assert.true(false); 8 | }); 9 | 10 | QUnit.module('module A scoped', function () { 11 | QUnit.test('test A1', function (assert) { 12 | assert.true(false); 13 | }); 14 | 15 | QUnit.module('module B nested', function () { 16 | QUnit.test('test B1', function (assert) { 17 | assert.true(true, 'run module B'); 18 | }); 19 | }); 20 | }); 21 | 22 | QUnit.module('module D flat'); 23 | QUnit.test('test D1', function (assert) { 24 | assert.true(false); 25 | }); 26 | 27 | QUnit.module('module E flat'); 28 | QUnit.test('test E1', function (assert) { 29 | assert.true(true, 'run module E'); 30 | assert.deepEqual( 31 | QUnit.config.moduleId, 32 | ['4dea3fbe', '9bf7d15c'], 33 | 'parsed config' 34 | ); 35 | }); 36 | -------------------------------------------------------------------------------- /docs/_posts/2012-07-11-qunit-1-9-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 1.9.0 Released" 4 | author: jzaefferer 5 | tags: 6 | - release 7 | --- 8 | 9 | ## Changelog 10 | 11 | * Assert: Rename `assert.raises()` to `assert.throws()`, keeping an alias for compat. [#267](https://github.com/qunitjs/qunit/issues/267) 12 | * Core: Make the module filter case-insensitive. [#252](https://github.com/qunitjs/qunit/issues/252) 13 | * HTML Reporter: Link should ignore "testNumber" and "module". [#270](https://github.com/qunitjs/qunit/issues/270) 14 | * HTML Reporter: Move checkboxes into toolbar and give them labels and tooltip descriptions. [#274](https://github.com/qunitjs/qunit/issues/274) 15 | * HTML Reporter: Remove use of shadows and change border radius to 5px for pass/error. 16 | * Release: Start publishing to npm under the `qunitjs` package name. 17 | 18 | ## See also 19 | 20 | * [Git tag: 1.9.0](https://github.com/qunitjs/qunit/releases/tag/1.9.0) 21 | -------------------------------------------------------------------------------- /.github/workflows/typesense.yaml: -------------------------------------------------------------------------------- 1 | name: typesense 2 | on: 3 | # Once a day at 11:30 UTC 4 | schedule: 5 | - cron: '30 11 * * *' 6 | # Or after a deployment 7 | push: 8 | branches: 9 | - main 10 | # Or manually 11 | workflow_dispatch: 12 | 13 | jobs: 14 | typesense: 15 | name: Update Typesense 16 | if: ${{ github.repository_owner == 'qunitjs' }} # skip on forks 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v4 20 | - name: Docsearch Scraper 21 | shell: bash 22 | run: | 23 | docker run \ 24 | -e TYPESENSE_API_KEY=${{ secrets.TYPESENSE_ADMIN_KEY }} \ 25 | -e TYPESENSE_HOST="${{ secrets.TYPESENSE_HOST }}" \ 26 | -e TYPESENSE_PORT="443" \ 27 | -e TYPESENSE_PROTOCOL="https" \ 28 | -e CONFIG="$(cat docsearch.config.json | jq -r tostring)" \ 29 | typesense/docsearch-scraper:0.9.1 30 | -------------------------------------------------------------------------------- /docs/_data/sitenav.yml: -------------------------------------------------------------------------------- 1 | - name: Guides 2 | href: /guides/ 3 | sub: 4 | - name: Getting Started 5 | href: /intro/ 6 | - name: Download 7 | href: /intro/#download 8 | - name: Browser Runner 9 | href: /browser/ 10 | - name: Command-line Interface 11 | href: /cli/ 12 | - name: Compatibility 13 | href: /intro/#compatibility 14 | - name: Test lifecycle 15 | href: /lifecycle/ 16 | - name: QUnit 2.0 Upgrade Guide 17 | href: /upgrade-guide-2.x/ 18 | - name: Documentation 19 | href: /api/ 20 | - name: Blog 21 | href: /blog/ 22 | - name: Community 23 | href: /about/ 24 | sub: 25 | - name: Support & Chat 26 | href: /intro/#support 27 | - name: Plugins 28 | href: /plugins/ 29 | - name: Who's using QUnit? 30 | href: /projects/ 31 | - name: About QUnit 32 | href: /about/ 33 | - name: Badge 34 | href: /badge/ 35 | - name: Brand Guidelines 36 | href: /brand/ 37 | -------------------------------------------------------------------------------- /docs/api/config/hidepassed.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.hidepassed 4 | excerpt: Hide results of passed tests (HTML Reporter). 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/hidepassed/" 9 | version_added: "1.0.0" 10 | --- 11 | 12 | In the HTML Reporter, hide results of passed tests. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`boolean`
default`false`
24 | 25 |

26 | 27 | This option can also be controlled via the [HTML Reporter](../../browser.md). 28 | 29 |

30 | 31 | By default, the HTML Reporter will list both passing and failing tests. Passing tests are by default collapsed to display only their name. Enable `hidepassed` to hide passing tests completely, and show only failing tests in the list. 32 | 33 | ## See also 34 | 35 | * [QUnit.config.collapse](./collapse.md) 36 | -------------------------------------------------------------------------------- /.eslintrc.base.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | 3 | // This JS file exists to reset 'env' and 'globals', 4 | // which ESLint doesn't have a built-in way to do otherwise. 5 | // Because of this, we have to bypass semistandard. 6 | const standard = require('eslint-config-standard'); 7 | 8 | const config = Object.assign(standard, { 9 | env: {}, 10 | globals: {}, 11 | rules: Object.assign(standard.rules, { 12 | // semistandard 13 | semi: ['error', 'always'], 14 | 'no-extra-semi': 'error', 15 | // disablements 16 | 'n/no-callback-literal': 'off', 17 | 'no-lone-blocks': 'off', 18 | 'object-shorthand': 'off', 19 | 'prefer-const': 'off', 20 | 'prefer-promise-reject-errors': 'off', 21 | // extra 22 | 'operator-linebreak': ['error', 'before', { overrides: { '=': 'after', '+=': 'after' } }], 23 | eqeqeq: ['error'], 24 | 'no-unused-vars': ['error', { args: 'all', argsIgnorePattern: '^_' }] 25 | }) 26 | }); 27 | 28 | module.exports = config; 29 | -------------------------------------------------------------------------------- /test/webWorker-worker.js: -------------------------------------------------------------------------------- 1 | // This worker script gets run via test/webWorker.html 2 | 3 | /* eslint-env worker */ 4 | 5 | importScripts( 6 | '../qunit/qunit.js', 7 | 8 | // Sync with test/index.html 9 | 'main/assert.js', 10 | 'main/assert-es6.js', 11 | 'main/assert-step.js', 12 | 'main/assert-timeout.js', 13 | 'main/async.js', 14 | 'main/browser-runner.js', 15 | 'main/callbacks.js', 16 | 'main/deepEqual.js', 17 | 'main/diff.js', 18 | 'main/dump.js', 19 | 'main/each.js', 20 | 'main/events.js', 21 | 'main/HtmlReporter.js', 22 | 'main/modules.js', 23 | 'main/modules-es2018.js', 24 | // TODO: 'main/modules-esm.mjs', 25 | 'main/legacy.js', 26 | 'main/onUncaughtException.js', 27 | 'main/promise.js', 28 | 'main/setTimeout.js', 29 | 'main/stacktrace.js', 30 | 'main/TapReporter.js', 31 | 'main/test.js', 32 | 'main/utilities.js' 33 | ); 34 | 35 | QUnit.on('runEnd', function (data) { 36 | postMessage(data); 37 | }); 38 | 39 | QUnit.start(); 40 | -------------------------------------------------------------------------------- /demos/testem.js: -------------------------------------------------------------------------------- 1 | const cp = require('child_process'); 2 | const path = require('path'); 3 | const DIR = path.join(__dirname, 'testem'); 4 | 5 | function normalize (str) { 6 | return str 7 | .trim() 8 | .replace(/(Firefox) [\d.]+/g, '$1') 9 | .replace(/(\d+ ms)/g, '0 ms'); 10 | } 11 | 12 | // Fast re-runs 13 | process.env.npm_config_prefer_offline = 'true'; 14 | process.env.npm_config_update_notifier = 'false'; 15 | process.env.npm_config_audit = 'false'; 16 | 17 | QUnit.module('testem', { 18 | before: () => { 19 | cp.execSync('npm install', { cwd: DIR, encoding: 'utf8' }); 20 | } 21 | }); 22 | 23 | QUnit.test('passing test', assert => { 24 | const ret = cp.execSync('npm run -s test', { cwd: DIR, encoding: 'utf8' }); 25 | assert.strictEqual( 26 | normalize(ret), 27 | ` 28 | ok 1 Firefox - [0 ms] - add: two numbers 29 | 30 | 1..1 31 | # tests 1 32 | # pass 1 33 | # skip 0 34 | # todo 0 35 | # fail 0 36 | 37 | # ok 38 | `.trim() 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /test/cli/fixtures/unhandled-rejection.tap.txt: -------------------------------------------------------------------------------- 1 | # name: unhandled rejection 2 | # command: ["qunit","unhandled-rejection.js"] 3 | 4 | TAP version 13 5 | not ok 1 global failure 6 | --- 7 | message: "Error: outside of a test context" 8 | severity: failed 9 | stack: | 10 | Error: outside of a test context 11 | at /qunit/test/cli/fixtures/unhandled-rejection.js:17:18 12 | at qunit.js 13 | at /qunit/test/cli/fixtures/unhandled-rejection.js:3:7 14 | at internal 15 | ... 16 | Bail out! Error: outside of a test context 17 | not ok 2 Unhandled Rejections > test passes just fine, but has a rejected promise 18 | --- 19 | message: "global failure: Error: Error thrown in non-returned promise!" 20 | severity: failed 21 | stack: | 22 | Error: Error thrown in non-returned promise! 23 | at /qunit/test/cli/fixtures/unhandled-rejection.js:10:13 24 | ... 25 | 1..2 26 | # pass 0 27 | # skip 0 28 | # todo 0 29 | # fail 2 30 | 31 | # exit code: 1 32 | -------------------------------------------------------------------------------- /docs/_posts/2023-09-23-qunit-2-20-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.20.0 Released: Improve diagnostics" 4 | author: krinkle 5 | tags: 6 | - release 7 | --- 8 | 9 | Add type check to `assert.async()` parameter, add `QUnit.reporters.perf`, and improve performance. 10 | 11 | Welcome Zixin and Hareesh as first-time QUnit contributions! 12 | 13 | ## Changelog 14 | 15 | ### Added 16 | 17 | * Core: Add `QUnit.reporters.perf`. (Timo Tijhof) [#1714](https://github.com/qunitjs/qunit/pull/1714) 18 | 19 | ### Changed 20 | 21 | * Assert: Add type check for `assert.async()` parameter. (Zixin Yin) [#1721](https://github.com/qunitjs/qunit/issues/1721) 22 | * HTML Reporter: Remove units for 0 values in qunit.css. (Hareesh) [#1715](https://github.com/qunitjs/qunit/pull/1715) 23 | 24 | ### Fixed 25 | 26 | * Core: Faster `inArray` by using Array.prototype.includes when possible. (Izel Nakri) 27 | 28 | ## See also 29 | 30 | * [Git tag: 2.20.0](https://github.com/qunitjs/qunit/releases/tag/2.20.0) 31 | -------------------------------------------------------------------------------- /docs/_posts/2018-10-10-qunit-2-7-0.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.7.0 Released: HTML Reporter Performance" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | Add Performance Timeline support, and improve HTML Reporter performance. 10 | 11 | ## Changelog 12 | 13 | ### Added 14 | 15 | * HTML Reporter: Add "User Timings" for each test to the browser's Performance Timeline. (Tobias Bieniek) [#1296](https://github.com/qunitjs/qunit/pull/1296) 16 | 17 | ### Fixed 18 | 19 | * CLI: Remove need for `fsevents` extension by upgrading the `sane` package. (Stefan Penner) [#1314](https://github.com/qunitjs/qunit/pull/1314) 20 | * HTML Reporter: Fix XHTML output issue. (Shlomi Fish) [#1317](https://github.com/qunitjs/qunit/pull/1317) 21 | * HTML Reporter: Faster "hidepassed" mode by removing elements from the DOM. (Gabriel Csapo) [#1311](https://github.com/qunitjs/qunit/pull/1311) 22 | 23 | ## See also 24 | 25 | * [Git tag: 2.7.0](https://github.com/qunitjs/qunit/releases/tag/2.7.0) 26 | -------------------------------------------------------------------------------- /docs/_posts/2015-01-12-sitepoint.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "Link: QUnit Tutorials - SitePoint" 4 | author: jzaefferer 5 | tags: 6 | - link 7 | --- 8 | 9 | Aurelio De Rosa wrote [What’s New in QUnit 1.16](https://web.archive.org/web/20150206130605/http://sitepoint.com/whats-new-qunit-1-16/) for the SitePoint Blog: 10 | 11 | > In December, version 1.16 of [QUnit] was released with some important changes. […] 12 | > 13 | > Updating your tests to version 1.16 now will help you in the process of the migration to version 2.0. QUnit 1.16 introduces several new methods that will become the default in the next milestone, […] 14 | 15 | ## See also 16 | 17 | * [Getting Started with QUnit - SitePoint](https://www.sitepoint.com/getting-started-qunit/) 18 | * [How to Test Asynchronous Code with QUnit - SitePoint](https://www.sitepoint.com/test-asynchronous-code-qunit/) 19 | * [QUnit Advanced Concepts: Modules and Configuration - SitePoint](https://www.sitepoint.com/qunit-advanced-concepts-modules-configuration/) 20 | -------------------------------------------------------------------------------- /docs/_posts/2019-10-08-qunit-2-9-3.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.9.3 Released: Faster CLI startup" 4 | author: trentmwillis 5 | tags: 6 | - release 7 | --- 8 | 9 | Contains a bunch of small fixes and documentation updates. Thanks to our contributors! 10 | 11 | ## Changelog 12 | 13 | ### Added 14 | 15 | * HTML Reporter: Display progress and runtime while test suite is executing. (Stefan Penner) [#1398](https://github.com/qunitjs/qunit/pull/1398) 16 | 17 | ### Fixed 18 | 19 | * CLI: Ignore folders mentioned in the gitignore to improve performance. (SparshithNRai) [#1384](https://github.com/qunitjs/qunit/pull/1384) 20 | * Core: Defer getting the stack trace to improve performance. (Adam Byrne) [#1401](https://github.com/qunitjs/qunit/pull/1401) 21 | * Core: Let `assert.timeout()` replace the timeout if `config.timeout` was already set. (Stephen Yeung) [#1400](https://github.com/qunitjs/qunit/pull/1400) 22 | 23 | ## See also 24 | 25 | * [Git tag: 2.9.3](https://github.com/qunitjs/qunit/releases/tag/2.9.3) 26 | -------------------------------------------------------------------------------- /test/cli/fixtures/each-array-labels.js: -------------------------------------------------------------------------------- 1 | // Automatic labels for test.each() array data where possible 2 | // https://github.com/qunitjs/qunit/issues/1733 3 | 4 | QUnit.test.each('array of arrays', [[1, 2, 3], [1, 1, 2]], function (assert, _data) { 5 | assert.true(true); 6 | }); 7 | 8 | QUnit.test.each('array of simple strings', [ 9 | 'foo', 10 | 'x'.repeat(40), 11 | '$', 12 | 'http://example.org', 13 | ' ', 14 | '' 15 | ], function (assert, _data) { 16 | assert.true(true); 17 | }); 18 | 19 | QUnit.test.each('array of mixed', [ 20 | undefined, 21 | null, 22 | false, 23 | true, 24 | 0, 25 | 1, 26 | -10, 27 | 10 / 3, 28 | 10e42, 29 | Infinity, 30 | NaN, 31 | [], 32 | {}, 33 | '999: example', 34 | 'simple string', 35 | '\b', 36 | '\n', 37 | 'y'.repeat(100) 38 | ], function (assert, _value) { 39 | assert.true(true); 40 | }); 41 | 42 | QUnit.test.each('keyed objects', { caseFoo: [1, 2, 3], caseBar: [1, 1, 2] }, function (assert, _data) { 43 | assert.true(true); 44 | }); 45 | -------------------------------------------------------------------------------- /test/cli/fixtures/test-if.js: -------------------------------------------------------------------------------- 1 | QUnit.test.if('skip me', false, function (assert) { 2 | assert.true(false); 3 | }); 4 | 5 | QUnit.test.if('keep me', true, function (assert) { 6 | assert.true(true); 7 | }); 8 | 9 | QUnit.test('regular', function (assert) { 10 | assert.true(true); 11 | }); 12 | 13 | QUnit.test.if.each('skip dataset', false, ['a', 'b'], function (assert, _data) { 14 | assert.true(false); 15 | }); 16 | 17 | QUnit.test.if.each('keep dataset', true, ['a', 'b'], function (assert, data) { 18 | assert.true(true); 19 | assert.equal(typeof data, 'string'); 20 | }); 21 | 22 | QUnit.module.if('skip group', false, function () { 23 | QUnit.test('skipper', function (assert) { 24 | assert.true(false); 25 | }); 26 | }); 27 | 28 | QUnit.module.if('keep group', true, function (hooks) { 29 | let list = []; 30 | hooks.beforeEach(function () { 31 | list.push('x'); 32 | }); 33 | QUnit.test('keeper', function (assert) { 34 | assert.true(true); 35 | assert.deepEqual(list, ['x']); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /docs/api/config/testId.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.testId 4 | excerpt: Select one or more tests to run, by their internal ID (HTML Reporter). 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/testId/" 9 | version_added: "1.16.0" 10 | --- 11 | 12 | Used by the HTML Reporter, select one or more tests to run by their internal ID. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`array` or `undefined`
default`undefined`
24 | 25 |

26 | 27 | This option can be controlled via the [HTML Reporter](../../browser.md) interface. 28 | 29 |

30 | 31 | This property allows QUnit to run specific tests by their internally hashed identifier. You can specify one or multiple tests to run. This option powers the "Rerun" button in the HTML Reporter. 32 | 33 | See also: 34 | * [QUnit.config.filter](./filter.md) 35 | * [QUnit.config.moduleId](./moduleId.md) 36 | -------------------------------------------------------------------------------- /docs/_posts/2025-01-25-qunit-2-24-1.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: "QUnit 2.24.1 Released: Bug fixes" 4 | author: krinkle 5 | excerpt: More TAP compliance fixes, and memory for "error" events. 6 | tags: 7 | - release 8 | --- 9 | 10 | ### Fixed 11 | 12 | * CLI: Fix TAP compliance for actual/expected indent and skip/todo colors. [b4d48fc710](https://github.com/qunitjs/qunit/commit/b4d48fc7107936b26d84b632b2c2782e368ea64c) 13 | * CLI: Fix TAP compliance for early errors (e.g. syntax error in test file). [01f7780bd8](https://github.com/qunitjs/qunit/commit/01f7780bd8df3c21667e3920e0a4187cdf986c35) 14 | * Core: Add memory to late [`error` event](https://qunitjs.com/api/callbacks/QUnit.on/#the-error-event) listeners, to improve reporting of early errors. [7c2f871ac3](https://github.com/qunitjs/qunit/commit/7c2f871ac339710845cee925207f5d6a62a8ad0e) 15 | 16 | ## See also 17 | 18 | * [Git tag: 2.24.1](https://github.com/qunitjs/qunit/releases/tag/2.24.1) 19 | * [QUnit 2.24.0 Released: Add memory to the "runEnd" event]({% post_url 2025-01-20-qunit-2-24-0 %}) 20 | -------------------------------------------------------------------------------- /docs/api/config/moduleId.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page-api 3 | title: QUnit.config.moduleId 4 | excerpt: Select one or more modules to run, by their internal ID (HTML Reporter). 5 | groups: 6 | - config 7 | redirect_from: 8 | - "/config/moduleId/" 9 | version_added: "1.23.0" 10 | --- 11 | 12 | Used by the HTML Reporter, this selects one or more modules by their internal ID to run exclusively. 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
type`array` or `undefined`
default`undefined`
24 | 25 |

26 | 27 | This option can be controlled via the [HTML Reporter](../../browser.md) interface. 28 | 29 |

30 | 31 | Specify modules by their internally hashed identifier for a given module. You can specify one or multiple modules to run. This option powers the multi-select dropdown menu in the HTML Reporter. 32 | 33 | See also: 34 | * [QUnit.config.module](./module.md) 35 | * [QUnit.config.testId](./testId.md) 36 | --------------------------------------------------------------------------------