From 0e7cdb847f50568bcdd868c3d1a61cd8040db770 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Thu, 31 Oct 2019 13:06:49 -0700 Subject: [PATCH 1/8] test: add tests for formatter receiving needlessDisables and invalidScopeDisables --- lib/__tests__/standalone-formatter.test.js | 50 ++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/lib/__tests__/standalone-formatter.test.js b/lib/__tests__/standalone-formatter.test.js index d5c64fa03e..ee09dcf279 100644 --- a/lib/__tests__/standalone-formatter.test.js +++ b/lib/__tests__/standalone-formatter.test.js @@ -50,3 +50,53 @@ it('standalone with invalid formatter option', () => { ); }); }); + +it('standalone formatter receives {needlessDisables} as second argument', () => { + const formatter = jest.fn((results, { needlessDisables }) => { + return JSON.stringify({ results, needlessDisables }, null, 2); + }); + + return standalone({ + code: ` + // stylelint-disable yo + a {} + `, + config: configBlockNoEmpty, + reportNeedlessDisables: true, + formatter, + }).then((linted) => { + const { output, results, needlessDisables } = linted; + + expect(needlessDisables).not.toBeUndefined(); + expect(needlessDisables).toHaveLength(1); + + expect(typeof output).toBe('string'); + expect(formatter).toHaveBeenCalledTimes(1); + expect(output).toBe(JSON.stringify({ results, needlessDisables }, null, 2)); + }); +}); + +it('standalone formatter receives {invalidScopeDisables} as second argument', () => { + const formatter = jest.fn((results, { invalidScopeDisables }) => { + return JSON.stringify({ results, invalidScopeDisables }, null, 2); + }); + + return standalone({ + code: ` + /* stylelint-disable indentation */ + a { color: red; } + `, + config: configBlockNoEmpty, + reportInvalidScopeDisables: true, + formatter, + }).then((linted) => { + const { output, results, invalidScopeDisables } = linted; + + expect(invalidScopeDisables).not.toBeUndefined(); + expect(invalidScopeDisables).toHaveLength(1); + + expect(typeof output).toBe('string'); + expect(formatter).toHaveBeenCalledTimes(1); + expect(output).toBe(JSON.stringify({ results, invalidScopeDisables }, null, 2)); + }); +}); From 836c5aa92fb3898e04322f6a318e1cc043c429cc Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Thu, 31 Oct 2019 13:09:24 -0700 Subject: [PATCH 2/8] feat: pass {needlessDisables, invalidScopeDisables} to formatter --- lib/standalone.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/standalone.js b/lib/standalone.js index 3b4b0a977c..193edcd66c 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -293,25 +293,35 @@ module.exports = function( const errored = stylelintResults.some( (result) => result.errored || result.parseErrors.length > 0, ); + /** @type {StylelintStandaloneReturnValue} */ const returnValue /*: stylelint$standaloneReturnValue*/ = { errored, - output: formatterFunction(stylelintResults), results: stylelintResults, }; + const formatterExtras = {}; + if (reportNeedlessDisables) { - returnValue.needlessDisables = needlessDisables(stylelintResults); + const foundNeedlessDisables = needlessDisables(stylelintResults); + + returnValue.needlessDisables = foundNeedlessDisables; + formatterExtras.needlessDisables = foundNeedlessDisables; } if (reportInvalidScopeDisables) { - returnValue.invalidScopeDisables = invalidScopeDisables( + const foundInvalidScopeDisables = invalidScopeDisables( stylelintResults, // TODO TYPES possible undefined /** @type {import('stylelint').StylelintConfig} */ (stylelint._options.config), ); + + returnValue.invalidScopeDisables = foundInvalidScopeDisables; + formatterExtras.invalidScopeDisables = foundInvalidScopeDisables; } + returnValue.output = formatterFunction(stylelintResults, formatterExtras); + if (maxWarnings !== undefined) { const foundWarnings = stylelintResults.reduce((count, file) => { return count + file.warnings.length; From f006e0205d32de2279e1f9ffea2ccc47882c4139 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Thu, 31 Oct 2019 13:17:22 -0700 Subject: [PATCH 3/8] simplify: pass returnValue to formatter, include maxWarningsExceeded --- lib/standalone.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/lib/standalone.js b/lib/standalone.js index 193edcd66c..9437941b9c 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -297,31 +297,20 @@ module.exports = function( /** @type {StylelintStandaloneReturnValue} */ const returnValue /*: stylelint$standaloneReturnValue*/ = { errored, - results: stylelintResults, }; - const formatterExtras = {}; - if (reportNeedlessDisables) { - const foundNeedlessDisables = needlessDisables(stylelintResults); - - returnValue.needlessDisables = foundNeedlessDisables; - formatterExtras.needlessDisables = foundNeedlessDisables; + returnValue.needlessDisables = needlessDisables(stylelintResults); } if (reportInvalidScopeDisables) { - const foundInvalidScopeDisables = invalidScopeDisables( + returnValue.invalidScopeDisables = invalidScopeDisables( stylelintResults, // TODO TYPES possible undefined /** @type {import('stylelint').StylelintConfig} */ (stylelint._options.config), ); - - returnValue.invalidScopeDisables = foundInvalidScopeDisables; - formatterExtras.invalidScopeDisables = foundInvalidScopeDisables; } - returnValue.output = formatterFunction(stylelintResults, formatterExtras); - if (maxWarnings !== undefined) { const foundWarnings = stylelintResults.reduce((count, file) => { return count + file.warnings.length; @@ -332,6 +321,9 @@ module.exports = function( } } + returnValue.output = formatterFunction(stylelintResults, returnValue); + returnValue.results = stylelintResults; + debug(`Linting complete in ${Date.now() - startTime}ms`); return returnValue; From 1342065db7945206d767743b8852d8eb21e0665e Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Thu, 31 Oct 2019 13:45:24 -0700 Subject: [PATCH 4/8] lint(types): initialize results, output on returnValue --- lib/standalone.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/standalone.js b/lib/standalone.js index 9437941b9c..bb0e10c478 100644 --- a/lib/standalone.js +++ b/lib/standalone.js @@ -297,6 +297,8 @@ module.exports = function( /** @type {StylelintStandaloneReturnValue} */ const returnValue /*: stylelint$standaloneReturnValue*/ = { errored, + results: [], + output: '', }; if (reportNeedlessDisables) { From b318ea1424ba007aa6864f3329bbddbd953e5119 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 5 Nov 2019 13:42:13 -0800 Subject: [PATCH 5/8] fix: use CSS comment in standalone formatter test --- lib/__tests__/standalone-formatter.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/__tests__/standalone-formatter.test.js b/lib/__tests__/standalone-formatter.test.js index ee09dcf279..87dd0b8a81 100644 --- a/lib/__tests__/standalone-formatter.test.js +++ b/lib/__tests__/standalone-formatter.test.js @@ -58,7 +58,7 @@ it('standalone formatter receives {needlessDisables} as second argument', () => return standalone({ code: ` - // stylelint-disable yo + /* stylelint-disable yo */ a {} `, config: configBlockNoEmpty, From 2982fa1fbdd9b0bfcb61d564acaf0dad56e4547b Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 5 Nov 2019 13:54:29 -0800 Subject: [PATCH 6/8] docs: describe formatter function signature + args --- docs/developer-guide/formatters.md | 43 +++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/developer-guide/formatters.md b/docs/developer-guide/formatters.md index 246ddbfd45..d1c7553fd1 100644 --- a/docs/developer-guide/formatters.md +++ b/docs/developer-guide/formatters.md @@ -1,6 +1,12 @@ # Writing formatters -A formatter is a function that accepts *an array of these stylelint result objects* and outputs a string: +A formatter is a function with the following signature: + +```js +formatter(results, returnValue) +``` + +Where the first argument (`results`) is an array of stylelint result objects in the form: ```js // A stylelint result object @@ -32,6 +38,41 @@ A formatter is a function that accepts *an array of these stylelint result objec } ``` +And the second argument (`returnValue`) is an object with one or more of the following keys: + +```js +{ + // true if there were any warnings with "error" severity + errored: false, + + // set if stylelint was configured with {reportNeedlessDisables: true} + needlessDisables: [ + { + source: "path/to/filename.css", + ranges: [ + {start: 10, unusedRule: 'indentation'} + ] + } + ], + + // set if stylelint was configured with {reportInvalidScopeDisables: true} + invalidScopeDisables: [ + { + source: "path/to/filename.css", + ranges: [ + {start: 1, unusedRule: 'color-named'} + ] + } + ], + + // set if stylelint was configured with a maxWarnings count, e.g. {maxWarnings: 10} + maxWarningsExceeded: { + maxWarnings: 10, + foundWarnings: 15 + } +} +``` + ## `stylelint.formatters` stylelint's internal formatters are exposed publicly in `stylelint.formatters`. From a0d26849526cb7514e8a80a7f9656c3ce37d9593 Mon Sep 17 00:00:00 2001 From: Shawn Allen Date: Tue, 5 Nov 2019 13:56:35 -0800 Subject: [PATCH 7/8] docs: add string return value to formatter sig --- docs/developer-guide/formatters.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/developer-guide/formatters.md b/docs/developer-guide/formatters.md index d1c7553fd1..8e7160903c 100644 --- a/docs/developer-guide/formatters.md +++ b/docs/developer-guide/formatters.md @@ -3,7 +3,9 @@ A formatter is a function with the following signature: ```js -formatter(results, returnValue) +formatter(results, returnValue) { + return 'a string of formatted results' +} ``` Where the first argument (`results`) is an array of stylelint result objects in the form: From 772dc8bacd66df064ca04e2898493ae639fadca9 Mon Sep 17 00:00:00 2001 From: Aleks Hudochenkov Date: Tue, 5 Nov 2019 23:06:01 +0100 Subject: [PATCH 8/8] Update formatting --- docs/developer-guide/formatters.md | 33 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/docs/developer-guide/formatters.md b/docs/developer-guide/formatters.md index 8e7160903c..8f64eb91fe 100644 --- a/docs/developer-guide/formatters.md +++ b/docs/developer-guide/formatters.md @@ -3,8 +3,8 @@ A formatter is a function with the following signature: ```js -formatter(results, returnValue) { - return 'a string of formatted results' +function formatter(results, returnValue) { + return "a string of formatted results"; } ``` @@ -44,31 +44,30 @@ And the second argument (`returnValue`) is an object with one or more of the fol ```js { - // true if there were any warnings with "error" severity - errored: false, - - // set if stylelint was configured with {reportNeedlessDisables: true} - needlessDisables: [ + errored: false, // `true` if there were any warnings with "error" severity + needlessDisables: [ // Present if stylelint was configured with `reportNeedlessDisables: true` { - source: "path/to/filename.css", + source: "path/to/file.css", ranges: [ - {start: 10, unusedRule: 'indentation'} + { + start: 10, + unusedRule: "indentation" + } ] } ], - - // set if stylelint was configured with {reportInvalidScopeDisables: true} - invalidScopeDisables: [ + invalidScopeDisables: [ // Present if stylelint was configured with `reportInvalidScopeDisables: true` { - source: "path/to/filename.css", + source: "path/to/file.css", ranges: [ - {start: 1, unusedRule: 'color-named'} + { + start: 1, + unusedRule: "color-named" + } ] } ], - - // set if stylelint was configured with a maxWarnings count, e.g. {maxWarnings: 10} - maxWarningsExceeded: { + maxWarningsExceeded: { // Present if stylelint was configured with a `maxWarnings` count maxWarnings: 10, foundWarnings: 15 }