From 90305e017c2c5fba0b4b62f41b180910b4baeedb Mon Sep 17 00:00:00 2001 From: Kai Cataldo <7041728+kaicataldo@users.noreply.github.com> Date: Sat, 9 Nov 2019 20:27:57 -0500 Subject: [PATCH] Update: Depcrecate isSpaceBetweenTokens() (#12519) --- docs/developer-guide/working-with-rules.md | 3 +- lib/source-code/source-code.js | 16 +- tests/lib/source-code/source-code.js | 333 +++++++++++++++++++++ 3 files changed, 350 insertions(+), 2 deletions(-) diff --git a/docs/developer-guide/working-with-rules.md b/docs/developer-guide/working-with-rules.md index ef6cbd63468..c5d8808049e 100644 --- a/docs/developer-guide/working-with-rules.md +++ b/docs/developer-guide/working-with-rules.md @@ -392,7 +392,7 @@ Once you have an instance of `SourceCode`, you can use the methods on it to work * `getCommentsAfter(nodeOrToken)` - returns an array of comment tokens that occur directly after the given node or token. * `getCommentsInside(node)` - returns an array of all comment tokens inside a given node. * `getJSDocComment(node)` - returns the JSDoc comment for a given node or `null` if there is none. -* `isSpaceBetweenTokens(first, second)` - returns true if there is a whitespace character between the two tokens. +* `isSpaceBetween(nodeOrToken, nodeOrToken)` - returns true if there is a whitespace character between the two tokens or, if given a node, the last token of the first node and the first token of the second node. * `getFirstToken(node, skipOptions)` - returns the first token representing the given node. * `getFirstTokens(node, countOptions)` - returns the first `count` tokens representing the given node. * `getLastToken(node, skipOptions)` - returns the last token representing the given node. @@ -447,6 +447,7 @@ Please note that the following methods have been deprecated and will be removed * `getComments()` - replaced by `getCommentsBefore()`, `getCommentsAfter()`, and `getCommentsInside()` * `getTokenOrCommentBefore()` - replaced by `getTokenBefore()` with the `{ includeComments: true }` option * `getTokenOrCommentAfter()` - replaced by `getTokenAfter()` with the `{ includeComments: true }` option +* `isSpaceBetweenTokens()` - replaced by `isSpaceBetween()` ### Options Schemas diff --git a/lib/source-code/source-code.js b/lib/source-code/source-code.js index 8a669095949..20b442f2367 100644 --- a/lib/source-code/source-code.js +++ b/lib/source-code/source-code.js @@ -432,7 +432,7 @@ class SourceCode extends TokenStore { * any of the tokens found between the two given nodes or tokens. * @public */ - isSpaceBetweenTokens(first, second) { + isSpaceBetween(first, second) { if (nodesOrTokensOverlap(first, second)) { return false; } @@ -457,6 +457,20 @@ class SourceCode extends TokenStore { return false; } + /** + * Determines if two nodes or tokens have at least one whitespace character + * between them. Order does not matter. Returns false if the given nodes or + * tokens overlap. + * @param {...ASTNode|Token} args The nodes or tokens to check between. + * @returns {boolean} True if there is a whitespace character between + * any of the tokens found between the two given nodes or tokens. + * @deprecated in favor of isSpaceBetween(). + * @public + */ + isSpaceBetweenTokens(...args) { + return this.isSpaceBetween(...args); + } + /** * Converts a source text index into a (line, column) pair. * @param {number} index The index of a character in a file diff --git a/tests/lib/source-code/source-code.js b/tests/lib/source-code/source-code.js index d4d1dd4dd27..29dbf1d6f43 100644 --- a/tests/lib/source-code/source-code.js +++ b/tests/lib/source-code/source-code.js @@ -1789,6 +1789,339 @@ describe("SourceCode", () => { }); }); + describe("isSpaceBetween()", () => { + describe("should return true when there is at least one whitespace character between two tokens", () => { + leche.withData([ + ["let foo", true], + ["let foo", true], + ["let /**/ foo", true], + ["let/**/foo", false], + ["let/*\n*/foo", false] + ], (code, expected) => { + describe("when the first given is located before the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[0], + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1] + ), + expected + ); + }); + }); + + describe("when the first given is located after the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1], + sourceCode.ast.tokens[0] + ), + expected + ); + }); + }); + }); + + leche.withData([ + ["a+b", false], + ["a +b", true], + ["a/**/+b", false], + ["a/* */+b", false], + ["a/**/ +b", true], + ["a/**/ /**/+b", true], + ["a/* */ /* */+b", true], + ["a/**/\n/**/+b", true], + ["a/* */\n/* */+b", true], + ["a/**/+b/**/+c", false], + ["a/* */+b/* */+c", false], + ["a/**/+b /**/+c", true], + ["a/* */+b /* */+c", true], + ["a/**/ +b/**/+c", true], + ["a/* */ +b/* */+c", true], + ["a/**/+b\t/**/+c", true], + ["a/* */+b\t/* */+c", true], + ["a/**/\t+b/**/+c", true], + ["a/* */\t+b/* */+c", true], + ["a/**/+b\n/**/+c", true], + ["a/* */+b\n/* */+c", true], + ["a/**/\n+b/**/+c", true], + ["a/* */\n+b/* */+c", true], + ["a/* */+' /**/ '/* */+c", false], + ["a/* */+ ' /**/ '/* */+c", true], + ["a/* */+' /**/ ' /* */+c", true], + ["a/* */+ ' /**/ ' /* */+c", true], + ["a/* */+` /*\n*/ `/* */+c", false], + ["a/* */+ ` /*\n*/ `/* */+c", true], + ["a/* */+` /*\n*/ ` /* */+c", true], + ["a/* */+ ` /*\n*/ ` /* */+c", true] + ], (code, expected) => { + describe("when the first given is located before the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[0], + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 2] + ), + expected + ); + }); + }); + + describe("when the first given is located after the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 2], + sourceCode.ast.tokens[0] + ), + expected + ); + }); + }); + }); + }); + + describe("should return true when there is at least one whitespace character between a token and a node", () => { + leche.withData([ + [";let foo = bar", false], + [";/**/let foo = bar", false], + [";/* */let foo = bar", false], + ["; let foo = bar", true], + ["; let foo = bar", true], + ["; /**/let foo = bar", true], + ["; /* */let foo = bar", true], + [";/**/ let foo = bar", true], + [";/* */ let foo = bar", true], + ["; /**/ let foo = bar", true], + ["; /* */ let foo = bar", true], + [";\tlet foo = bar", true], + [";\tlet foo = bar", true], + [";\t/**/let foo = bar", true], + [";\t/* */let foo = bar", true], + [";/**/\tlet foo = bar", true], + [";/* */\tlet foo = bar", true], + [";\t/**/\tlet foo = bar", true], + [";\t/* */\tlet foo = bar", true], + [";\nlet foo = bar", true], + [";\nlet foo = bar", true], + [";\n/**/let foo = bar", true], + [";\n/* */let foo = bar", true], + [";/**/\nlet foo = bar", true], + [";/* */\nlet foo = bar", true], + [";\n/**/\nlet foo = bar", true], + [";\n/* */\nlet foo = bar", true] + ], (code, expected) => { + describe("when the first given is located before the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[0], + sourceCode.ast.body[sourceCode.ast.body.length - 1] + ), + expected + ); + }); + }); + + describe("when the first given is located after the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[sourceCode.ast.body.length - 1], + sourceCode.ast.tokens[0] + ), + expected + ); + }); + }); + }); + }); + + describe("should return true when there is at least one whitespace character between a node and a token", () => { + leche.withData([ + ["let foo = bar;;", false], + ["let foo = bar;;;", false], + ["let foo = 1; let bar = 2;;", true], + ["let foo = bar;/**/;", false], + ["let foo = bar;/* */;", false], + ["let foo = bar;;;", false], + ["let foo = bar; ;", true], + ["let foo = bar; /**/;", true], + ["let foo = bar; /* */;", true], + ["let foo = bar;/**/ ;", true], + ["let foo = bar;/* */ ;", true], + ["let foo = bar; /**/ ;", true], + ["let foo = bar; /* */ ;", true], + ["let foo = bar;\t;", true], + ["let foo = bar;\t/**/;", true], + ["let foo = bar;\t/* */;", true], + ["let foo = bar;/**/\t;", true], + ["let foo = bar;/* */\t;", true], + ["let foo = bar;\t/**/\t;", true], + ["let foo = bar;\t/* */\t;", true], + ["let foo = bar;\n;", true], + ["let foo = bar;\n/**/;", true], + ["let foo = bar;\n/* */;", true], + ["let foo = bar;/**/\n;", true], + ["let foo = bar;/* */\n;", true], + ["let foo = bar;\n/**/\n;", true], + ["let foo = bar;\n/* */\n;", true] + ], (code, expected) => { + describe("when the first given is located before the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[0], + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1] + ), + expected + ); + }); + }); + + describe("when the first given is located after the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1], + sourceCode.ast.body[0] + ), + expected + ); + }); + }); + }); + }); + + describe("should return true when there is at least one whitespace character between two nodes", () => { + leche.withData([ + ["let foo = bar;let baz = qux;", false], + ["let foo = bar;/**/let baz = qux;", false], + ["let foo = bar;/* */let baz = qux;", false], + ["let foo = bar; let baz = qux;", true], + ["let foo = bar; /**/let baz = qux;", true], + ["let foo = bar; /* */let baz = qux;", true], + ["let foo = bar;/**/ let baz = qux;", true], + ["let foo = bar;/* */ let baz = qux;", true], + ["let foo = bar; /**/ let baz = qux;", true], + ["let foo = bar; /* */ let baz = qux;", true], + ["let foo = bar;\tlet baz = qux;", true], + ["let foo = bar;\t/**/let baz = qux;", true], + ["let foo = bar;\t/* */let baz = qux;", true], + ["let foo = bar;/**/\tlet baz = qux;", true], + ["let foo = bar;/* */\tlet baz = qux;", true], + ["let foo = bar;\t/**/\tlet baz = qux;", true], + ["let foo = bar;\t/* */\tlet baz = qux;", true], + ["let foo = bar;\nlet baz = qux;", true], + ["let foo = bar;\n/**/let baz = qux;", true], + ["let foo = bar;\n/* */let baz = qux;", true], + ["let foo = bar;/**/\nlet baz = qux;", true], + ["let foo = bar;/* */\nlet baz = qux;", true], + ["let foo = bar;\n/**/\nlet baz = qux;", true], + ["let foo = bar;\n/* */\nlet baz = qux;", true], + ["let foo = 1;let foo2 = 2; let foo3 = 3;", true] + ], (code, expected) => { + describe("when the first given is located before the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[0], + sourceCode.ast.body[sourceCode.ast.body.length - 1] + ), + expected + ); + }); + }); + + describe("when the first given is located after the second", () => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[sourceCode.ast.body.length - 1], + sourceCode.ast.body[0] + ), + expected + ); + }); + }); + }); + }); + + describe("should return false either of the arguments' location is inside the other one", () => { + leche.withData([ + ["let foo = bar;", false] + ], (code, expected) => { + it(code, () => { + const ast = espree.parse(code, DEFAULT_CONFIG), + sourceCode = new SourceCode(code, ast); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[0], + sourceCode.ast.body[0] + ), + expected + ); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1], + sourceCode.ast.body[0] + ), + expected + ); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[0], + sourceCode.ast.tokens[0] + ), + expected + ); + + assert.strictEqual( + sourceCode.isSpaceBetween( + sourceCode.ast.body[0], + sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1] + ), + expected + ); + }); + }); + }); + }); + describe("isSpaceBetweenTokens()", () => { describe("should return true when there is at least one whitespace character between two tokens", () => { leche.withData([