Skip to content

Commit

Permalink
Update: add checkBooleanAssertions option to no-negated-ok rule (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
bmish authored Apr 22, 2021
1 parent 7790c4d commit 12c0d71
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/rules/no-negated-ok.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ QUnit.test('test', function (assert) {

This rule takes an optional object containing:

* `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
* `fixToNotOk` (boolean, default: true): Whether the rule should autofix `assert.ok(!foo)` to `assert.notOk(foo)` ([notOk](https://api.qunitjs.com/assert/notOk/) was added in QUnit 1.18)

## When Not to Use It
Expand Down
19 changes: 17 additions & 2 deletions lib/rules/no-negated-ok.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
const assert = require("assert"),
utils = require("../utils");

const ASSERTION_OPPOSITES = {
"false": "true",
"notOk": "ok",
"ok": "notOk",
"true": "false"
};

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
Expand All @@ -27,6 +34,10 @@ module.exports = {
{
type: "object",
properties: {
checkBooleanAssertions: {
type: "boolean",
default: false
},
fixToNotOk: {
type: "boolean",
default: true
Expand All @@ -38,12 +49,16 @@ module.exports = {
},

create: function (context) {
const checkBooleanAssertions = context.options[0] && context.options[0].checkBooleanAssertions;
const fixToNotOk = !context.options[0] || context.options[0].fixToNotOk;

const POSITIVE_ASSERTIONS = checkBooleanAssertions ? ["ok", "true"] : ["ok"];
const NEGATIVE_ASSERTIONS = checkBooleanAssertions ? ["notOk", "false"] : ["notOk"];

// Declare a stack in case of nested test cases (not currently supported
// in QUnit).
const asyncStateStack = [],
ASSERTIONS_TO_CHECK = ["ok", "notOk"],
ASSERTIONS_TO_CHECK = [...POSITIVE_ASSERTIONS, ...NEGATIVE_ASSERTIONS],
sourceCode = context.getSourceCode();

function getAssertVar() {
Expand Down Expand Up @@ -120,7 +135,7 @@ module.exports = {
// * assert.ok(!foo) => assert.notOk(foo) -- when `fixToNotOk` option enabled

const assertionVariableName = callExprNode.callee.object.name;
const oppositeAssertionFunctionName = callExprNode.callee.property.name === "ok" ? "notOk" : "ok";
const oppositeAssertionFunctionName = ASSERTION_OPPOSITES[callExprNode.callee.property.name];
const newAssertionFunctionName = !fixToNotOk && oppositeAssertionFunctionName === "notOk" ? "equal" : oppositeAssertionFunctionName;
const newArgsTextArray = [unwrapNegation(firstArgNode), ...callExprNode.arguments.slice(1)].map(arg => sourceCode.getText(arg));
if (newAssertionFunctionName === "equal") {
Expand Down
60 changes: 59 additions & 1 deletion tests/lib/rules/no-negated-ok.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,49 @@ ruleTester.run("no-negated-ok", rule, {
wrap("assert.ok.foo(!a)"),
wrap("foo.assert.ok(!a)"),
wrap("foo.assert.bar.ok(!a)"),
wrap("foo.assert.bar.ok.baz(!a)")
wrap("foo.assert.bar.ok.baz(!a)"),

// Boolean assertions, no negation
{
code: wrap("assert.true(foo)"),
options: [{ checkBooleanAssertions: true }]
},
{
code: wrap("assert.true(foo, 'message')"),
options: [{ checkBooleanAssertions: true }]
},
{
code: wrap("assert.false(foo)"),
options: [{ checkBooleanAssertions: true }]
},
{
code: wrap("assert.false(foo, 'message')"),
options: [{ checkBooleanAssertions: true }]
},

// Boolean assertions, negation, checkBooleanAssertions = false (implicitly)
wrap("assert.true(!foo)"),
wrap("assert.true(!foo, 'message')"),
wrap("assert.false(!foo)"),
wrap("assert.false(!foo, 'message')"),

// Boolean assertions, negation, checkBooleanAssertions = false (explicitly)
{
code: wrap("assert.true(!foo)"),
options: [{ checkBooleanAssertions: false }]
},
{
code: wrap("assert.true(!foo, 'message')"),
options: [{ checkBooleanAssertions: false }]
},
{
code: wrap("assert.false(!foo)"),
options: [{ checkBooleanAssertions: false }]
},
{
code: wrap("assert.false(!foo, 'message')"),
options: [{ checkBooleanAssertions: false }]
}
],

invalid: [
Expand Down Expand Up @@ -192,6 +234,22 @@ ruleTester.run("no-negated-ok", rule, {
code: wrap("assert.notOk(!!!foo, 'message')"),
output: wrap("assert.ok(foo, 'message')"),
errors: [createError("assert.notOk")]
},

// true
{
code: wrap("assert.true(!foo)"),
output: wrap("assert.false(foo)"),
options: [{ checkBooleanAssertions: true }],
errors: [createError("assert.true")]
},

// false
{
code: wrap("assert.false(!foo)"),
output: wrap("assert.true(foo)"),
options: [{ checkBooleanAssertions: true }],
errors: [createError("assert.false")]
}
]

Expand Down

0 comments on commit 12c0d71

Please sign in to comment.