diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dde3293..f22ef420 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,6 @@ jobs: - run: npm ci - run: npm test - - run: npm run update && git diff --exit-code - run: npm install --save-dev eslint@7 && npm run unit-test - name: Coveralls diff --git a/README.md b/README.md index 52e13e04..9ae83170 100644 --- a/README.md +++ b/README.md @@ -19,57 +19,55 @@ For more details on how to extend your configuration from a plugin configuration ## Rules -Each rule has emojis denoting: - -* What configuration it belongs to -* 🔧 if some problems reported by the rule are automatically fixable by the `--fix` [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) option -* 💡 if some problems reported by the rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions) - - - -| Name | Description | ✅ | 🔧 | 💡 | -|:--------|:--------|:---|:---|:---| -| [assert-args](./docs/rules/assert-args.md) | enforce that the correct number of assert arguments are used | ✅ | | | -| [literal-compare-order](./docs/rules/literal-compare-order.md) | enforce comparison assertions have arguments in the right order | ✅ | 🔧 | | -| [no-arrow-tests](./docs/rules/no-arrow-tests.md) | disallow arrow functions as QUnit test/module callbacks | | 🔧 | | -| [no-assert-equal](./docs/rules/no-assert-equal.md) | disallow the use of assert.equal | ✅ | | 💡 | -| [no-assert-equal-boolean](./docs/rules/no-assert-equal-boolean.md) | require use of boolean assertions | ✅ | 🔧 | | -| [no-assert-logical-expression](./docs/rules/no-assert-logical-expression.md) | disallow binary logical expressions in assert arguments | ✅ | | | -| [no-assert-ok](./docs/rules/no-assert-ok.md) | disallow the use of assert.ok/assert.notOk | | | | -| [no-async-in-loops](./docs/rules/no-async-in-loops.md) | disallow async calls in loops | ✅ | | | -| [no-async-module-callbacks](./docs/rules/no-async-module-callbacks.md) | disallow async module callbacks | ✅ | | | -| [no-async-test](./docs/rules/no-async-test.md) | disallow the use of asyncTest or QUnit.asyncTest | ✅ | | | -| [no-commented-tests](./docs/rules/no-commented-tests.md) | disallow commented tests | ✅ | | | -| [no-compare-relation-boolean](./docs/rules/no-compare-relation-boolean.md) | disallow comparing relational expressions to booleans in assertions | ✅ | 🔧 | | -| [no-conditional-assertions](./docs/rules/no-conditional-assertions.md) | disallow assertions within if statements or conditional expressions | ✅ | | | -| [no-early-return](./docs/rules/no-early-return.md) | disallow early return in tests | ✅ | | | -| [no-global-assertions](./docs/rules/no-global-assertions.md) | disallow global QUnit assertions | ✅ | | | -| [no-global-expect](./docs/rules/no-global-expect.md) | disallow global expect | ✅ | | | -| [no-global-module-test](./docs/rules/no-global-module-test.md) | disallow global module/test/asyncTest | ✅ | | | -| [no-global-stop-start](./docs/rules/no-global-stop-start.md) | disallow global stop/start | ✅ | | | -| [no-hooks-from-ancestor-modules](./docs/rules/no-hooks-from-ancestor-modules.md) | disallow the use of hooks from ancestor modules | ✅ | | | -| [no-identical-names](./docs/rules/no-identical-names.md) | disallow identical test and module names | ✅ | | | -| [no-init](./docs/rules/no-init.md) | disallow use of QUnit.init | ✅ | | | -| [no-jsdump](./docs/rules/no-jsdump.md) | disallow use of QUnit.jsDump | ✅ | | | -| [no-loose-assertions](./docs/rules/no-loose-assertions.md) | disallow the use of assert.equal/assert.ok/assert.notEqual/assert.notOk | | | | -| [no-negated-ok](./docs/rules/no-negated-ok.md) | disallow negation in assert.ok/assert.notOk | ✅ | 🔧 | | -| [no-nested-tests](./docs/rules/no-nested-tests.md) | disallow nested QUnit.test() calls | ✅ | | | -| [no-ok-equality](./docs/rules/no-ok-equality.md) | disallow equality comparisons in assert.ok/assert.notOk | ✅ | 🔧 | | -| [no-only](./docs/rules/no-only.md) | disallow QUnit.only | ✅ | | | -| [no-qunit-push](./docs/rules/no-qunit-push.md) | disallow QUnit.push | ✅ | | | -| [no-qunit-start-in-tests](./docs/rules/no-qunit-start-in-tests.md) | disallow QUnit.start() within tests or test hooks | ✅ | | | -| [no-qunit-stop](./docs/rules/no-qunit-stop.md) | disallow QUnit.stop | ✅ | | | -| [no-reassign-log-callbacks](./docs/rules/no-reassign-log-callbacks.md) | disallow overwriting of QUnit logging callbacks | ✅ | | | -| [no-reset](./docs/rules/no-reset.md) | disallow QUnit.reset | ✅ | | | -| [no-setup-teardown](./docs/rules/no-setup-teardown.md) | disallow setup/teardown module hooks | ✅ | 🔧 | | -| [no-skip](./docs/rules/no-skip.md) | disallow QUnit.skip | | | | -| [no-test-expect-argument](./docs/rules/no-test-expect-argument.md) | disallow the expect argument in QUnit.test | ✅ | | | -| [no-throws-string](./docs/rules/no-throws-string.md) | disallow assert.throws() with block, string, and message args | ✅ | | | -| [require-expect](./docs/rules/require-expect.md) | enforce that `expect` is called | ✅ | | | -| [require-object-in-propequal](./docs/rules/require-object-in-propequal.md) | enforce use of objects as expected value in `assert.propEqual` | ✅ | | | -| [resolve-async](./docs/rules/resolve-async.md) | require that async calls are resolved | ✅ | | | - - + + +✅ Enabled in the `recommended` [configuration](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations).\ +🔧 Fixable with [`eslint --fix`](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems).\ +💡 Provides editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). + +| Rule | Description | ✅ | 🔧 | 💡 | +| ------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | --- | --- | --- | +| [assert-args](docs/rules/assert-args.md) | enforce that the correct number of assert arguments are used | ✅ | | | +| [literal-compare-order](docs/rules/literal-compare-order.md) | enforce comparison assertions have arguments in the right order | ✅ | 🔧 | | +| [no-arrow-tests](docs/rules/no-arrow-tests.md) | disallow arrow functions as QUnit test/module callbacks | | 🔧 | | +| [no-assert-equal](docs/rules/no-assert-equal.md) | disallow the use of assert.equal | ✅ | | 💡 | +| [no-assert-equal-boolean](docs/rules/no-assert-equal-boolean.md) | require use of boolean assertions | ✅ | 🔧 | | +| [no-assert-logical-expression](docs/rules/no-assert-logical-expression.md) | disallow binary logical expressions in assert arguments | ✅ | | | +| [no-assert-ok](docs/rules/no-assert-ok.md) | disallow the use of assert.ok/assert.notOk | | | | +| [no-async-in-loops](docs/rules/no-async-in-loops.md) | disallow async calls in loops | ✅ | | | +| [no-async-module-callbacks](docs/rules/no-async-module-callbacks.md) | disallow async module callbacks | ✅ | | | +| [no-async-test](docs/rules/no-async-test.md) | disallow the use of asyncTest or QUnit.asyncTest | ✅ | | | +| [no-commented-tests](docs/rules/no-commented-tests.md) | disallow commented tests | ✅ | | | +| [no-compare-relation-boolean](docs/rules/no-compare-relation-boolean.md) | disallow comparing relational expressions to booleans in assertions | ✅ | 🔧 | | +| [no-conditional-assertions](docs/rules/no-conditional-assertions.md) | disallow assertions within if statements or conditional expressions | ✅ | | | +| [no-early-return](docs/rules/no-early-return.md) | disallow early return in tests | ✅ | | | +| [no-global-assertions](docs/rules/no-global-assertions.md) | disallow global QUnit assertions | ✅ | | | +| [no-global-expect](docs/rules/no-global-expect.md) | disallow global expect | ✅ | | | +| [no-global-module-test](docs/rules/no-global-module-test.md) | disallow global module/test/asyncTest | ✅ | | | +| [no-global-stop-start](docs/rules/no-global-stop-start.md) | disallow global stop/start | ✅ | | | +| [no-hooks-from-ancestor-modules](docs/rules/no-hooks-from-ancestor-modules.md) | disallow the use of hooks from ancestor modules | ✅ | | | +| [no-identical-names](docs/rules/no-identical-names.md) | disallow identical test and module names | ✅ | | | +| [no-init](docs/rules/no-init.md) | disallow use of QUnit.init | ✅ | | | +| [no-jsdump](docs/rules/no-jsdump.md) | disallow use of QUnit.jsDump | ✅ | | | +| [no-loose-assertions](docs/rules/no-loose-assertions.md) | disallow the use of assert.equal/assert.ok/assert.notEqual/assert.notOk | | | | +| [no-negated-ok](docs/rules/no-negated-ok.md) | disallow negation in assert.ok/assert.notOk | ✅ | 🔧 | | +| [no-nested-tests](docs/rules/no-nested-tests.md) | disallow nested QUnit.test() calls | ✅ | | | +| [no-ok-equality](docs/rules/no-ok-equality.md) | disallow equality comparisons in assert.ok/assert.notOk | ✅ | 🔧 | | +| [no-only](docs/rules/no-only.md) | disallow QUnit.only | ✅ | | | +| [no-qunit-push](docs/rules/no-qunit-push.md) | disallow QUnit.push | ✅ | | | +| [no-qunit-start-in-tests](docs/rules/no-qunit-start-in-tests.md) | disallow QUnit.start() within tests or test hooks | ✅ | | | +| [no-qunit-stop](docs/rules/no-qunit-stop.md) | disallow QUnit.stop | ✅ | | | +| [no-reassign-log-callbacks](docs/rules/no-reassign-log-callbacks.md) | disallow overwriting of QUnit logging callbacks | ✅ | | | +| [no-reset](docs/rules/no-reset.md) | disallow QUnit.reset | ✅ | | | +| [no-setup-teardown](docs/rules/no-setup-teardown.md) | disallow setup/teardown module hooks | ✅ | 🔧 | | +| [no-skip](docs/rules/no-skip.md) | disallow QUnit.skip | | | | +| [no-test-expect-argument](docs/rules/no-test-expect-argument.md) | disallow the expect argument in QUnit.test | ✅ | | | +| [no-throws-string](docs/rules/no-throws-string.md) | disallow assert.throws() with block, string, and message args | ✅ | | | +| [require-expect](docs/rules/require-expect.md) | enforce that `expect` is called | ✅ | | | +| [require-object-in-propequal](docs/rules/require-object-in-propequal.md) | enforce use of objects as expected value in `assert.propEqual` | ✅ | | | +| [resolve-async](docs/rules/resolve-async.md) | require that async calls are resolved | ✅ | | | + + ## Contributors diff --git a/docs/rules/assert-args.md b/docs/rules/assert-args.md index e3416877..ffaace7e 100644 --- a/docs/rules/assert-args.md +++ b/docs/rules/assert-args.md @@ -1,6 +1,8 @@ -# Enforce that the correct number of assert arguments are used (assert-args) +# Enforce that the correct number of assert arguments are used (`qunit/assert-args`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit's assertions expect a certain number of arguments based on what sort of condition is being evaluated. diff --git a/docs/rules/literal-compare-order.md b/docs/rules/literal-compare-order.md index 96254d2a..e82c9344 100644 --- a/docs/rules/literal-compare-order.md +++ b/docs/rules/literal-compare-order.md @@ -1,8 +1,10 @@ -# Enforce comparison assertions have arguments in the right order (literal-compare-order) +# Enforce comparison assertions have arguments in the right order (`qunit/literal-compare-order`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + QUnit's many comparison assertions (`equal`, `strictEqual`, etc.) distinguish between an expected value and an actual value, and report incorrect assertions diff --git a/docs/rules/no-arrow-tests.md b/docs/rules/no-arrow-tests.md index 9fce5da4..c3c799af 100644 --- a/docs/rules/no-arrow-tests.md +++ b/docs/rules/no-arrow-tests.md @@ -1,6 +1,8 @@ -# Disallow arrow functions as QUnit test/module callbacks (no-arrow-tests) +# Disallow arrow functions as QUnit test/module callbacks (`qunit/no-arrow-tests`) -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + QUnit test and module callbacks can share state by modifying properties of `this` within those callbacks. diff --git a/docs/rules/no-assert-equal-boolean.md b/docs/rules/no-assert-equal-boolean.md index 0b103d97..abb0d4ca 100644 --- a/docs/rules/no-assert-equal-boolean.md +++ b/docs/rules/no-assert-equal-boolean.md @@ -1,8 +1,10 @@ -# Require use of boolean assertions (no-assert-equal-boolean) +# Require use of boolean assertions (`qunit/no-assert-equal-boolean`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + The boolean assertion functions `assert.true()` and `assert.false()` are available as of QUnit 2.11. These assertions can be stricter and clearer about intent when compared to using other assertion functions for boolean comparisons. diff --git a/docs/rules/no-assert-equal.md b/docs/rules/no-assert-equal.md index d8b53d28..abf2416c 100644 --- a/docs/rules/no-assert-equal.md +++ b/docs/rules/no-assert-equal.md @@ -1,8 +1,10 @@ -# Disallow the use of assert.equal (no-assert-equal) +# Disallow the use of assert.equal (`qunit/no-assert-equal`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -💡 Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions). +💡 This rule provides [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions) that can be applied manually. + + The `assert.equal` assertion method in QUnit uses loose equality comparison. In a project which favors strict equality comparison, it is better to use `assert.strictEqual` for scalar values and either `assert.deepEqual` or `assert.propEqual` for more complex objects. diff --git a/docs/rules/no-assert-logical-expression.md b/docs/rules/no-assert-logical-expression.md index 0c4d6c71..499e40f7 100644 --- a/docs/rules/no-assert-logical-expression.md +++ b/docs/rules/no-assert-logical-expression.md @@ -1,6 +1,8 @@ -# Disallow binary logical expressions in assert arguments (no-assert-logical-expression) +# Disallow binary logical expressions in assert arguments (`qunit/no-assert-logical-expression`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Generally, it is not a good idea to use logical expressions as assertion arguments. Logical-and assertions can be broken down into multiple assertions, while logical-or assertions may be indicative of uncertainty or nondeterminism in a test. diff --git a/docs/rules/no-assert-ok.md b/docs/rules/no-assert-ok.md index dc621fca..e10af9b3 100644 --- a/docs/rules/no-assert-ok.md +++ b/docs/rules/no-assert-ok.md @@ -1,4 +1,6 @@ -# Disallow the use of assert.ok/assert.notOk (no-assert-ok) +# Disallow the use of assert.ok/assert.notOk (`qunit/no-assert-ok`) + + `assert.ok` and `assert.notOk` pass for any truthy/falsy argument. As [many expressions evaluate to true/false in JavaScript](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) the usage of `assert.ok` is potentially error prone. In general, it should be advisable to always test for exact values in tests which makes tests a lot more solid. diff --git a/docs/rules/no-async-in-loops.md b/docs/rules/no-async-in-loops.md index 51c498da..6735d069 100644 --- a/docs/rules/no-async-in-loops.md +++ b/docs/rules/no-async-in-loops.md @@ -1,6 +1,8 @@ -# Disallow async calls in loops (no-async-in-loops) +# Disallow async calls in loops (`qunit/no-async-in-loops`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Asynchronous operations are much harder to reason about in loops. To increase maintainability, asynchronous operations should not be placed within loops. diff --git a/docs/rules/no-async-module-callbacks.md b/docs/rules/no-async-module-callbacks.md index c084e9a1..93994366 100644 --- a/docs/rules/no-async-module-callbacks.md +++ b/docs/rules/no-async-module-callbacks.md @@ -1,6 +1,8 @@ -# Disallow async module callbacks (no-async-module-callbacks) +# Disallow async module callbacks (`qunit/no-async-module-callbacks`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit does not support async module callbacks. Only test and hook callbacks will work as expected when using `async` and `await`. Code after an `await` diff --git a/docs/rules/no-async-test.md b/docs/rules/no-async-test.md index b953d477..18108d0a 100644 --- a/docs/rules/no-async-test.md +++ b/docs/rules/no-async-test.md @@ -1,6 +1,8 @@ -# Disallow the use of asyncTest or QUnit.asyncTest (no-async-test) +# Disallow the use of asyncTest or QUnit.asyncTest (`qunit/no-async-test`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating `QUnit.asyncTest()` in favor of `assert.async()` within tests. This rule will flag `asyncTest` and `QUnit.asyncTest` calls and recommend that you use `assert.async()` instead. diff --git a/docs/rules/no-commented-tests.md b/docs/rules/no-commented-tests.md index e4beff63..334a5387 100644 --- a/docs/rules/no-commented-tests.md +++ b/docs/rules/no-commented-tests.md @@ -1,6 +1,8 @@ -# Disallow commented tests (no-commented-tests) +# Disallow commented tests (`qunit/no-commented-tests`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + When developing non-trivial projects, it is unfortunately realistic that unit tests may need to be temporarily prevented from running until an upstream diff --git a/docs/rules/no-compare-relation-boolean.md b/docs/rules/no-compare-relation-boolean.md index 0763ef78..430d221e 100644 --- a/docs/rules/no-compare-relation-boolean.md +++ b/docs/rules/no-compare-relation-boolean.md @@ -1,8 +1,10 @@ -# Disallow comparing relational expressions to booleans in assertions (no-compare-relation-boolean) +# Disallow comparing relational expressions to booleans in assertions (`qunit/no-compare-relation-boolean`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Sometimes, QUnit assertions contain relations (such as `expected === actual`). Many of these relations can be expressed better using different assertion methods (such as `assert.strictEqual`). However, even for those comparisons which cannot easily be expressed (such as `actual > expected`), comparing those results explicitly to `true` or `false` provides no added value, because the assertion will show that true equals or does not equal true. diff --git a/docs/rules/no-conditional-assertions.md b/docs/rules/no-conditional-assertions.md index 26a1f675..70a28d99 100644 --- a/docs/rules/no-conditional-assertions.md +++ b/docs/rules/no-conditional-assertions.md @@ -1,6 +1,8 @@ -# Disallow assertions within if statements or conditional expressions (no-conditional-assertions) +# Disallow assertions within if statements or conditional expressions (`qunit/no-conditional-assertions`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + This rule aims to detect non-deterministic unit testing by looking for assertions in an if statement or conditional expression. diff --git a/docs/rules/no-early-return.md b/docs/rules/no-early-return.md index d9459e4e..aed80849 100644 --- a/docs/rules/no-early-return.md +++ b/docs/rules/no-early-return.md @@ -1,6 +1,8 @@ -# Disallow early return in tests (no-early-return) +# Disallow early return in tests (`qunit/no-early-return`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + This rule aims to prevent early returns in a QUnit test. Unit tests which can return early are usually indications that a test is nondeterministic or too dependent on environmental factors. On the rare occasion that a test should be run conditionally, the whole test should be run or skipped, rather than having a test that can return early (which is harder to maintain). diff --git a/docs/rules/no-global-assertions.md b/docs/rules/no-global-assertions.md index d4c99be4..8535bce6 100644 --- a/docs/rules/no-global-assertions.md +++ b/docs/rules/no-global-assertions.md @@ -1,6 +1,8 @@ -# Disallow global QUnit assertions (no-global-assertions) +# Disallow global QUnit assertions (`qunit/no-global-assertions`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating and removing global QUnit assertions such as `ok()`, requiring consumers to instead use scoped assertions provided on the test callback argument. diff --git a/docs/rules/no-global-expect.md b/docs/rules/no-global-expect.md index 3e9b727a..90e57301 100644 --- a/docs/rules/no-global-expect.md +++ b/docs/rules/no-global-expect.md @@ -1,6 +1,8 @@ -# Disallow global expect (no-global-expect) +# Disallow global expect (`qunit/no-global-expect`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating and removing the global `expect` function. This rule will warn when the global `expect` function is used. diff --git a/docs/rules/no-global-module-test.md b/docs/rules/no-global-module-test.md index dfe08306..04e101b3 100644 --- a/docs/rules/no-global-module-test.md +++ b/docs/rules/no-global-module-test.md @@ -1,6 +1,8 @@ -# Disallow global module/test/asyncTest (no-global-module-test) +# Disallow global module/test/asyncTest (`qunit/no-global-module-test`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating and removing global functions related to declaring tests and modules. This rule will warn when the global functions are used. diff --git a/docs/rules/no-global-stop-start.md b/docs/rules/no-global-stop-start.md index a579d634..5f5aacee 100644 --- a/docs/rules/no-global-stop-start.md +++ b/docs/rules/no-global-stop-start.md @@ -1,6 +1,8 @@ -# Disallow global stop/start (no-global-stop-start) +# Disallow global stop/start (`qunit/no-global-stop-start`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating and removing all of its global exports, including `stop()` and `start()`. diff --git a/docs/rules/no-hooks-from-ancestor-modules.md b/docs/rules/no-hooks-from-ancestor-modules.md index 4e870c55..ecb22922 100644 --- a/docs/rules/no-hooks-from-ancestor-modules.md +++ b/docs/rules/no-hooks-from-ancestor-modules.md @@ -1,6 +1,8 @@ -# Disallow the use of hooks from ancestor modules (no-hooks-from-ancestor-modules) +# Disallow the use of hooks from ancestor modules (`qunit/no-hooks-from-ancestor-modules`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + When a QUnit `module` is used with a nested callback, the callback provides a `hooks` object as its first argument. This allows calling `hooks.beforeEach` and `hooks.afterEach` diff --git a/docs/rules/no-identical-names.md b/docs/rules/no-identical-names.md index ca8b3405..ef0ce76a 100644 --- a/docs/rules/no-identical-names.md +++ b/docs/rules/no-identical-names.md @@ -1,6 +1,8 @@ -# Disallow identical test and module names (no-identical-names) +# Disallow identical test and module names (`qunit/no-identical-names`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Having identical names for two different tests or modules may create confusion. For example, when a test with the same name as another test diff --git a/docs/rules/no-init.md b/docs/rules/no-init.md index fbc953fb..06a00a15 100644 --- a/docs/rules/no-init.md +++ b/docs/rules/no-init.md @@ -1,6 +1,8 @@ -# Disallow use of QUnit.init (no-init) +# Disallow use of QUnit.init (`qunit/no-init`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Early versions of QUnit exposed the `QUnit.init()` function, which allowed consumers to reinitialize the QUnit test runner. This has been discouraged for diff --git a/docs/rules/no-jsdump.md b/docs/rules/no-jsdump.md index 6f4ae474..13b42eaa 100644 --- a/docs/rules/no-jsdump.md +++ b/docs/rules/no-jsdump.md @@ -1,6 +1,8 @@ -# Disallow use of QUnit.jsDump (no-jsdump) +# Disallow use of QUnit.jsDump (`qunit/no-jsdump`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + When QUnit was first developed, it used the `jsDump` library for serializing objects as strings. Since then, QUnit has forked and evolved the library. To diff --git a/docs/rules/no-loose-assertions.md b/docs/rules/no-loose-assertions.md index 40d4a27d..d8e29a37 100644 --- a/docs/rules/no-loose-assertions.md +++ b/docs/rules/no-loose-assertions.md @@ -1,4 +1,6 @@ -# Disallow the use of assert.equal/assert.ok/assert.notEqual/assert.notOk (no-loose-assertions) +# Disallow the use of assert.equal/assert.ok/assert.notEqual/assert.notOk (`qunit/no-loose-assertions`) + + The `assert.equal`/`assert.notEqual` assertion methods in QUnit use loose equality comparison. In a project which favors strict equality comparison, it is better to use `assert.strictEqual`/`assert.notStrictEqual` for scalar values and either `assert.deepEqual` or `assert.propEqual` for more complex objects. diff --git a/docs/rules/no-negated-ok.md b/docs/rules/no-negated-ok.md index 7d11b392..0765c73f 100644 --- a/docs/rules/no-negated-ok.md +++ b/docs/rules/no-negated-ok.md @@ -1,8 +1,10 @@ -# Disallow negation in assert.ok/assert.notOk (no-negated-ok) +# Disallow negation in assert.ok/assert.notOk (`qunit/no-negated-ok`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Negated `assert.ok()` or `assert.notOk()` solutions can be misleading, because the error message may show a double negative or otherwise be hard to read. It diff --git a/docs/rules/no-nested-tests.md b/docs/rules/no-nested-tests.md index 27a5c19a..e842c95b 100644 --- a/docs/rules/no-nested-tests.md +++ b/docs/rules/no-nested-tests.md @@ -1,6 +1,8 @@ -# Disallow nested QUnit.test() calls (no-nested-tests) +# Disallow nested QUnit.test() calls (`qunit/no-nested-tests`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + This rule prevents from incorrect usage of [Nested Scope](https://github.com/qunitjs/qunit/blob/master/docs/QUnit/module.md#nested-scope). Developer can write nested test instead of nested module by mistake. In this case test will still be executed, but effects may be unexpected. diff --git a/docs/rules/no-ok-equality.md b/docs/rules/no-ok-equality.md index 14a600b0..6622d979 100644 --- a/docs/rules/no-ok-equality.md +++ b/docs/rules/no-ok-equality.md @@ -1,8 +1,10 @@ -# Disallow equality comparisons in assert.ok/assert.notOk (no-ok-equality) +# Disallow equality comparisons in assert.ok/assert.notOk (`qunit/no-ok-equality`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + Equality comparisons in `assert.ok` or `assert.notOk` calls are not valuable because if the assertion fails, QUnit cannot reveal any comparison information. diff --git a/docs/rules/no-only.md b/docs/rules/no-only.md index 1e4c4be1..80c58501 100644 --- a/docs/rules/no-only.md +++ b/docs/rules/no-only.md @@ -1,6 +1,8 @@ -# Disallow QUnit.only (no-only) +# Disallow QUnit.only (`qunit/no-only`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + `QUnit.only` is useful for restricting a test run to just one test while developing, but committing a test file using this function to a repository is dangerous because it will ensure that the rest of the test suite is not run. diff --git a/docs/rules/no-qunit-push.md b/docs/rules/no-qunit-push.md index 3a2c0c94..d66d21c4 100644 --- a/docs/rules/no-qunit-push.md +++ b/docs/rules/no-qunit-push.md @@ -1,6 +1,8 @@ -# Disallow QUnit.push (no-qunit-push) +# Disallow QUnit.push (`qunit/no-qunit-push`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + When writing custom assertions, the proper way to log an assertion result used to be calling `QUnit.push()` with the assertion result data. However, in diff --git a/docs/rules/no-qunit-start-in-tests.md b/docs/rules/no-qunit-start-in-tests.md index db6322d3..d94b023c 100644 --- a/docs/rules/no-qunit-start-in-tests.md +++ b/docs/rules/no-qunit-start-in-tests.md @@ -1,6 +1,8 @@ -# Disallow QUnit.start() within tests or test hooks (no-qunit-start-in-tests) +# Disallow QUnit.start() within tests or test hooks (`qunit/no-qunit-start-in-tests`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + The purpose of this rule is to ensure that `QUnit.start()` is not used within tests or test hooks. diff --git a/docs/rules/no-qunit-stop.md b/docs/rules/no-qunit-stop.md index 2e5855d4..27927680 100644 --- a/docs/rules/no-qunit-stop.md +++ b/docs/rules/no-qunit-stop.md @@ -1,6 +1,8 @@ -# Disallow QUnit.stop (no-qunit-stop) +# Disallow QUnit.stop (`qunit/no-qunit-stop`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit's handling of asynchronous tests used to be via tracking a global semaphore and not starting a test until the previous test had decremented the diff --git a/docs/rules/no-reassign-log-callbacks.md b/docs/rules/no-reassign-log-callbacks.md index 6f875934..c4aa0d63 100644 --- a/docs/rules/no-reassign-log-callbacks.md +++ b/docs/rules/no-reassign-log-callbacks.md @@ -1,6 +1,8 @@ -# Disallow overwriting of QUnit logging callbacks (no-reassign-log-callbacks) +# Disallow overwriting of QUnit logging callbacks (`qunit/no-reassign-log-callbacks`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + In early versions of QUnit, it was possible to create logging functions that would be invoked as QUnit processed tests and modules by assigning to specific diff --git a/docs/rules/no-reset.md b/docs/rules/no-reset.md index 9686a986..0771365a 100644 --- a/docs/rules/no-reset.md +++ b/docs/rules/no-reset.md @@ -1,6 +1,8 @@ -# Disallow QUnit.reset (no-reset) +# Disallow QUnit.reset (`qunit/no-reset`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Early versions of QUnit exposed the `QUnit.reset()` function, which allowed consumers to invoke the internal QUnit fixture reset logic. This has been diff --git a/docs/rules/no-setup-teardown.md b/docs/rules/no-setup-teardown.md index f7cd9ca2..6554d146 100644 --- a/docs/rules/no-setup-teardown.md +++ b/docs/rules/no-setup-teardown.md @@ -1,8 +1,10 @@ -# Disallow setup/teardown module hooks (no-setup-teardown) +# Disallow setup/teardown module hooks (`qunit/no-setup-teardown`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). -🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. +🔧 This rule is automatically fixable using the `--fix` [option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix) on the command line. + + QUnit supports two hooks at the module level: `beforeEach` and `afterEach`. These hooks are run before and after each test, respectively. Before QUnit diff --git a/docs/rules/no-skip.md b/docs/rules/no-skip.md index f5e14cc5..6c4afb35 100644 --- a/docs/rules/no-skip.md +++ b/docs/rules/no-skip.md @@ -1,4 +1,6 @@ -# Disallow QUnit.skip (no-skip) +# Disallow QUnit.skip (`qunit/no-skip`) + + `QUnit.skip` is useful to mark a test as skipped. This should be preferred over commenting out the test. However, leaving tests skipped in perpetuity is a bad practice, as the test ceases to provide any use in ensuring correctness of your code. Skipping tests should be done sparingly. diff --git a/docs/rules/no-test-expect-argument.md b/docs/rules/no-test-expect-argument.md index b433e218..8273b87d 100644 --- a/docs/rules/no-test-expect-argument.md +++ b/docs/rules/no-test-expect-argument.md @@ -1,6 +1,8 @@ -# Disallow the expect argument in QUnit.test (no-test-expect-argument) +# Disallow the expect argument in QUnit.test (`qunit/no-test-expect-argument`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 is deprecating expect counts as the second argument of `QUnit.test`. Users are expected to use `assert.expect()` instead. diff --git a/docs/rules/no-throws-string.md b/docs/rules/no-throws-string.md index 57a3fdc1..4a3bb049 100644 --- a/docs/rules/no-throws-string.md +++ b/docs/rules/no-throws-string.md @@ -1,6 +1,8 @@ -# Disallow assert.throws() with block, string, and message args (no-throws-string) +# Disallow assert.throws() with block, string, and message args (`qunit/no-throws-string`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit 2.0 has deprecated the `assert.throws(block, string, message)` form of `assert.throws()`. This rule can be used to flag uses of the deprecated form diff --git a/docs/rules/require-expect.md b/docs/rules/require-expect.md index b25ee1f2..fafe5f3e 100644 --- a/docs/rules/require-expect.md +++ b/docs/rules/require-expect.md @@ -1,6 +1,8 @@ -# Enforce that `expect` is called (require-expect) +# Enforce that `expect` is called (`qunit/require-expect`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + QUnit's `assert.expect(...)` helps developers create tests that correctly fail when their expected number of assertions are not called. QUnit will throw an diff --git a/docs/rules/require-object-in-propequal.md b/docs/rules/require-object-in-propequal.md index f6ea2d23..20762fc7 100644 --- a/docs/rules/require-object-in-propequal.md +++ b/docs/rules/require-object-in-propequal.md @@ -1,6 +1,8 @@ -# Enforce use of objects as expected value in `assert.propEqual` (require-object-in-propequal) +# Enforce use of objects as expected value in `assert.propEqual` (`qunit/require-object-in-propequal`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + The `assert.propEqual` assertion is for the strict-equality comparison of own-properties of two objects. If the expected value is a string or other non-object, the assertion diff --git a/docs/rules/resolve-async.md b/docs/rules/resolve-async.md index d9f84ad6..b8a456b0 100644 --- a/docs/rules/resolve-async.md +++ b/docs/rules/resolve-async.md @@ -1,6 +1,8 @@ -# Require that async calls are resolved (resolve-async) +# Require that async calls are resolved (`qunit/resolve-async`) -✅ The `"extends": "plugin:qunit/recommended"` property in a configuration file enables this rule. +✅ This rule is enabled in the `recommended` [config](https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations). + + Asynchronous operations on QUnit tests should be resolved within the scope of the test to maximize readability and maintainability. Also, if there are more diff --git a/package-lock.json b/package-lock.json index 2b046a62..fda24b74 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "chai": "^4.3.6", "coveralls": "^3.1.1", "eslint": "^8.19.0", + "eslint-doc-generator": "^0.6.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^4.4.0", "eslint-plugin-markdown": "^2.2.1", @@ -686,6 +687,12 @@ "node": ">= 8" } }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "node_modules/@types/mdast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", @@ -791,6 +798,113 @@ } } }, + "node_modules/@typescript-eslint/utils": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz", + "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.39.0", + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/typescript-estree": "5.39.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz", + "integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz", + "integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz", + "integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz", + "integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.39.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "5.30.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", @@ -1773,6 +1887,48 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint-doc-generator": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-0.6.0.tgz", + "integrity": "sha512-OvWFCrTd+vCWWu6lCal5lJDJS5fr9YdrJiErkh/QDTVujp+S2xLyCjkr5BLfzOOgPYIogcsdYL0kHxqt0XbwTw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.38.1", + "commander": "^9.4.0", + "type-fest": "^3.0.0" + }, + "bin": { + "eslint-doc-generator": "dist/bin/eslint-doc-generator.js" + }, + "engines": { + "node": "^14.18.0 || ^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">= 7", + "prettier": ">= 2" + } + }, + "node_modules/eslint-doc-generator/node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/eslint-doc-generator/node_modules/type-fest": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.1.0.tgz", + "integrity": "sha512-StmrZmK3eD9mDF9Vt7UhqthrDSk66O9iYl5t5a0TSoVkHjl0XZx/xuc/BRz4urAXXGHOY5OLsE0RdJFIApSFmw==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/eslint-plugin-es": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", @@ -1984,6 +2140,19 @@ "eslint": ">=8.8.0" } }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -2147,6 +2316,15 @@ "node": ">=4.0" } }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -4635,6 +4813,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "peer": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", @@ -6415,6 +6609,12 @@ "fastq": "^1.6.0" } }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, "@types/mdast": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.3.tgz", @@ -6479,6 +6679,69 @@ "tsutils": "^3.21.0" } }, + "@typescript-eslint/utils": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz", + "integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.39.0", + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/typescript-estree": "5.39.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz", + "integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0" + } + }, + "@typescript-eslint/types": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz", + "integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz", + "integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "@typescript-eslint/visitor-keys": "5.39.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz", + "integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.39.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } + } + }, "@typescript-eslint/visitor-keys": { "version": "5.30.5", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.5.tgz", @@ -7267,6 +7530,31 @@ } } }, + "eslint-doc-generator": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/eslint-doc-generator/-/eslint-doc-generator-0.6.0.tgz", + "integrity": "sha512-OvWFCrTd+vCWWu6lCal5lJDJS5fr9YdrJiErkh/QDTVujp+S2xLyCjkr5BLfzOOgPYIogcsdYL0kHxqt0XbwTw==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^5.38.1", + "commander": "^9.4.0", + "type-fest": "^3.0.0" + }, + "dependencies": { + "commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true + }, + "type-fest": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.1.0.tgz", + "integrity": "sha512-StmrZmK3eD9mDF9Vt7UhqthrDSk66O9iYl5t5a0TSoVkHjl0XZx/xuc/BRz4urAXXGHOY5OLsE0RdJFIApSFmw==", + "dev": true + } + } + }, "eslint-plugin-es": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", @@ -7408,6 +7696,16 @@ "strip-indent": "^3.0.0" } }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, "eslint-utils": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", @@ -7474,6 +7772,12 @@ } } }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -9306,6 +9610,13 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, + "prettier": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "dev": true, + "peer": true + }, "process-on-spawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", diff --git a/package.json b/package.json index a059861f..ad11460c 100644 --- a/package.json +++ b/package.json @@ -7,11 +7,12 @@ "test": "npm run lint && npm run unit-test", "lint": "npm-run-all --continue-on-error --aggregate-output --parallel lint:*", "lint:docs": "markdownlint \"**/*.md\"", + "lint:eslint-docs": "npm-run-all update:eslint-docs && git diff --exit-code", "lint:js": "eslint --cache --report-unused-disable-directives .", "unit-test": "nyc mocha tests/**/*.js", "report-coverage-html": "nyc report --reporter=html --report-dir build/coverage", "preversion": "npm test", - "update": "node ./scripts/update-rules.js", + "update:eslint-docs": "eslint-doc-generator --url-configs \"https://github.com/platinumazure/eslint-plugin-qunit/blob/master/README.md#configurations\"", "version": "node build/generate-release-changelog.js" }, "files": [ @@ -28,6 +29,7 @@ "chai": "^4.3.6", "coveralls": "^3.1.1", "eslint": "^8.19.0", + "eslint-doc-generator": "^0.6.0", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-eslint-plugin": "^4.4.0", "eslint-plugin-markdown": "^2.2.1", diff --git a/scripts/update-rules.js b/scripts/update-rules.js deleted file mode 100644 index 2c9649a7..00000000 --- a/scripts/update-rules.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; - -const fs = require("fs"); -const path = require("path"); -const { rules, configs } = require("../"); - -const pathReadme = path.resolve(__dirname, "../README.md"); -const readmeContent = fs.readFileSync(pathReadme, "utf8"); -const tablePlaceholder = /[\S\s]*/; - -// Config/preset/fixable emojis. -const EMOJI_RECOMMENDED = "✅"; -const EMOJI_FIXABLE = "🔧"; -const EMOJI_SUGGESTIONS = "💡"; - -// Generate rule table contents. -const rulesTableContent = Object.keys(rules) - .sort() - .map((ruleName) => { - // Check which emojis to show for this rule. - const isRecommended = Object.prototype.hasOwnProperty.call(configs.recommended.rules, `qunit/${ruleName}`); - const isFixable = rules[ruleName].meta.fixable; - const hasSuggestions = rules[ruleName].meta.hasSuggestions; - const url = `./docs/rules/${ruleName}.md`; - const link = `[${ruleName}](${url})`; - const description = rules[ruleName].meta.docs.description; - return `| ${link} | ${description} | ${isRecommended ? EMOJI_RECOMMENDED : ""} | ${isFixable ? EMOJI_FIXABLE : ""} | ${hasSuggestions ? EMOJI_SUGGESTIONS : ""} |`; - }) - .join("\n"); - -fs.writeFileSync( - pathReadme, - readmeContent.replace( - tablePlaceholder, - `\n\n| Name | Description | ${EMOJI_RECOMMENDED} | ${EMOJI_FIXABLE} | ${EMOJI_SUGGESTIONS} |\n|:--------|:--------|:---|:---|:---|\n${rulesTableContent}\n\n` - ) -); diff --git a/tests/index.js b/tests/index.js index 683b78d6..98b959dc 100644 --- a/tests/index.js +++ b/tests/index.js @@ -17,46 +17,6 @@ const assert = require("chai").assert, // Tests //------------------------------------------------------------------------------ -const MESSAGES = { - fixable: "🔧 The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.", - configRecommended: "✅ The `\"extends\": \"plugin:qunit/recommended\"` property in a configuration file enables this rule.", - hasSuggestions: "💡 Some problems reported by this rule are manually fixable by editor [suggestions](https://eslint.org/docs/developer-guide/working-with-rules#providing-suggestions)." -}; - -function toSentenceCase(str) { - return str.replace( - /^\w/, - function (txt) { - return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase(); - } - ); -} - -/** - * Get list of named options from a JSON schema (used for rule schemas). - * @param {Object|Array} jsonSchema - the JSON schema to check - * @returns {String[]} list of named options - */ -function getAllNamedOptions(jsonSchema) { - if (!jsonSchema) { - return []; - } - - if (Array.isArray(jsonSchema)) { - return jsonSchema.flatMap(item => getAllNamedOptions(item)); - } - - if (jsonSchema.items) { - return getAllNamedOptions(jsonSchema.items); - } - - if (jsonSchema.properties) { - return Object.keys(jsonSchema.properties); - } - - return []; -} - const ruleNames = fs.readdirSync("./lib/rules").map(rawFileName => path.basename(rawFileName, ".js")); describe("index.js", function () { @@ -94,72 +54,6 @@ describe("index.js", function () { "includes jsdoc comment for rule type" ); }); - - // eslint-disable-next-line complexity - it("should have the right doc contents", function () { - const path = `./docs/rules/${ruleName}.md`; - const fileContents = fs.readFileSync(path, "utf8"); - const lines = fileContents.split("\n"); - const rule = rules[ruleName]; - - // First content should be title. - const description = rule.meta.docs.description; - const expectedTitle = `# ${toSentenceCase(description)} (${ruleName})`; - assert.equal(lines[0], expectedTitle, "includes the rule description and name in title"); - - // Decide which notices should be shown at the top of the doc. - const expectedNotices = []; - const unexpectedNotices = []; - if (configs.recommended.rules[`qunit/${ruleName}`]) { - expectedNotices.push("configRecommended"); - } else { - unexpectedNotices.push("configRecommended"); - } - if (rule.meta.fixable) { - expectedNotices.push("fixable"); - } else { - unexpectedNotices.push("fixable"); - } - if (rule.meta.hasSuggestions) { - expectedNotices.push("hasSuggestions"); - } else { - unexpectedNotices.push("hasSuggestions"); - } - - // Ensure that expected notices are present in the correct order. - let currentLineNumber = 1; - for (const expectedNotice of expectedNotices) { - assert.equal(lines[currentLineNumber], "", `has blank line before ${expectedNotice} notice`); - assert.equal(lines[currentLineNumber + 1], MESSAGES[expectedNotice], `includes ${expectedNotice} notice`); - currentLineNumber += 2; - } - - // Ensure that unexpected notices are not present. - for (const unexpectedNotice of unexpectedNotices) { - assert.ok( - !fileContents.includes(MESSAGES[unexpectedNotice]), - `does not include unexpected ${unexpectedNotice} notice` - ); - } - - // Check if the rule has configuration options. - if ( - Array.isArray(rule.meta.schema) && rule.meta.schema.length > 0 || - typeof rule.meta.schema === "object" && Object.keys(rule.meta.schema).length > 0 - ) { - // Should have a configuration section header: - assert.ok(fileContents.includes("## Options"), "Should have an \"## Options\" section"); - - // Ensure all configuration options are mentioned. - for (const namedOption of getAllNamedOptions(rule.meta.schema)) { - assert.ok(fileContents.includes(namedOption), `Should mention the \`${namedOption}\` option`); - } - } else { - // Should NOT have any options/config section headers: - assert.notOk(fileContents.includes("# Options"), "Should not have an \"Options\" section"); - assert.notOk(fileContents.includes("# Config"), "Should not have a \"Config\" section"); - } - }); }); } });