diff --git a/.eslintrc.js b/.eslintrc.js index b4772aee..7320c47b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -59,7 +59,6 @@ module.exports = { }, env: { node: true, - mocha: true, }, rules: { 'ember/no-test-support-import': 'off', diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f2ffb87a..e1bd36d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,11 +44,8 @@ jobs: fail-fast: false matrix: ember-try-scenario: - - ember-default-with-mocha - embroider-safe - - embroider-safe-with-mocha - embroider-optimized - - embroider-optimized-with-mocha - ember-lts-4.8 - ember-lts-4.12 - ember-release diff --git a/README.md b/README.md index 3085c7bb..bbb6ed2e 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Code Climate](https://codeclimate.com/github/trentmwillis/ember-exam/badges/gpa.svg)](https://codeclimate.com/github/trentmwillis/ember-exam) [![Node Test Coverage](https://codeclimate.com/github/trentmwillis/ember-exam/badges/coverage.svg)](https://codeclimate.com/github/trentmwillis/ember-exam/coverage) -Ember Exam is an addon to allow you more control over how you run your tests when used in conjunction with [Ember QUnit](https://github.com/emberjs/ember-qunit) or [Ember Mocha](https://github.com/emberjs/ember-mocha). It provides the ability to randomize, split, parallelize, and load-balance your test suite by adding a more robust CLI command. +Ember Exam is an addon to allow you more control over how you run your tests when used in conjunction with [ember-qunit](https://github.com/emberjs/ember-qunit). It provides the ability to randomize, split, parallelize, and load-balance your test suite by adding a more robust CLI command. It started as a way to help reduce flaky tests and encourage healthy test driven development. It's like [Head & Shoulders](http://www.headandshoulders.com/) for your tests! @@ -70,13 +70,13 @@ $ ember exam --load-balance --parallel --server The idea is that you can replace `ember test` with `ember exam` and never look back. -To get the unique features of Ember Exam (described in-depth below), you will need to **replace** the use of `start()` from `Ember-Qunit` or `Ember-Mocha` in `test-helper.js` with `start()` from `ember-exam`: +To get the unique features of Ember Exam (described in-depth below), you will need to **replace** the use of `start()` from `ember-qunit` in `test-helper.js` with `start()` from `ember-exam`: ```js // test-helper.js import start from 'ember-exam/test-support/start'; -// Options passed to `start` will be passed-through to ember-qunit or ember-mocha +// Options passed to `start` will be passed-through to ember-qunit start(); ``` @@ -121,7 +121,7 @@ ember exam --split=2 --random Randomizing tests with seed: hwr74nkk55vzpvi ``` -_Note: You must be using QUnit version `1.23.0` or greater for this feature to work properly. This feature is not currently supported by Mocha._ +_Note: You must be using QUnit version `1.23.0` or greater for this feature to work properly. #### Randomization Iterator @@ -145,8 +145,6 @@ $ ember exam:iterate --options The `options` should be a string matching what you would use via the CLI. -_Note: This feature is not currently supported by Mocha._ - ### Generating Module Metadata File For Test Execution ```bash @@ -195,8 +193,6 @@ and it looks something like below: ] ``` -_Note: This feature is not currently supported by Mocha._ - ### Splitting @@ -216,7 +212,7 @@ The `partition` option allows you to specify which test group to run after using $ ember exam --split=4 --partition=1 --partition=2 ``` -_Note: Ember Exam splits tests by modifying the Ember-QUnit/Ember-Mocha's `TestLoader` to bucket each test file into a partition, where each partition has an even number of test files. This makes it possible to have unbalanced partitions. To run your tests with balanced partitions, consider using `--load-balance`. For more info, see [_Test Load Balancing_](#test-load-balancing). +_Note: Ember Exam splits tests by modifying the ember-qunit's `TestLoader` to bucket each test file into a partition, where each partition has an even number of test files. This makes it possible to have unbalanced partitions. To run your tests with balanced partitions, consider using `--load-balance`. For more info, see [_Test Load Balancing_](#test-load-balancing). #### Split Test Parallelization @@ -325,7 +321,6 @@ ok 3 Chrome 66.0 - Exam Partition 1 - browser Id 3 - some the other test 2. You must be using `ember-cli` version 3.2.0 or greater for load balancing and test failure reproduction features to work properly. 3. You must be using `ember-qunit` version 4.1.1 or greater for this feature to work properly. 4. You must be using `qunit` version 2.13.0 or greater for this feature to work properly. -5. This feature is not currently supported by Mocha. ##### Test Failure Reproduction @@ -380,7 +375,6 @@ $ ember exam --replay-execution=test-execution-000000.json 1. You must be using `ember-cli` version 3.2.0 or greater for load-balnce and test failure reproduction features to work properly. 2. You must be using `ember-qunit` version 4.1.1 or greater for this feature to work properly. 3. You must be using `qunit` version 2.8.0 or greater for this feature to work properly. -4. This feature is not currently supported by Mocha. #### Preserve Test Name diff --git a/addon-test-support/-private/ember-exam-mocha-test-loader.js b/addon-test-support/-private/ember-exam-mocha-test-loader.js deleted file mode 100644 index c4cf7033..00000000 --- a/addon-test-support/-private/ember-exam-mocha-test-loader.js +++ /dev/null @@ -1,87 +0,0 @@ -import getUrlParams from './get-url-params'; -import splitTestModules from './split-test-modules'; -import { filterTestModules } from './filter-test-modules'; -import { TestLoader } from 'ember-mocha/test-loader'; - -/** - * EmberExamMochaTestLoader extends ember-mocha/test-loader used by `ember test`, since it - * overrides moduleLoadFailure() to log a test failure when a module fails to load - * @class EmberExamMochaTestLoader - * @extends {TestLoader} - */ -export default class EmberExamMochaTestLoader extends TestLoader { - constructor(testem, urlParams) { - super(); - this._testModules = []; - this._testem = testem; - this._urlParams = urlParams || getUrlParams(); - } - - get urlParams() { - return this._urlParams; - } - - /** - * Ember-cli-test-loader instantiates a new TestLoader instance and calls loadModules. - * EmberExamMochaTestLoader does not support load() in favor of loadModules(). - * - * @method load - */ - static load() { - throw new Error("`EmberExamMochaTestLoader` doesn't support `load()`."); - } - - /** - * require() collects the full list of modules before requiring each module with - * super.require, instead of requiring and unseeing a module when each gets loaded. - * - * @method require - * @param {string} moduleName - */ - require(moduleName) { - this._testModules.push(moduleName); - } - - /** - * Make unsee a no-op to avoid any unwanted resets - * - * @method unsee - */ - unsee() {} - - /** - * Loads the test modules depending on the urlParam - * - * @method loadModules - */ - loadModules() { - const modulePath = this._urlParams.get('modulePath'); - const filePath = this._urlParams.get('filePath'); - let partitions = this._urlParams.get('partition'); - let split = parseInt(this._urlParams.get('split'), 10); - - split = isNaN(split) ? 1 : split; - - if (partitions === undefined) { - partitions = [1]; - } else if (!Array.isArray(partitions)) { - partitions = [partitions]; - } - - super.loadModules(); - - if (modulePath || filePath) { - this._testModules = filterTestModules( - this._testModules, - modulePath, - filePath, - ); - } - - this._testModules = splitTestModules(this._testModules, split, partitions); - this._testModules.forEach((moduleName) => { - super.require(moduleName); - super.unsee(moduleName); - }); - } -} diff --git a/addon-test-support/-private/ember-exam-qunit-test-loader.js b/addon-test-support/-private/ember-exam-test-loader.js similarity index 98% rename from addon-test-support/-private/ember-exam-qunit-test-loader.js rename to addon-test-support/-private/ember-exam-test-loader.js index 8a79282b..d12900ec 100644 --- a/addon-test-support/-private/ember-exam-qunit-test-loader.js +++ b/addon-test-support/-private/ember-exam-test-loader.js @@ -13,7 +13,7 @@ import QUnit from 'qunit'; * @class EmberExamQUnitTestLoader * @extends {TestLoader} */ -export default class EmberExamQUnitTestLoader extends TestLoader { +export default class EmberExamTestLoader extends TestLoader { constructor(testem, urlParams, qunit = QUnit) { super(); this._testModules = []; diff --git a/addon-test-support/-private/get-test-loader.js b/addon-test-support/-private/get-test-loader.js deleted file mode 100644 index b84cf58a..00000000 --- a/addon-test-support/-private/get-test-loader.js +++ /dev/null @@ -1,30 +0,0 @@ -import { - dependencySatisfies, - macroCondition, - importSync, -} from '@embroider/macros'; - -/** - * Returns ember-exam-qunit-test-loader or ember-exam-mocha-test-loader - * - * @export - * @function getTestLoader - * @return {Object} - */ -export default function getTestLoader() { - if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - const EmberExamQUnitTestLoader = importSync( - './ember-exam-qunit-test-loader', - ); - return EmberExamQUnitTestLoader['default']; - } else if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - const EmberExamMochaTestLoader = importSync( - './ember-exam-mocha-test-loader', - ); - return EmberExamMochaTestLoader['default']; - } - - throw new Error( - 'Unable to find a suitable test loader. You should ensure that one of `ember-qunit` or `ember-mocha` are added as dependencies.', - ); -} diff --git a/addon-test-support/load.js b/addon-test-support/load.js index 8c6238ed..878f3290 100644 --- a/addon-test-support/load.js +++ b/addon-test-support/load.js @@ -1,5 +1,5 @@ +import EmberExamTestLoader from './-private/ember-exam-test-loader'; import { patchTestemOutput } from './-private/patch-testem-output'; -import getTestLoader from './-private/get-test-loader'; let loaded = false; @@ -17,7 +17,7 @@ export default function loadEmberExam() { } loaded = true; - const EmberExamTestLoader = getTestLoader(); + const testLoader = new EmberExamTestLoader(window.Testem); if (window.Testem) { diff --git a/addon-test-support/start.js b/addon-test-support/start.js index 0f19040e..26e7076c 100644 --- a/addon-test-support/start.js +++ b/addon-test-support/start.js @@ -1,12 +1,8 @@ import loadEmberExam from 'ember-exam/test-support/load'; -import { - dependencySatisfies, - macroCondition, - importSync, -} from '@embroider/macros'; +import { start as qunitStart } from 'ember-qunit'; /** - * Equivalent to ember-qunit or ember-mocha's loadTest() except this does not create a new TestLoader instance + * Equivalent to ember-qunit's loadTest() except this does not create a new TestLoader instance * * @function loadTests * @param {*} testLoader @@ -23,7 +19,7 @@ function loadTests(testLoader) { /** * Ember-exam's own start function to set up EmberExamTestLoader, load tests and calls start() from - * ember-qunit or ember-mocha + * ember-qunit * * @function start * @param {*} qunitOptions @@ -34,15 +30,5 @@ export default function start(qunitOptions) { const testLoader = loadEmberExam(); loadTests(testLoader); - - let emberTestFramework; - if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - emberTestFramework = importSync('ember-qunit'); - } else if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - emberTestFramework = importSync('ember-mocha'); - } - - if (emberTestFramework.start) { - emberTestFramework.start(modifiedOptions); - } + qunitStart(modifiedOptions); } diff --git a/bin/install-test-framework.sh b/bin/install-test-framework.sh deleted file mode 100755 index b85338c4..00000000 --- a/bin/install-test-framework.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash -set -ev -if [ "${TEST_FRAMEWORK}" = "ember-mocha" ]; then - yarn remove ember-qunit 2>/dev/null && echo "n" | ember install ember-mocha || true -fi diff --git a/ember-cli-build.js b/ember-cli-build.js index 11ec4117..377725d5 100644 --- a/ember-cli-build.js +++ b/ember-cli-build.js @@ -10,13 +10,5 @@ module.exports = function (defaults) { }); const { maybeEmbroider } = require('@embroider/test-setup'); - return maybeEmbroider(app, { - packagerOptions: { - webpackConfig: { - externals: { - mocha: 'mocha', - }, - }, - }, - }); + return maybeEmbroider(app, {}); }; diff --git a/index.js b/index.js index f87de789..20314e5a 100644 --- a/index.js +++ b/index.js @@ -8,12 +8,4 @@ module.exports = { includedCommands() { return require('./lib/commands'); }, - - init() { - this._super.init.apply(this, arguments); - - this.options.autoImport = { - exclude: ['ember-mocha', 'mocha'], - }; - }, }; diff --git a/lib/commands/exam.js b/lib/commands/exam.js index e6d77923..19df253b 100644 --- a/lib/commands/exam.js +++ b/lib/commands/exam.js @@ -123,32 +123,10 @@ module.exports = TestCommand.extend({ */ _validateOptions(commandOptions) { const Validator = require('../utils/tests-options-validator'); - const validator = new Validator( - commandOptions, - this._getTestFramework(), - this.emberCliVersion, - ); + const validator = new Validator(commandOptions, this.emberCliVersion); return validator.validateCommands(); }, - /** - * Gets the name of the test framework being used by the project. - * - * @private - * @return {string} - */ - _getTestFramework() { - const pkg = this.project.pkg; - const dependencies = pkg.dependencies || {}; - const devDependencies = pkg.devDependencies || {}; - - if (dependencies['ember-mocha'] || devDependencies['ember-mocha']) { - return 'mocha'; - } else { - return 'qunit'; - } - }, - /** * Validates the command options and then runs the original test command. * diff --git a/lib/utils/tests-options-validator.js b/lib/utils/tests-options-validator.js index a8648c92..b4bdfffa 100644 --- a/lib/utils/tests-options-validator.js +++ b/lib/utils/tests-options-validator.js @@ -111,9 +111,8 @@ function validateElementsUnique(arr, typeOfValue) { * @class TestsOptionsValidator */ module.exports = class TestsOptionsValidator { - constructor(options, framework, emberCliVersion) { + constructor(options, emberCliVersion) { this.options = options; - this.framework = framework; this.emberCliVersion = emberCliVersion; } @@ -210,16 +209,7 @@ module.exports = class TestsOptionsValidator { * @return {boolean} */ validateRandom() { - const shouldRandomize = typeof this.options.random === 'string'; - - if (shouldRandomize && this.framework === 'mocha') { - // eslint-disable-next-line no-console - console.warn( - 'Mocha does not currently support randomizing test order, so tests will run in normal order. Please see https://github.com/mochajs/mocha/issues/902 for more info.', - ); - } - - return shouldRandomize; + return typeof this.options.random === 'string'; } /** diff --git a/node-tests/fixtures/test-helper-with-load.js b/node-tests/fixtures/test-helper-with-load.js index 66257ed8..2f4a0a4f 100644 --- a/node-tests/fixtures/test-helper-with-load.js +++ b/node-tests/fixtures/test-helper-with-load.js @@ -1,23 +1,10 @@ import { setResolver } from '@ember/test-helpers'; import resolver from './helpers/resolver'; import loadEmberExam from 'ember-exam/test-support/load'; - -const framework = require.has('ember-qunit') ? 'qunit' : 'mocha'; -const oppositeFramework = !require.has('ember-qunit') ? 'qunit' : 'mocha'; - -Object.keys(require.entries).forEach((entry) => { - if (entry.indexOf(oppositeFramework) !== -1) { - delete require.entries[entry]; - } -}); +import { start } from 'ember-qunit'; setResolver(resolver); loadEmberExam(); -// ember-qunit >= v3 support -if (framework === 'qunit') { - // Use string literal to prevent Babel to transpile this into ES6 import - // that would break when tests run with Mocha framework. - require(`ember-${framework}`).start(); -} +start(); diff --git a/node-tests/unit/commands/exam-test.js b/node-tests/unit/commands/exam-test.js index 58ae0030..ee7b4500 100644 --- a/node-tests/unit/commands/exam-test.js +++ b/node-tests/unit/commands/exam-test.js @@ -152,35 +152,4 @@ describe('ExamCommand', function () { }); }); }); - - describe('_getTestFramework', function () { - let command; - - function assertFramework(command, name) { - assert.strictEqual(command._getTestFramework(), name); - } - - beforeEach(function () { - command = createCommand(); - }); - - it('returns mocha if ember-mocha is a dependency', function () { - command.project.pkg.dependencies = { - 'ember-mocha': '*', - }; - assertFramework(command, 'mocha'); - }); - - it('returns mocha if ember-mocha is a dev-dependency', function () { - command.project.pkg.devDependencies = { - 'ember-mocha': '*', - }; - assertFramework(command, 'mocha'); - }); - - it('returns qunit if ember-mocha is not a dependency of any kind', function () { - command = createCommand(); - assertFramework(command, 'qunit'); - }); - }); }); diff --git a/node-tests/unit/utils/tests-options-validator-test.js b/node-tests/unit/utils/tests-options-validator-test.js index 733fe952..356923da 100644 --- a/node-tests/unit/utils/tests-options-validator-test.js +++ b/node-tests/unit/utils/tests-options-validator-test.js @@ -33,20 +33,12 @@ describe('TestOptionsValidator', function () { } function shouldThrow(cmd, options, message, emberCliVer = '3.7.0') { - const validator = new TestOptionsValidator( - options, - options.framework, - emberCliVer, - ); + const validator = new TestOptionsValidator(options, emberCliVer); assert.throws(() => validateCommand(validator, cmd), message); } function shouldEqual(cmd, options, value, emberCliVer = '3.7.0') { - const validator = new TestOptionsValidator( - options, - options.framework, - emberCliVer, - ); + const validator = new TestOptionsValidator(options, emberCliVer); assert.strictEqual(validateCommand(validator, cmd), value); } @@ -60,11 +52,7 @@ describe('TestOptionsValidator', function () { warnMessage = message; }; - const validator = new TestOptionsValidator( - options, - options.framework, - emberCliVer, - ); + const validator = new TestOptionsValidator(options, emberCliVer); assert.notEqual(validateCommand(validator, cmd), undefined); assert.strictEqual(warnCalled, 1); assert.strictEqual(warnMessage, value); @@ -151,14 +139,6 @@ describe('TestOptionsValidator', function () { it('should return false if `random` is not used', function () { shouldRandomizeEqual({}, false); }); - - it('should warn that randomization is not supported in mocha', function () { - shouldWarn( - 'Random', - { random: '', framework: 'mocha' }, - 'Mocha does not currently support randomizing test order, so tests will run in normal order. Please see https://github.com/mochajs/mocha/issues/902 for more info.', - ); - }); }); describe('shouldParallelize', function () { diff --git a/package.json b/package.json index 29dc3b76..d10c323c 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "test": "concurrently \"npm:lint\" \"npm:test:*\" --names \"lint,test:\"", "test:ember": "ember test", "test:ember-compatibility": "ember try:each", - "test:mocha": "TEST_FRAMEWORK=ember-mocha bin/install-test-framework.sh && ember test", "test:node": "nyc mocha 'node-tests/**/*-test.js'" }, "nyc": { @@ -40,7 +39,6 @@ }, "dependencies": { "@babel/core": "^7.23.6", - "@embroider/macros": "^1.13.4", "chalk": "^5.3.0", "cli-table3": "^0.6.0", "debug": "^4.2.0", @@ -92,7 +90,6 @@ "eslint-plugin-qunit": "8.0.1", "fixturify": "3.0.0", "loader.js": "4.7.0", - "lodash.mergewith": "4.6.2", "mocha": "10.2.0", "mocha-eslint": "7.0.0", "nyc": "15.1.0", @@ -107,22 +104,10 @@ "webpack": "5.89.0" }, "peerDependencies": { - "ember-mocha": "*", "ember-qunit": "*", "ember-source": ">= 4.0.0", "qunit": "*" }, - "peerDependenciesMeta": { - "ember-mocha": { - "optional": true - }, - "ember-qunit": { - "optional": true - }, - "qunit": { - "optional": true - } - }, "engines": { "node": ">= 18" }, diff --git a/tests/dummy/app/templates/docs/index.md b/tests/dummy/app/templates/docs/index.md index 3b109970..4e8cfc69 100644 --- a/tests/dummy/app/templates/docs/index.md +++ b/tests/dummy/app/templates/docs/index.md @@ -35,13 +35,13 @@ ember exam --load-balance --parallel --server --no-launch The idea is that you can replace `ember test` with `ember exam` and never look back. -To get the unique features of Ember Exam (described in-depth below), you will need to **replace** the use of `start()` from `Ember-Qunit` or `Ember-Mocha` in `test-helper.js` with `start()` from `ember-exam`: +To get the unique features of Ember Exam (described in-depth below), you will need to **replace** the use of `start()` from `ember-qunit` in `test-helper.js` with `start()` from `ember-exam`: ```js // test-helper.js import start from 'ember-exam/test-support/start'; -// start() triggers qunit or mocha start after instantiating either qunit or mocha test-loader instance and loading test modules. +// start() triggers qunit start after instantiating qunit test-loader instance and loading test modules. start(); ``` diff --git a/tests/dummy/app/templates/docs/load-balancing.md b/tests/dummy/app/templates/docs/load-balancing.md index e58fac1f..8d684ae7 100644 --- a/tests/dummy/app/templates/docs/load-balancing.md +++ b/tests/dummy/app/templates/docs/load-balancing.md @@ -40,7 +40,6 @@ ok 3 Chrome 66.0 - Exam Partition 1 - browser Id 3 - some the other test 2. You must be using `ember-cli` version 3.2.0 or greater for load balancing and test failure reproduction features to work properly. 3. You must be using `ember-qunit` version 4.1.1 or greater for this feature to work properly. 4. You must be using `qunit` version 2.13.0 or greater for this feature to work properly. -5. This feature is not currently supported by Mocha. ## Test Failure Reproduction @@ -95,4 +94,3 @@ ember exam --replay-execution=test-execution-000000.json 1. You must be using `ember-cli` version 3.2.0 or greater for load-balnce and test failure reproduction features to work properly. 2. You must be using `ember-qunit` version 4.1.1 or greater for this feature to work properly. 3. You must be using `qunit` version 2.8.0 or greater for this feature to work properly. -4. This feature is not currently supported by Mocha. diff --git a/tests/dummy/app/templates/docs/module-metadata.md b/tests/dummy/app/templates/docs/module-metadata.md index 1482bc6e..37283e13 100644 --- a/tests/dummy/app/templates/docs/module-metadata.md +++ b/tests/dummy/app/templates/docs/module-metadata.md @@ -46,4 +46,3 @@ and it looks something like below: ] ``` -_Note: This feature is not currently supported by Mocha._ diff --git a/tests/dummy/app/templates/docs/randomization-iterator.md b/tests/dummy/app/templates/docs/randomization-iterator.md index d65997bd..866f07ab 100644 --- a/tests/dummy/app/templates/docs/randomization-iterator.md +++ b/tests/dummy/app/templates/docs/randomization-iterator.md @@ -20,4 +20,3 @@ ember exam:iterate --options The `options` should be a string matching what you would use via the CLI. -_Note: This feature is not currently supported by Mocha._ diff --git a/tests/dummy/app/templates/docs/randomization.md b/tests/dummy/app/templates/docs/randomization.md index ab29a591..ffcc17e8 100644 --- a/tests/dummy/app/templates/docs/randomization.md +++ b/tests/dummy/app/templates/docs/randomization.md @@ -26,4 +26,4 @@ ember exam --split=2 --random Randomizing tests with seed: hwr74nkk55vzpvi ``` -_Note: You must be using QUnit version `1.23.0` or greater for this feature to work properly. This feature is not currently supported by Mocha._ +_Note: You must be using QUnit version `1.23.0` or greater for this feature to work properly. diff --git a/tests/dummy/app/templates/docs/splitting.md b/tests/dummy/app/templates/docs/splitting.md index 8962fc05..baac2896 100644 --- a/tests/dummy/app/templates/docs/splitting.md +++ b/tests/dummy/app/templates/docs/splitting.md @@ -16,4 +16,4 @@ The `partition` option allows you to specify which test group to run after using ember exam --split=4 --partition=1 --partition=2 ``` -_Note: Ember Exam splits tests by modifying the Ember-QUnit/Ember-Mocha's `TestLoader` to bucket each test file into a partition, where each partition has an even number of test files. This makes it possible to have unbalanced partitions. To run your tests with balanced partitions, consider using `--load-balance`. For more info, see [_Test Load Balancing_](#test-load-balancing). +_Note: Ember Exam splits tests by modifying the ember-qunit's `TestLoader` to bucket each test file into a partition, where each partition has an even number of test files. This makes it possible to have unbalanced partitions. To run your tests with balanced partitions, consider using `--load-balance`. For more info, see [_Test Load Balancing_](#test-load-balancing). diff --git a/tests/dummy/app/templates/index.hbs b/tests/dummy/app/templates/index.hbs index 8f6cb358..b02a43c5 100644 --- a/tests/dummy/app/templates/index.hbs +++ b/tests/dummy/app/templates/index.hbs @@ -15,9 +15,7 @@

Ember Exam is an addon to allow you more control over how you run your tests when used in conjunction with - Ember QUnit - or - Ember Mocha. + ember-qunit. It provides the ability to randomize, split, parallelize, and load-balance your test suite by adding a more robust CLI command.

diff --git a/tests/dummy/config/ember-try.js b/tests/dummy/config/ember-try.js index bf243155..45111629 100644 --- a/tests/dummy/config/ember-try.js +++ b/tests/dummy/config/ember-try.js @@ -2,23 +2,6 @@ const getChannelURL = require('ember-source-channel-url'); const { embroiderSafe, embroiderOptimized } = require('@embroider/test-setup'); -const mergeWith = require('lodash.mergewith'); - -function mochaScenario(scenario = {}) { - return mergeWith({}, scenario, { - npm: { - devDependencies: { - 'chai-dom': '*', - 'ember-cli-chai': '*', - 'ember-mocha': '*', - 'ember-qunit': null, - }, - peerDependencies: { - 'ember-qunit': null, - } - }, - }); -} const command = [ 'ember', @@ -78,21 +61,8 @@ module.exports = async function () { }, }, }, - mochaScenario({ - name: 'ember-default-with-mocha', - }), embroiderSafe(), - embroiderSafe( - mochaScenario({ - name: 'embroider-safe-with-mocha', - }), - ), embroiderOptimized(), - embroiderOptimized( - mochaScenario({ - name: 'embroider-optimized-with-mocha', - }), - ), ], }; }; diff --git a/tests/test-helper.js b/tests/test-helper.js index b698e2df..734d801c 100644 --- a/tests/test-helper.js +++ b/tests/test-helper.js @@ -1,21 +1,6 @@ -/* globals require */ - import { setResolver } from '@ember/test-helpers'; import resolver from './helpers/resolver'; import start from 'ember-exam/test-support/start'; -import { macroCondition, dependencySatisfies } from '@embroider/macros'; - -const oppositeFramework = macroCondition( - dependencySatisfies('ember-qunit', '*'), -) - ? 'mocha' - : 'qunit'; - -Object.keys(require.entries).forEach((entry) => { - if (entry.indexOf(oppositeFramework) !== -1) { - delete require.entries[entry]; - } -}); setResolver(resolver); start(); diff --git a/tests/unit/mocha/filter-test-modules-test.js b/tests/unit/mocha/filter-test-modules-test.js deleted file mode 100644 index e5c44398..00000000 --- a/tests/unit/mocha/filter-test-modules-test.js +++ /dev/null @@ -1,154 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; -import { - convertFilePathToModulePath, - filterTestModules, -} from 'ember-exam/test-support/-private/filter-test-modules'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it, beforeEach, afterEach } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Unit | Mocha | filter-test-modules', () => { - describe('convertFilePathToModulePath', () => { - it('should return an input string without file extension when the input contains file extension', () => { - expect( - convertFilePathToModulePath('/tests/integration/foo.js'), - ).to.equal('/tests/integration/foo'); - }); - - it(`should return an input string without file extension when the input doesn't contain file extension`, () => { - expect(convertFilePathToModulePath('/tests/integration/foo')).to.equal( - '/tests/integration/foo', - ); - }); - - it('should return an input string after `tests` when the input is a full test file path', () => { - expect( - convertFilePathToModulePath('dummy/tests/integration/foo.js'), - ).to.equal('/tests/integration/foo'); - }); - }); - - describe('modulePath | Mocha', () => { - let modules = []; - - beforeEach(() => { - modules = ['foo-test', 'bar-test']; - }); - - afterEach(() => { - modules = []; - }); - - it('should return a list of filtered tests', () => { - expect(filterTestModules(modules, 'foo')).to.deep.equal(['foo-test']); - }); - - it('should return an empty list when there is no match', () => { - expect(() => { - filterTestModules(modules, 'no-match'); - }).to.throw(/No tests matched with the filter:/); - }); - - it('should return a list of tests matched with a regular expression', () => { - expect(filterTestModules(modules, '/foo/')).to.deep.equal(['foo-test']); - }); - - it('should return a list of tests matched with a regular expression that excluses foo', () => { - expect(filterTestModules(modules, '!/foo/')).to.deep.equal([ - 'bar-test', - ]); - }); - - it('should return a list of tests matches with a list of string options', () => { - expect(filterTestModules(modules, 'foo, bar')).to.deep.equal([ - 'foo-test', - 'bar-test', - ]); - }); - - it('should return a list of unique tests matches when options are repeated', () => { - expect(filterTestModules(modules, 'foo, foo')).to.deep.equal([ - 'foo-test', - ]); - }); - }); - - describe('filePath | Mocha', () => { - let modules = []; - - beforeEach(() => { - modules = [ - 'dummy/tests/integration/foo-test', - 'dummy/tests/unit/foo-test', - 'dummy/tests/unit/bar-test', - ]; - }); - - afterEach(() => { - modules = []; - }); - - it('should return a test module matches with full test file path', () => { - expect( - filterTestModules(modules, null, 'app/tests/integration/foo-test.js'), - ).to.deep.equal(['dummy/tests/integration/foo-test']); - }); - - it('should return a test module matches with relative test file path', () => { - expect( - filterTestModules(modules, null, '/tests/unit/foo-test'), - ).to.deep.equal(['dummy/tests/unit/foo-test']); - }); - - it('should return a test module matched with test file path with wildcard', () => { - expect(filterTestModules(modules, null, '/unit/*')).to.deep.equal([ - 'dummy/tests/unit/foo-test', - 'dummy/tests/unit/bar-test', - ]); - }); - - it('should return a test module matched with test file path with wildcard', () => { - expect(filterTestModules(modules, null, '/tests/*/foo*')).to.deep.equal( - ['dummy/tests/integration/foo-test', 'dummy/tests/unit/foo-test'], - ); - }); - - it('should return a list of tests matched with a regular expression', () => { - expect(() => { - filterTestModules(modules, null, 'no-match'); - }).to.throw(/No tests matched with the filter:/); - }); - - it('should return a list of tests matches with a list of string options', () => { - expect( - filterTestModules( - modules, - null, - '/tests/integration/*, dummy/tests/unit/foo-test', - ), - ).to.deep.equal([ - 'dummy/tests/integration/foo-test', - 'dummy/tests/unit/foo-test', - ]); - }); - - it('should return a list of unique tests matches when options are repeated', () => { - expect( - filterTestModules( - modules, - null, - 'app/tests/unit/bar-test.js, /tests/unit/*', - ), - ).to.deep.equal([ - 'dummy/tests/unit/bar-test', - 'dummy/tests/unit/foo-test', - ]); - }); - }); - }); -} diff --git a/tests/unit/mocha/multiple-edge-cases-test.js b/tests/unit/mocha/multiple-edge-cases-test.js deleted file mode 100644 index 80391e76..00000000 --- a/tests/unit/mocha/multiple-edge-cases-test.js +++ /dev/null @@ -1,16 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Mocha | #3: Module With Multiple Edge Case Tests', function () { - it('#1 RegExp test', function () { - expect(/derp/.test('derp')).to.be.ok; - }); - }); -} diff --git a/tests/unit/mocha/multiple-ember-tests-test.js b/tests/unit/mocha/multiple-ember-tests-test.js deleted file mode 100644 index ce407ca0..00000000 --- a/tests/unit/mocha/multiple-ember-tests-test.js +++ /dev/null @@ -1,43 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it } = importSync('mocha'); - let { expect } = importSync('chai'); - let { setupTest } = importSync('ember-mocha'); - - describe('Mocha | #1: Module-For With Multiple Tests', function () { - setupTest(); - - it('#1', function () { - expect(true).to.be.ok; - }); - it('#2', function () { - expect(true).to.be.ok; - }); - it('#3', function () { - expect(true).to.be.ok; - }); - it('#4', function () { - expect(true).to.be.ok; - }); - it('#5', function () { - expect(true).to.be.ok; - }); - it('#6', function () { - expect(true).to.be.ok; - }); - it('#7', function () { - expect(true).to.be.ok; - }); - it('#8', function () { - expect(true).to.be.ok; - }); - it('#9', function () { - expect(true).to.be.ok; - }); - }); -} diff --git a/tests/unit/mocha/multiple-tests-test.js b/tests/unit/mocha/multiple-tests-test.js deleted file mode 100644 index 946f674d..00000000 --- a/tests/unit/mocha/multiple-tests-test.js +++ /dev/null @@ -1,40 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Mocha | #2: Module With Multiple Tests', function () { - it('#1', function () { - expect(true).to.be.ok; - }); - it('#2', function () { - expect(true).to.be.ok; - }); - it('#3', function () { - expect(true).to.be.ok; - }); - it('#4', function () { - expect(true).to.be.ok; - }); - it('#5', function () { - expect(true).to.be.ok; - }); - it('#6', function () { - expect(true).to.be.ok; - }); - it('#7', function () { - expect(true).to.be.ok; - }); - it('#8', function () { - expect(true).to.be.ok; - }); - it('#9', function () { - expect(true).to.be.ok; - }); - }); -} diff --git a/tests/unit/mocha/test-loader-test.js b/tests/unit/mocha/test-loader-test.js deleted file mode 100644 index a46788cf..00000000 --- a/tests/unit/mocha/test-loader-test.js +++ /dev/null @@ -1,190 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; -import EmberExamTestLoader from 'ember-exam/test-support/-private/ember-exam-mocha-test-loader'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it, beforeEach, afterEach } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Unit | Mocha | test-loader', function () { - beforeEach(function () { - this.originalRequire = window.require; - this.requiredModules = []; - window.require = (name) => { - this.requiredModules.push(name); - }; - - window.requirejs.entries = { - 'test-1-test': true, - 'test-2-test': true, - 'test-3-test': true, - 'test-4-test': true, - }; - this.originalURLParams = EmberExamTestLoader._urlParams; - }); - - afterEach(function () { - window.require = this.originalRequire; - }); - - it('loads all test modules by default', function () { - const testLoader = new EmberExamTestLoader(this.testem, new Map()); - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal([ - 'test-1-test', - 'test-2-test', - 'test-3-test', - 'test-4-test', - ]); - }); - - it('loads modules from a specified partition', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('partition', 3).set('split', 4), - ); - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal(['test-3-test']); - }); - - it('loads modules from multiple specified partitions', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('partition', [1, 3]).set('split', 4), - ); - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal([ - 'test-1-test', - 'test-3-test', - ]); - }); - - it('loads modules from the first partition by default', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 4), - ); - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal(['test-1-test']); - }); - - it('handles params as strings', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('partition', '3').set('split', '4'), - ); - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal(['test-3-test']); - }); - - it('throws an error if splitting less than one', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 0), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw(/You must specify a split greater than 0/); - }); - - it("throws an error if partition isn't a number", function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 2).set('partition', 'foo'), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw( - /You must specify numbers for partition \(you specified 'foo'\)/, - ); - }); - - it("throws an error if partition isn't a number with multiple partitions", function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 2).set('partition', [1, 'foo']), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw( - /You must specify numbers for partition \(you specified '1,foo'\)/, - ); - }); - - it('throws an error if loading partition greater than split number', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 2).set('partition', 3), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw( - /You must specify partitions numbered less than or equal to your split value/, - ); - }); - - it('throws an error if loading partition greater than split number with multiple partitions', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 2).set('partition', [2, 3]), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw( - /You must specify partitions numbered less than or equal to your split value/, - ); - }); - - it('throws an error if loading partition less than one', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('split', 2).set('partition', 0), - ); - - expect(() => { - testLoader.loadModules(); - }).to.throw(/You must specify partitions numbered greater than 0/); - }); - - it('load works with a double-digit single partition', function () { - const testLoader = new EmberExamTestLoader( - this.testem, - new Map().set('partition', '10').set('split', 10), - ); - - window.requirejs.entries = { - 'test-1-test': true, - 'test-2-test': true, - 'test-3-test': true, - 'test-4-test': true, - 'test-5-test': true, - 'test-6-test': true, - 'test-7-test': true, - 'test-8-test': true, - 'test-9-test': true, - 'test-10-test': true, - }; - - testLoader.loadModules(); - - expect(this.requiredModules).to.deep.equal(['test-10-test']); - }); - - it('dummy test to even out the number of tests', function () { - expect(true).to.be.ok; - }); - }); -} diff --git a/tests/unit/mocha/testem-output-test.js b/tests/unit/mocha/testem-output-test.js deleted file mode 100644 index dd33c391..00000000 --- a/tests/unit/mocha/testem-output-test.js +++ /dev/null @@ -1,103 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; -import * as TestemOutput from 'ember-exam/test-support/-private/patch-testem-output'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Unit | Mocha | patch-testem-output', () => { - describe('`preserveTestName` is passed', () => { - it('does not add partition number to test name when `split` is passed', function () { - expect( - TestemOutput.updateTestName( - new Map().set('split', 2).set('preserveTestName', true), - 'test_module | test_name', - ), - ).to.equal('test_module | test_name'); - }); - - it('does not add partition number to test name when `split` and `partition` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('preserveTestName', true), - 'test_module | test_name', - ), - ).to.equal('test_module | test_name'); - }); - - it('does not add browser number to test name when `loadBalance` and `browser` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map() - .set('loadBalance', 2) - .set('browser', 1) - .set('preserveTestName', true), - 'test_module | test_name', - ), - ).to.equal('test_module | test_name'); - }); - - it('does not add partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('browser', 1) - .set('loadBalance', 2) - .set('preserveTestName', true), - 'test_module | test_name', - ), - ).to.equal('test_module | test_name'); - }); - }); - describe('`preserveTestName` is not passed', () => { - it('adds partition number to test name when `split` is passed', function () { - expect( - TestemOutput.updateTestName( - new Map().set('split', 2), - 'test_module | test_name', - ), - ).to.equal('Exam Partition 1 - test_module | test_name'); - }); - - it('adds partition number to test name when `split` and `partition` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map().set('split', 2).set('partition', 2), - 'test_module | test_name', - ), - ).to.equal('Exam Partition 2 - test_module | test_name'); - }); - - it('adds browser number to test name when `loadBalance` and `browser` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map().set('loadBalance', 2).set('browser', 1), - 'test_module | test_name', - ), - ).to.equal('Browser Id 1 - test_module | test_name'); - }); - - it('adds partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function () { - expect( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('browser', 1) - .set('loadBalance', 2), - 'test_module | test_name', - ), - ).to.equal('Exam Partition 2 - Browser Id 1 - test_module | test_name'); - }); - }); - }); -} diff --git a/tests/unit/mocha/weight-test-modules-test.js b/tests/unit/mocha/weight-test-modules-test.js deleted file mode 100644 index 702b67a0..00000000 --- a/tests/unit/mocha/weight-test-modules-test.js +++ /dev/null @@ -1,53 +0,0 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; -import weightTestModules from 'ember-exam/test-support/-private/weight-test-modules'; - -if (macroCondition(dependencySatisfies('ember-mocha', '*'))) { - let { describe, it } = importSync('mocha'); - let { expect } = importSync('chai'); - - describe('Unit | Mocha | weight-test-modules', () => { - it('should sort a list of file paths by weight', function () { - const listOfModules = [ - '/acceptance/test-1-test', - '/unit/test-1-test', - '/integration/test-1-test', - 'test-1-test', - ]; - - expect(weightTestModules(listOfModules)).to.deep.equal([ - '/acceptance/test-1-test', - 'test-1-test', - '/integration/test-1-test', - '/unit/test-1-test', - ]); - }); - - it('should sort a list of file paths by weight and alphbetical order', function () { - const listOfModules = [ - 'test-b-test', - 'test-a-test', - '/integration/test-b-test', - '/integration/test-a-test', - '/unit/test-b-test', - '/acceptance/test-b-test', - '/acceptance/test-a-test', - '/unit/test-a-test', - ]; - - expect(weightTestModules(listOfModules)).to.deep.equal([ - '/acceptance/test-a-test', - '/acceptance/test-b-test', - 'test-a-test', - 'test-b-test', - '/integration/test-a-test', - '/integration/test-b-test', - '/unit/test-a-test', - '/unit/test-b-test', - ]); - }); - }); -} diff --git a/tests/unit/qunit/async-iterator-test.js b/tests/unit/qunit/async-iterator-test.js index c01aeb40..94b54406 100644 --- a/tests/unit/qunit/async-iterator-test.js +++ b/tests/unit/qunit/async-iterator-test.js @@ -1,38 +1,30 @@ import AsyncIterator from 'ember-exam/test-support/-private/async-iterator'; -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; - - module('Unit | Qunit | async-iterator', { - beforeEach() { - this.testem = { - eventHandler: new Array(), - emit: function (event) { - const argsWithoutFirst = Array.prototype.slice.call(arguments, 1); - if (this.eventHandler && this.eventHandler[event]) { - let handlers = this.eventHandler[event]; - for (let i = 0; i < handlers.length; i++) { - handlers[i].apply(this, argsWithoutFirst); - } +import { module, test } from 'qunit'; + +module('Unit | async-iterator', function (hooks) { + hooks.beforeEach(function () { + this.testem = { + eventHandler: new Array(), + emit: function (event) { + const argsWithoutFirst = Array.prototype.slice.call(arguments, 1); + if (this.eventHandler && this.eventHandler[event]) { + let handlers = this.eventHandler[event]; + for (let i = 0; i < handlers.length; i++) { + handlers[i].apply(this, argsWithoutFirst); } - }, - on: function (event, callBack) { - if (!this.eventHandler) { - this.eventHandler = {}; - } - if (!this.eventHandler[event]) { - this.eventHandler[event] = []; - } - this.eventHandler[event].push(callBack); - }, - removeEventCallbacks: () => {}, - }; - }, + } + }, + on: function (event, callBack) { + if (!this.eventHandler) { + this.eventHandler = {}; + } + if (!this.eventHandler[event]) { + this.eventHandler[event] = []; + } + this.eventHandler[event].push(callBack); + }, + removeEventCallbacks: () => {}, + }; }); test('should instantiate', function (assert) { @@ -199,4 +191,4 @@ if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { /Was not expecting a response, but got a response/, ); }); -} +}); diff --git a/tests/unit/qunit/filter-test-modules-test.js b/tests/unit/qunit/filter-test-modules-test.js index ba957cf7..df00d8d4 100644 --- a/tests/unit/qunit/filter-test-modules-test.js +++ b/tests/unit/qunit/filter-test-modules-test.js @@ -2,167 +2,152 @@ import { convertFilePathToModulePath, filterTestModules, } from 'ember-exam/test-support/-private/filter-test-modules'; -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; - let { setupTest } = importSync('ember-qunit'); - - module('Unit | Qunit | filter-test-modules', function () { - module('covertFilePathToModulePath', function (hooks) { - setupTest(hooks); - - test('should return an input string without file extension when the input contains file extension', function (assert) { - assert.strictEqual( - convertFilePathToModulePath('/tests/integration/foo.js'), - '/tests/integration/foo', - ); - }); - - test(`should return an input string without file extension when the input doesn't contain file extension`, function (assert) { - assert.strictEqual( - convertFilePathToModulePath('/tests/integration/foo'), - '/tests/integration/foo', - ); - }); - - test('should return an input string after `tests` when the input is a full test file path', function (assert) { - assert.strictEqual( - convertFilePathToModulePath('dummy/tests/integration/foo.js'), - '/tests/integration/foo', - ); - }); - }), - module('modulePath | Qunit', function (hooks) { - setupTest(hooks); - hooks.beforeEach(function () { - this.modules = ['foo-test', 'bar-test']; - }); - - hooks.afterEach(function () { - this.modules = []; - }); - - test('should return a list of filtered tests', function (assert) { - assert.deepEqual( - ['foo-test'], - filterTestModules(this.modules, 'foo'), - ); - }); - - test('should return an empty list when there is no match', function (assert) { - assert.throws( - () => filterTestModules(this.modules, 'no-match'), - /No tests matched with the filter:/, - ); - }); - - test('should return a list of tests matched with a regular expression', function (assert) { - assert.deepEqual( - ['foo-test'], - filterTestModules(this.modules, '/foo/'), - ); - }); - - test('should return a list of tests matched with a regular expression that excluse foo', function (assert) { - assert.deepEqual( - ['bar-test'], - filterTestModules(this.modules, '!/foo/'), - ); - }); - - test('should return a list of tests matches with a list of string options', function (assert) { - assert.deepEqual( - ['foo-test', 'bar-test'], - filterTestModules(this.modules, 'foo, bar'), - ); - }); - - test('should return a list of unique tests matches when options are repeated', function (assert) { - assert.deepEqual( - ['foo-test'], - filterTestModules(this.modules, 'foo, foo'), - ); - }); - }), - module('filePath | Qunit', function (hooks) { - setupTest(hooks); - hooks.beforeEach(function () { - this.modules = [ - 'dummy/tests/integration/foo-test', - 'dummy/tests/unit/foo-test', - 'dummy/tests/unit/bar-test', - ]; - }); - - hooks.afterEach(function () { - this.modules = []; - }); - - test('should return a test module matched with full test file path', function (assert) { - assert.deepEqual( - ['dummy/tests/integration/foo-test'], - filterTestModules( - this.modules, - null, - 'app/tests/integration/foo-test.js', - ), - ); - }); - - test('should return a test module matched with relative test file path', function (assert) { - assert.deepEqual( - ['dummy/tests/unit/foo-test'], - filterTestModules(this.modules, null, '/unit/foo-test'), - ); - }); - - test('should return a test module matched with test folder path with wildcard', function (assert) { - assert.deepEqual( - ['dummy/tests/unit/foo-test', 'dummy/tests/unit/bar-test'], - filterTestModules(this.modules, null, '/unit/*'), - ); - }); - - test('should return a test module matched with test file path with wildcard', function (assert) { - assert.deepEqual( - ['dummy/tests/integration/foo-test', 'dummy/tests/unit/foo-test'], - filterTestModules(this.modules, null, '/tests/*/foo*'), - ); - }); - - test('should return an empty list when there is no match', function (assert) { - assert.throws( - () => filterTestModules(this.modules, null, 'no-match'), - /No tests matched with the filter:/, - ); - }); - - test('should return a list of tests matches with a list of string options', function (assert) { - assert.deepEqual( - ['dummy/tests/integration/foo-test', 'dummy/tests/unit/foo-test'], - filterTestModules( - this.modules, - null, - '/tests/integration/*, dummy/tests/unit/foo-test', - ), - ); - }); - - test('should return a list of unique tests matches when options are repeated', function (assert) { - assert.deepEqual( - ['dummy/tests/unit/bar-test', 'dummy/tests/unit/foo-test'], - filterTestModules( - this.modules, - null, - 'app/tests/unit/bar-test.js, /tests/unit/*', - ), - ); - }); - }); +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | filter-test-modules', function () { + module('covertFilePathToModulePath', function (hooks) { + setupTest(hooks); + + test('should return an input string without file extension when the input contains file extension', function (assert) { + assert.strictEqual( + convertFilePathToModulePath('/tests/integration/foo.js'), + '/tests/integration/foo', + ); + }); + + test(`should return an input string without file extension when the input doesn't contain file extension`, function (assert) { + assert.strictEqual( + convertFilePathToModulePath('/tests/integration/foo'), + '/tests/integration/foo', + ); + }); + + test('should return an input string after `tests` when the input is a full test file path', function (assert) { + assert.strictEqual( + convertFilePathToModulePath('dummy/tests/integration/foo.js'), + '/tests/integration/foo', + ); + }); + }); + + module('modulePath', function (hooks) { + setupTest(hooks); + hooks.beforeEach(function () { + this.modules = ['foo-test', 'bar-test']; + }); + + hooks.afterEach(function () { + this.modules = []; + }); + + test('should return a list of filtered tests', function (assert) { + assert.deepEqual(['foo-test'], filterTestModules(this.modules, 'foo')); + }); + + test('should return an empty list when there is no match', function (assert) { + assert.throws( + () => filterTestModules(this.modules, 'no-match'), + /No tests matched with the filter:/, + ); + }); + + test('should return a list of tests matched with a regular expression', function (assert) { + assert.deepEqual(['foo-test'], filterTestModules(this.modules, '/foo/')); + }); + + test('should return a list of tests matched with a regular expression that excluse foo', function (assert) { + assert.deepEqual(['bar-test'], filterTestModules(this.modules, '!/foo/')); + }); + + test('should return a list of tests matches with a list of string options', function (assert) { + assert.deepEqual( + ['foo-test', 'bar-test'], + filterTestModules(this.modules, 'foo, bar'), + ); + }); + + test('should return a list of unique tests matches when options are repeated', function (assert) { + assert.deepEqual( + ['foo-test'], + filterTestModules(this.modules, 'foo, foo'), + ); + }); + }); + + module('filePath', function (hooks) { + setupTest(hooks); + hooks.beforeEach(function () { + this.modules = [ + 'dummy/tests/integration/foo-test', + 'dummy/tests/unit/foo-test', + 'dummy/tests/unit/bar-test', + ]; + }); + + hooks.afterEach(function () { + this.modules = []; + }); + + test('should return a test module matched with full test file path', function (assert) { + assert.deepEqual( + ['dummy/tests/integration/foo-test'], + filterTestModules( + this.modules, + null, + 'app/tests/integration/foo-test.js', + ), + ); + }); + + test('should return a test module matched with relative test file path', function (assert) { + assert.deepEqual( + ['dummy/tests/unit/foo-test'], + filterTestModules(this.modules, null, '/unit/foo-test'), + ); + }); + + test('should return a test module matched with test folder path with wildcard', function (assert) { + assert.deepEqual( + ['dummy/tests/unit/foo-test', 'dummy/tests/unit/bar-test'], + filterTestModules(this.modules, null, '/unit/*'), + ); + }); + + test('should return a test module matched with test file path with wildcard', function (assert) { + assert.deepEqual( + ['dummy/tests/integration/foo-test', 'dummy/tests/unit/foo-test'], + filterTestModules(this.modules, null, '/tests/*/foo*'), + ); + }); + + test('should return an empty list when there is no match', function (assert) { + assert.throws( + () => filterTestModules(this.modules, null, 'no-match'), + /No tests matched with the filter:/, + ); + }); + + test('should return a list of tests matches with a list of string options', function (assert) { + assert.deepEqual( + ['dummy/tests/integration/foo-test', 'dummy/tests/unit/foo-test'], + filterTestModules( + this.modules, + null, + '/tests/integration/*, dummy/tests/unit/foo-test', + ), + ); + }); + + test('should return a list of unique tests matches when options are repeated', function (assert) { + assert.deepEqual( + ['dummy/tests/unit/bar-test', 'dummy/tests/unit/foo-test'], + filterTestModules( + this.modules, + null, + 'app/tests/unit/bar-test.js, /tests/unit/*', + ), + ); + }); }); -} +}); diff --git a/tests/unit/qunit/multiple-edge-cases-test.js b/tests/unit/qunit/multiple-edge-cases-test.js index 2d7fe5df..a7b0a4ca 100644 --- a/tests/unit/qunit/multiple-edge-cases-test.js +++ b/tests/unit/qunit/multiple-edge-cases-test.js @@ -1,15 +1,7 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; - - module('Qunit | #3: Module With Multiple Edge Case Tests'); +import { module, test } from 'qunit'; +module('#3: Module With Multiple Edge Case Tests', function () { test('#1 RegExp test', function (assert) { assert.ok(/derp/.test('derp')); }); -} +}); diff --git a/tests/unit/qunit/multiple-ember-tests-test.js b/tests/unit/qunit/multiple-ember-tests-test.js index 156cf416..220aaf8a 100644 --- a/tests/unit/qunit/multiple-ember-tests-test.js +++ b/tests/unit/qunit/multiple-ember-tests-test.js @@ -1,42 +1,34 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; - let { setupTest } = importSync('ember-qunit'); +module('#1: Module-For With Multiple Tests', function (hooks) { + setupTest(hooks); - module('Qunit | #1: Module-For With Multiple Tests', function (hooks) { - setupTest(hooks); - - test('#1', function (assert) { - assert.ok(true); - }); - test('#2', function (assert) { - assert.ok(true); - }); - test('#3', function (assert) { - assert.ok(true); - }); - test('#4', function (assert) { - assert.ok(true); - }); - test('#5', function (assert) { - assert.ok(true); - }); - test('#6', function (assert) { - assert.ok(true); - }); - test('#7', function (assert) { - assert.ok(true); - }); - test('#8', function (assert) { - assert.ok(true); - }); - test('#9', function (assert) { - assert.ok(true); - }); - }); -} + test('#1', function (assert) { + assert.ok(true); + }); + test('#2', function (assert) { + assert.ok(true); + }); + test('#3', function (assert) { + assert.ok(true); + }); + test('#4', function (assert) { + assert.ok(true); + }); + test('#5', function (assert) { + assert.ok(true); + }); + test('#6', function (assert) { + assert.ok(true); + }); + test('#7', function (assert) { + assert.ok(true); + }); + test('#8', function (assert) { + assert.ok(true); + }); + test('#9', function (assert) { + assert.ok(true); + }); +}); diff --git a/tests/unit/qunit/multiple-tests-test.js b/tests/unit/qunit/multiple-tests-test.js index e817f899..0b4766ac 100644 --- a/tests/unit/qunit/multiple-tests-test.js +++ b/tests/unit/qunit/multiple-tests-test.js @@ -1,14 +1,6 @@ -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; - - module('Qunit | #2: Module With Multiple Tests'); +import { module, test } from 'qunit'; +module('#2: Module With Multiple Tests', function () { test('#1', function (assert) { assert.ok(true); }); @@ -36,4 +28,4 @@ if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { test('#9', function (assert) { assert.ok(true); }); -} +}); diff --git a/tests/unit/qunit/test-loader-test.js b/tests/unit/qunit/test-loader-test.js index 9d970cf3..b694870e 100644 --- a/tests/unit/qunit/test-loader-test.js +++ b/tests/unit/qunit/test-loader-test.js @@ -1,49 +1,39 @@ -import EmberExamTestLoader from 'ember-exam/test-support/-private/ember-exam-qunit-test-loader'; -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; - -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let QUnit = importSync('qunit').default; - - let { module, test } = QUnit; - - module('Unit | Qunit | test-loader', { - beforeEach() { - this.originalRequire = window.require; - this.requiredModules = []; - window.require = (name) => { - this.requiredModules.push(name); - }; - - window.requirejs.entries = { - 'test-1-test': true, - 'test-2-test': true, - 'test-3-test': true, - 'test-4-test': true, - }; - this.testem = { - eventQueue: new Array(), - emit: function (event) { - this.eventQueue.push(event); - }, - on: () => {}, - }; - this.qunit = { - config: { - queue: [], - }, - begin: () => {}, - moduleDone: () => {}, - testDone: () => {}, - }; - }, - - afterEach() { - window.require = this.originalRequire; - }, +import EmberExamTestLoader from 'ember-exam/test-support/-private/ember-exam-test-loader'; +import { module, test } from 'qunit'; + +module('Unit | test-loader', function (hooks) { + hooks.beforeEach(function () { + this.originalRequire = window.require; + this.requiredModules = []; + window.require = (name) => { + this.requiredModules.push(name); + }; + + window.requirejs.entries = { + 'test-1-test': true, + 'test-2-test': true, + 'test-3-test': true, + 'test-4-test': true, + }; + this.testem = { + eventQueue: new Array(), + emit: function (event) { + this.eventQueue.push(event); + }, + on: () => {}, + }; + this.qunit = { + config: { + queue: [], + }, + begin: () => {}, + moduleDone: () => {}, + testDone: () => {}, + }; + }); + + hooks.afterEach(function () { + window.require = this.originalRequire; }); test('loads all test modules by default', function (assert) { @@ -235,4 +225,4 @@ if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { 'testem:set-modules-queue event was fired', ); }); -} +}); diff --git a/tests/unit/qunit/testem-output-test.js b/tests/unit/qunit/testem-output-test.js index 72c9adf0..9e39916c 100644 --- a/tests/unit/qunit/testem-output-test.js +++ b/tests/unit/qunit/testem-output-test.js @@ -1,110 +1,103 @@ import * as TestemOutput from 'ember-exam/test-support/-private/patch-testem-output'; -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; +import { module, test } from 'qunit'; -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; +module('Unit | patch-testem-output', function () { + module('`preserveTestName` is passed', function () { + test('does not add partition number to test name when `split` is passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map().set('split', 2).set('preserveTestName', true), + 'test_module | test_name', + ), + 'test_module | test_name', + ); + }); - module('Unit | Qunit | patch-testem-output', () => { - module('`preserveTestName` is passed', () => { - test('does not add partition number to test name when `split` is passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map().set('split', 2).set('preserveTestName', true), - 'test_module | test_name', - ), + test('does not add partition number to test name when `split` and `partition` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map() + .set('split', 2) + .set('partition', 2) + .set('preserveTestName', true), 'test_module | test_name', - ); - }); + ), + 'test_module | test_name', + ); + }); - test('does not add partition number to test name when `split` and `partition` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('preserveTestName', true), - 'test_module | test_name', - ), + test('does not add browser number to test name when `loadBalance` and `browser` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map() + .set('loadBalance', 2) + .set('browser', 1) + .set('preserveTestName', true), 'test_module | test_name', - ); - }); + ), + 'test_module | test_name', + ); + }); - test('does not add browser number to test name when `loadBalance` and `browser` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map() - .set('loadBalance', 2) - .set('browser', 1) - .set('preserveTestName', true), - 'test_module | test_name', - ), + test('does not add partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map() + .set('split', 2) + .set('partition', 2) + .set('browser', 1) + .set('loadBalance', 2) + .set('preserveTestName', true), 'test_module | test_name', - ); - }); + ), + 'test_module | test_name', + ); + }); + }); - test('does not add partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('browser', 1) - .set('loadBalance', 2) - .set('preserveTestName', true), - 'test_module | test_name', - ), + module('`preserveTestName` is not passed', function () { + test('adds partition number to test name when `split` is passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map().set('split', 2), 'test_module | test_name', - ); - }); + ), + 'Exam Partition 1 - test_module | test_name', + ); }); - module('`preserveTestName` is not passed', () => { - test('adds partition number to test name when `split` is passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map().set('split', 2), - 'test_module | test_name', - ), - 'Exam Partition 1 - test_module | test_name', - ); - }); - test('adds partition number to test name when `split` and `partition` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map().set('split', 2).set('partition', 2), - 'test_module | test_name', - ), - 'Exam Partition 2 - test_module | test_name', - ); - }); + test('adds partition number to test name when `split` and `partition` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map().set('split', 2).set('partition', 2), + 'test_module | test_name', + ), + 'Exam Partition 2 - test_module | test_name', + ); + }); - test('adds browser number to test name when `loadBalance` and `browser` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map().set('loadBalance', 2).set('browser', 1), - 'test_module | test_name', - ), - 'Browser Id 1 - test_module | test_name', - ); - }); + test('adds browser number to test name when `loadBalance` and `browser` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map().set('loadBalance', 2).set('browser', 1), + 'test_module | test_name', + ), + 'Browser Id 1 - test_module | test_name', + ); + }); - test('adds partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function (assert) { - assert.deepEqual( - TestemOutput.updateTestName( - new Map() - .set('split', 2) - .set('partition', 2) - .set('browser', 1) - .set('loadBalance', 2), - 'test_module | test_name', - ), - 'Exam Partition 2 - Browser Id 1 - test_module | test_name', - ); - }); + test('adds partition number, browser number to test name when `split`, `partition`, `browser`, and `loadBalance` are passed', function (assert) { + assert.deepEqual( + TestemOutput.updateTestName( + new Map() + .set('split', 2) + .set('partition', 2) + .set('browser', 1) + .set('loadBalance', 2), + 'test_module | test_name', + ), + 'Exam Partition 2 - Browser Id 1 - test_module | test_name', + ); }); }); -} +}); diff --git a/tests/unit/qunit/weight-test-modules-test.js b/tests/unit/qunit/weight-test-modules-test.js index 80de6b3a..126c2de1 100644 --- a/tests/unit/qunit/weight-test-modules-test.js +++ b/tests/unit/qunit/weight-test-modules-test.js @@ -1,58 +1,50 @@ import weightTestModules from 'ember-exam/test-support/-private/weight-test-modules'; -import { - macroCondition, - dependencySatisfies, - importSync, -} from '@embroider/macros'; +import { module, test } from 'qunit'; -if (macroCondition(dependencySatisfies('ember-qunit', '*'))) { - let { module, test } = importSync('qunit').default; +module('Unit | weight-test-modules', function () { + test('should sort a list of file paths by weight', function (assert) { + const listOfModules = [ + '/acceptance/test-1-test', + '/unit/test-1-test', + '/integration/test-1-test', + 'test-1-test', + ]; - module('Unit | Qunit | weight-test-modules', () => { - test('should sort a list of file paths by weight', function (assert) { - const listOfModules = [ + assert.deepEqual( + [ '/acceptance/test-1-test', - '/unit/test-1-test', - '/integration/test-1-test', 'test-1-test', - ]; + '/integration/test-1-test', + '/unit/test-1-test', + ], + weightTestModules(listOfModules), + ); + }); - assert.deepEqual( - [ - '/acceptance/test-1-test', - 'test-1-test', - '/integration/test-1-test', - '/unit/test-1-test', - ], - weightTestModules(listOfModules), - ); - }); + test('should sort a list of file paths by weight and alphabetical order', function (assert) { + const listOfModules = [ + 'test-b-test', + 'test-a-test', + '/integration/test-b-test', + '/integration/test-a-test', + '/unit/test-b-test', + '/acceptance/test-b-test', + '/acceptance/test-a-test', + '/unit/test-a-test', + ]; - test('should sort a list of file paths by weight and alphbetical order', function (assert) { - const listOfModules = [ - 'test-b-test', + assert.deepEqual( + [ + '/acceptance/test-a-test', + '/acceptance/test-b-test', 'test-a-test', - '/integration/test-b-test', + 'test-b-test', '/integration/test-a-test', - '/unit/test-b-test', - '/acceptance/test-b-test', - '/acceptance/test-a-test', + '/integration/test-b-test', '/unit/test-a-test', - ]; - - assert.deepEqual( - [ - '/acceptance/test-a-test', - '/acceptance/test-b-test', - 'test-a-test', - 'test-b-test', - '/integration/test-a-test', - '/integration/test-b-test', - '/unit/test-a-test', - '/unit/test-b-test', - ], - weightTestModules(listOfModules), - ); - }); + '/unit/test-b-test', + ], + weightTestModules(listOfModules), + ); }); -} +}); diff --git a/yarn.lock b/yarn.lock index fdd62686..28285b9f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1386,7 +1386,7 @@ broccoli-funnel "^3.0.8" semver "^7.3.8" -"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.12.2", "@embroider/macros@^1.13.1", "@embroider/macros@^1.13.3", "@embroider/macros@^1.13.4", "@embroider/macros@^1.8.1", "@embroider/macros@^1.8.3": +"@embroider/macros@^0.50.0 || ^1.0.0", "@embroider/macros@^1.0.0", "@embroider/macros@^1.10.0", "@embroider/macros@^1.12.2", "@embroider/macros@^1.13.1", "@embroider/macros@^1.13.3", "@embroider/macros@^1.8.1", "@embroider/macros@^1.8.3": version "1.13.4" resolved "https://registry.yarnpkg.com/@embroider/macros/-/macros-1.13.4.tgz#4fefb79d68bcfbc4619551572b2ca3040a224fb5" integrity sha512-A6tXvfwnscx66QO0R3c2dIJwEltfsTL4ihsYjMtgP9ODCCmQlCaRlZDQYw5Drta0ER9Fj3nXntu4naV5Wt5XLA== @@ -11005,11 +11005,6 @@ lodash.merge@^4.6.0, lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== -lodash.mergewith@4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55" - integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ== - lodash.omit@^4.1.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.omit/-/lodash.omit-4.5.0.tgz#6eb19ae5a1ee1dd9df0b969e66ce0b7fa30b5e60"