From 291a6c179fcae6b929fab3ba652073356ec8a333 Mon Sep 17 00:00:00 2001 From: Bryan Mishkin <698306+bmish@users.noreply.github.com> Date: Wed, 21 Apr 2021 18:10:06 -0700 Subject: [PATCH] Update: add checkBooleanAssertions option to no-ok-equality rule (#173) --- docs/rules/no-ok-equality.md | 7 ++++ lib/rules/no-ok-equality.js | 17 +++++--- tests/lib/rules/no-ok-equality.js | 70 +++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/docs/rules/no-ok-equality.md b/docs/rules/no-ok-equality.md index 9a366f98..ac37732c 100644 --- a/docs/rules/no-ok-equality.md +++ b/docs/rules/no-ok-equality.md @@ -62,6 +62,13 @@ QUnit.test("Name", function (assert) { assert.ok(x instanceof Number); }); ``` +## Configuration + +This rule takes an optional object containing: + +* `allowGlobals` (boolean, default: true): Whether the rule should check global assertions +* `checkBooleanAssertions` (boolean, default: false): Whether the rule should check the [true](https://api.qunitjs.com/assert/true/) and [false](https://api.qunitjs.com/assert/false/) boolean assertions + ## When Not to Use It It is best to enable this rule, but since it is possible to test a codebase diff --git a/lib/rules/no-ok-equality.js b/lib/rules/no-ok-equality.js index a41d1cda..fac4d461 100644 --- a/lib/rules/no-ok-equality.js +++ b/lib/rules/no-ok-equality.js @@ -28,6 +28,9 @@ module.exports = { properties: { allowGlobal: { type: "boolean" + }, + checkBooleanAssertions: { + type: "boolean" } }, additionalProperties: false @@ -40,11 +43,15 @@ module.exports = { // in QUnit). const asyncStateStack = [], DEFAULT_OPTIONS = { - allowGlobal: true + allowGlobal: true, + checkBooleanAssertions: false }, options = context.options[0] || DEFAULT_OPTIONS, sourceCode = context.getSourceCode(); + const POSITIVE_ASSERTIONS = options.checkBooleanAssertions ? ["ok", "true"] : ["ok"]; + const NEGATIVE_ASSERTIONS = options.checkBooleanAssertions ? ["notOk", "false"] : ["notOk"]; + function getAssertContextVar() { const state = asyncStateStack[asyncStateStack.length - 1]; return state && state.assertContextVar; @@ -53,13 +60,13 @@ module.exports = { function isOk(calleeNode) { const assertContextVar = getAssertContextVar(); - const isOk = calleeNode.type === "Identifier" && calleeNode.name === "ok"; + const isOk = calleeNode.type === "Identifier" && POSITIVE_ASSERTIONS.includes(calleeNode.name); const isAssertOk = calleeNode.type === "MemberExpression" && calleeNode.object.type === "Identifier" && calleeNode.object.name === assertContextVar && calleeNode.property.type === "Identifier" && - calleeNode.property.name === "ok"; + POSITIVE_ASSERTIONS.includes(calleeNode.property.name); if (options.allowGlobal) { return isOk || isAssertOk; @@ -71,13 +78,13 @@ module.exports = { function isNotOk(calleeNode) { const assertContextVar = getAssertContextVar(); - const isNotOk = calleeNode.type === "Identifier" && calleeNode.name === "notOk"; + const isNotOk = calleeNode.type === "Identifier" && NEGATIVE_ASSERTIONS.includes(calleeNode.name); const isAssertNotOk = calleeNode.type === "MemberExpression" && calleeNode.object.type === "Identifier" && calleeNode.object.name === assertContextVar && calleeNode.property.type === "Identifier" && - calleeNode.property.name === "notOk"; + NEGATIVE_ASSERTIONS.includes(calleeNode.property.name); if (options.allowGlobal) { return isNotOk || isAssertNotOk; diff --git a/tests/lib/rules/no-ok-equality.js b/tests/lib/rules/no-ok-equality.js index 824b2b1a..bcf3b8f1 100644 --- a/tests/lib/rules/no-ok-equality.js +++ b/tests/lib/rules/no-ok-equality.js @@ -79,6 +79,38 @@ ruleTester.run("no-ok-equality", rule, { { code: "test('Name', function () { notOk(x != 1); });", options: [{ allowGlobal: false }] + }, + + // Boolean assertions with no equality checks: + { + code: "test('Name', function (assert) { assert.true(x); });", + options: [{ checkBooleanAssertions: true }] + }, + { + code: "test('Name', function (assert) { assert.true(x, 'message'); });", + options: [{ checkBooleanAssertions: true }] + }, + { + code: "test('Name', function (assert) { assert.false(x); });", + options: [{ checkBooleanAssertions: true }] + }, + { + code: "test('Name', function (assert) { assert.false(x, 'message'); });", + options: [{ checkBooleanAssertions: true }] + }, + + // Boolean assertions with equality checks (checkBooleanAssertions = false, implicitly) + "test('Name', function (assert) { assert.true(x === 1); });", + "test('Name', function (assert) { assert.false(x === 1); });", + + // Boolean assertions with equality checks (checkBooleanAssertions = false, explicitly) + { + code: "test('Name', function (assert) { assert.true(x === 1); });", + options: [{ checkBooleanAssertions: false }] + }, + { + code: "test('Name', function (assert) { assert.false(x === 1); });", + options: [{ checkBooleanAssertions: false }] } ], @@ -210,6 +242,44 @@ ruleTester.run("no-ok-equality", rule, { errors: [ createError("notOk", "equal", "x", "1") ] + }, + + // Boolean assertions with equality checks (checkBooleanAssertions = true, explicitly) + { + // true + code: "test('Name', function (assert) { assert.true(x === 1); });", + output: "test('Name', function (assert) { assert.strictEqual(x, 1); });", + options: [{ checkBooleanAssertions: true }], + errors: [ + createError("assert.true", "assert.strictEqual", "x", "1") + ] + }, + { + // true, with message + code: "test('Name', function (assert) { assert.true(x === 1, 'message'); });", + output: "test('Name', function (assert) { assert.strictEqual(x, 1, 'message'); });", + options: [{ checkBooleanAssertions: true }], + errors: [ + createError("assert.true", "assert.strictEqual", "x", "1") + ] + }, + { + // false + code: "test('Name', function (assert) { assert.false(x === 1); });", + output: "test('Name', function (assert) { assert.notStrictEqual(x, 1); });", + options: [{ checkBooleanAssertions: true }], + errors: [ + createError("assert.false", "assert.notStrictEqual", "x", "1") + ] + }, + { + // false, with message + code: "test('Name', function (assert) { assert.false(x === 1, 'message'); });", + output: "test('Name', function (assert) { assert.notStrictEqual(x, 1, 'message'); });", + options: [{ checkBooleanAssertions: true }], + errors: [ + createError("assert.false", "assert.notStrictEqual", "x", "1") + ] } ]