diff --git a/CHANGELOG.md b/CHANGELOG.md index ca9f226..b4235a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.2.4 () +## 1.2.4 (2019-04-08) - Added rule `no-trailing-whitespace` to warn the user when code, comment or blank lines contain trailing whitespaces. This rule will supply the `fix` functionality in a future release. - Added `getLines()` sourceCode utility function for rule developers. This method returns the source code split into lines. - Added `getComments()` sourceCode utility function for rule developers. This method returns a list of AST Nodes representing comments in the source code. diff --git a/config/rulesets/solium-all.js b/config/rulesets/solium-all.js index f9cf5d3..11303ee 100644 --- a/config/rulesets/solium-all.js +++ b/config/rulesets/solium-all.js @@ -40,6 +40,7 @@ module.exports = { "error-reason": "warning", "visibility-first": "warning", "constructor": "warning", + "no-trailing-whitespace": "warning", // Turn OFF all deprecated rules "double-quotes": "off", diff --git a/config/rulesets/solium-recommended.js b/config/rulesets/solium-recommended.js index da98513..3be2ac2 100644 --- a/config/rulesets/solium-recommended.js +++ b/config/rulesets/solium-recommended.js @@ -41,6 +41,7 @@ module.exports = { "function-order": "off", "conditionals-whitespace": "off", "no-experimental": "off", + "no-trailing-whitespace": "warning", // Disable deprecated rules "double-quotes": "off", diff --git a/docs/developer-guide.rst b/docs/developer-guide.rst index c7c9cf3..3101569 100644 --- a/docs/developer-guide.rst +++ b/docs/developer-guide.rst @@ -400,7 +400,7 @@ You're now ready to write your tests (see `shouldjs documentation `_. You also need to add your rule's entry to the ``List of Style Rules`` section in User Guide. -Finally, add an entry for your rule in `solium all `_ ruleset: ``foo-bar: `` where severity should be how your rule should be treated by default (as an error or warning). Severity should be same as what you specified in your rule's ``meta.docs.type``. +Finally, add an entry for your rule in `solium all `_ and `solium recommended `_ rulesets: ``foo-bar: `` where severity should be how your rule should be treated by default (as an error or warning). Severity should be same as what you specified in your rule's ``meta.docs.type``. Now run ``npm run lint`` to let eslint work its magic. Resolve any lint issues you might see in your rule & test files. Run ``npm test`` and resolve any failures. diff --git a/lib/rules/no-trailing-whitespace.js b/lib/rules/no-trailing-whitespace.js index 16e4fcb..e4fa359 100644 --- a/lib/rules/no-trailing-whitespace.js +++ b/lib/rules/no-trailing-whitespace.js @@ -60,8 +60,8 @@ function create(context) { codeLines.forEach((line, i) => { if ( - (isBlankLine(line) && skipBlankLines) || - (isLineInsideAComment(line, i+1, comments, sourceCode) && ignoreComments) + (skipBlankLines && isBlankLine(line)) || + (ignoreComments && isLineInsideAComment(line, i+1, comments, sourceCode)) ) { return; } @@ -109,9 +109,7 @@ module.exports = { ignoreComments: { type: "boolean" } }, additionalProperties: false - }], - - fixable: "code" + }] }, create diff --git a/lib/solium.js b/lib/solium.js index b1eef20..db58177 100644 --- a/lib/solium.js +++ b/lib/solium.js @@ -127,7 +127,7 @@ module.exports = (function() { let message = `[Deprecated] Rule "${name}" is deprecated.`; if (rule.meta.docs.replacedBy) { - message += " Please use " + rule.meta.docs.replacedBy.map(function(rn) { + message += " Use " + rule.meta.docs.replacedBy.map(function(rn) { return "\"" + rn + "\""; }).join(", ") + " instead."; } diff --git a/test/lib/rules.js b/test/lib/rules.js index cf02420..aa08438 100644 --- a/test/lib/rules.js +++ b/test/lib/rules.js @@ -212,7 +212,7 @@ describe("Checking exported rules object", function() { // We extend ALL solium core rules and eliminate a few by setting their severity to 0. // The rest of the rules should all be available. // The below count will keep changing with every change in the number of core rules that exist in solium. - Object.keys(ruleDescriptions).length.should.equal(29); + Object.keys(ruleDescriptions).length.should.equal(30); done(); }); diff --git a/test/lib/rules/no-trailing-whitespace/no-trailing-whitespace.js b/test/lib/rules/no-trailing-whitespace/no-trailing-whitespace.js index e69de29..4d8b807 100644 --- a/test/lib/rules/no-trailing-whitespace/no-trailing-whitespace.js +++ b/test/lib/rules/no-trailing-whitespace/no-trailing-whitespace.js @@ -0,0 +1,121 @@ +/** + * @fileoverview Tests for no-trailing-whitespace rule + * @author Raghav Dua + */ + +"use strict"; + + +const Solium = require("../../../../lib/solium"); + +const config = { + "rules": { + "no-trailing-whitespace": "error" + } +}; + + +describe("[RULE] no-trailing-whitespace: Acceptances", () => { + + it("should accept lines having no trailing whitespaces", done => { + const code = ` + + contract Foo { + // a comment + function baz() returns(uint) { + /* + another happy comment + on multiple lines + */ + + + callHelloWorld( + 100, /* another block comment */ + "voila!", + + 0x1892873871198 + ); + } + }`; + + Solium.lint(code, config).should.be.empty(); + done(); + }); + + it("should accept comments & blank lines with trailing whitespaces if they're ignored", done => { + const configLocal = { + "rules": { + "no-trailing-whitespace": [ + "error", + { "skipBlankLines": true, "ignoreComments": true } + ] + } + }; + + const code = ` + \t\t \t + contract Foo { + // a comment + function baz() returns(uint) { + /* \t + another happy comment + on multiple lines\t + */ + + \t \t + callHelloWorld( + 100, /* another block comment */ + "voila!", +\t + 0x1892873871198 + ); + } // another line comment\t\t + + + function /* hello */ bax() /* world */ returns(string) { /* this is a stretched \t + comment */ + return "hello"; + } + }`; + + Solium.lint(code, configLocal).should.be.empty(); + done(); + }); + +}); + + +describe("[RULE] no-trailing-whitespace: Rejections", () => { + + it("should reject code, comment & blank lines with trailing whitespaces", done => { + const code = ` + \t\t \t + contract Foo { + // a comment + function baz() returns(uint) { + /* \t + another happy comment + on multiple lines\t + */ + + \t \t + callHelloWorld( + 100, /* another block comment */ + "voila!", +\t + 0x1892873871198\t + ); + } // another line comment\t\t + + + function /* hello */ bax() /* world */ returns(string) { /* this is a stretched \t + comment */ + return "hello"; + } + }`; + + Solium.lint(code, config).should.have.size(16); + done(); + }); + +}); diff --git a/test/lib/solium.js b/test/lib/solium.js index 7283d26..6be1247 100644 --- a/test/lib/solium.js +++ b/test/lib/solium.js @@ -866,7 +866,14 @@ describe("Solium.lint() comment directives", () => { `; - const errors = Solium.lint(code, { "extends": "solium:all" }); + const config = { + "extends": "solium:all", + "rules": { + "no-trailing-whitespace": "off" + } + }; + + const errors = Solium.lint(code, config); errors.should.be.Array(); errors.should.have.size(10); // This no. can change if changes are made in any rules from solium:all ruleset @@ -876,7 +883,13 @@ describe("Solium.lint() comment directives", () => { }); it("should respect solium-disable", done => { - const config = { "extends": "solium:all" }; + const config = { + "extends": "solium:all", + "rules": { + "no-trailing-whitespace": "off" + } + }; + let code = `// \t solium-disable contract blah{} contract f { @@ -1392,7 +1405,13 @@ describe("Solium.lint() comment directives", () => { }); it("should respect solium-disable-line", done => { - const config = { "extends": "solium:all" }; + const config = { + "extends": "solium:all", + "rules": { + "no-trailing-whitespace": "off" + } + }; + let code = ` contract blah{}// \t solium-disable-line contract f { @@ -1759,7 +1778,13 @@ describe("Solium.lint() comment directives", () => { }); it("should respect solium-disable-next-line", done => { - const config = { "extends": "solium:all" }; + const config = { + "extends": "solium:all", + "rules": { + "no-trailing-whitespace": "off" + } + }; + let code = ` contract blah{}// \t solium-disable-next-line contract f {