diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f9c7cb1..c72009c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - Language server can now be restarted with the "Restart Stylelint Server" command ([#339](https://github.com/stylelint/vscode-stylelint/pull/339)). - The warning shown for unsupported versions of Stylelint will now be shown in any workspace with a locally installed copy of Stylelint, regardless of the file type of the open file ([#340](https://github.com/stylelint/vscode-stylelint/pull/340)). - Language server can now be disposed with `server.dispose()` and is disposed when receiving the shutdown LSP notification ([#326](https://github.com/stylelint/vscode-stylelint/pull/326)). +- Add support for range warnings ([#358](https://github.com/stylelint/vscode-stylelint/pull/358)). ### Changed diff --git a/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.ts.snap b/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.ts.snap index eb93330a..51b53eb5 100644 --- a/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.ts.snap +++ b/src/utils/stylelint/__tests__/__snapshots__/stylelint-runner.ts.snap @@ -31,7 +31,7 @@ Object { "message": "Unexpected empty block (block-no-empty)", "range": Object { "end": Object { - "character": 3, + "character": 4, "line": 0, }, "start": Object { diff --git a/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.ts.snap b/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.ts.snap index 0d9a8b2e..3bd2e790 100644 --- a/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.ts.snap +++ b/src/utils/stylelint/__tests__/__snapshots__/warning-to-diagnostic.ts.snap @@ -47,7 +47,7 @@ Object { "message": "Expected \\"#bbbbbb\\" to be \\"#bbb\\" (color-hex-length)", "range": Object { "end": Object { - "character": 19, + "character": 25, "line": 2, }, "start": Object { diff --git a/src/utils/stylelint/warning-to-diagnostic.ts b/src/utils/stylelint/warning-to-diagnostic.ts index 22b39104..7d773e51 100644 --- a/src/utils/stylelint/warning-to-diagnostic.ts +++ b/src/utils/stylelint/warning-to-diagnostic.ts @@ -46,7 +46,10 @@ export function warningToDiagnostic( ruleMetadata?: stylelint.LinterResult['ruleMetadata'], ): Diagnostic { const start = Position.create(warning.line - 1, warning.column - 1); - const end = Position.create(warning.line - 1, warning.column); + const end = + typeof warning.endLine === 'number' && typeof warning.endColumn === 'number' + ? Position.create(warning.endLine - 1, warning.endColumn - 1) + : Position.create(warning.line - 1, warning.column); const ruleDocUrl = ruleMetadata?.[warning.rule]?.url; diff --git a/test/e2e/__tests__/__snapshots__/code-actions.ts.snap b/test/e2e/__tests__/__snapshots__/code-actions.ts.snap index 9386e0f7..9cb0cf8e 100644 --- a/test/e2e/__tests__/__snapshots__/code-actions.ts.snap +++ b/test/e2e/__tests__/__snapshots__/code-actions.ts.snap @@ -19,6 +19,20 @@ exports[`Code actions should disable rules for a specific line with a comment on " `; +exports[`Code actions should disable rules for a specific line with a comment on the same line 2`] = ` +"#!/usr/bin/env node +/* stylelint-disable color-no-invalid-hex */ +/* eslint-disable node/shebang */ +'use strict'; + +const css = css\` + .foo { + color: #00; + } +\`; +" +`; + exports[`Code actions should disable rules for an entire file 1`] = ` "/* stylelint-disable indentation */ a { diff --git a/test/e2e/__tests__/__snapshots__/config-basedir.ts.snap b/test/e2e/__tests__/__snapshots__/config-basedir.ts.snap index 0e760b25..df058eb5 100644 --- a/test/e2e/__tests__/__snapshots__/config-basedir.ts.snap +++ b/test/e2e/__tests__/__snapshots__/config-basedir.ts.snap @@ -29,7 +29,7 @@ Array [ "message": "Expected indentation of 8 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 14, "line": 1, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/config-file.ts.snap b/test/e2e/__tests__/__snapshots__/config-file.ts.snap index d39f18fc..04c1a47f 100644 --- a/test/e2e/__tests__/__snapshots__/config-file.ts.snap +++ b/test/e2e/__tests__/__snapshots__/config-file.ts.snap @@ -10,7 +10,7 @@ Array [ "message": "Unexpected empty block (block-no-empty)", "range": Object { "end": Object { - "character": 3, + "character": 4, "line": 0, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/ignore-disables.ts.snap b/test/e2e/__tests__/__snapshots__/ignore-disables.ts.snap index b59647d6..fa82bc8d 100644 --- a/test/e2e/__tests__/__snapshots__/ignore-disables.ts.snap +++ b/test/e2e/__tests__/__snapshots__/ignore-disables.ts.snap @@ -29,7 +29,7 @@ Array [ "message": "Expected indentation of 4 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 14, "line": 3, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/lint.ts.snap b/test/e2e/__tests__/__snapshots__/lint.ts.snap index 2ae3651c..5755060d 100644 --- a/test/e2e/__tests__/__snapshots__/lint.ts.snap +++ b/test/e2e/__tests__/__snapshots__/lint.ts.snap @@ -26,7 +26,7 @@ Array [ "message": "Unexpected invalid hex color \\"#y3\\" (color-no-invalid-hex)", "range": Object { "end": Object { - "character": 12, + "character": 14, "line": 6, }, "start": Object { @@ -45,7 +45,7 @@ Array [ "message": "Expected indentation of 4 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 13, "line": 2, }, "start": Object { @@ -69,7 +69,7 @@ Array [ "message": "Expected indentation of 4 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 13, "line": 2, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/report-descriptionless-disables.ts.snap b/test/e2e/__tests__/__snapshots__/report-descriptionless-disables.ts.snap index 602fefad..7f1d464a 100644 --- a/test/e2e/__tests__/__snapshots__/report-descriptionless-disables.ts.snap +++ b/test/e2e/__tests__/__snapshots__/report-descriptionless-disables.ts.snap @@ -7,7 +7,7 @@ Array [ "message": "Disable for \\"indentation\\" is missing a description", "range": Object { "end": Object { - "character": 5, + "character": 48, "line": 2, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/report-invalid-scope-disables.ts.snap b/test/e2e/__tests__/__snapshots__/report-invalid-scope-disables.ts.snap index e2b55eef..326ae8ed 100644 --- a/test/e2e/__tests__/__snapshots__/report-invalid-scope-disables.ts.snap +++ b/test/e2e/__tests__/__snapshots__/report-invalid-scope-disables.ts.snap @@ -7,7 +7,7 @@ Array [ "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 36, "line": 0, }, "start": Object { @@ -23,7 +23,7 @@ Array [ "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 31, "line": 2, }, "start": Object { @@ -39,7 +39,7 @@ Array [ "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 26, "line": 4, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/report-needless-disables.ts.snap b/test/e2e/__tests__/__snapshots__/report-needless-disables.ts.snap index 5bf7aa0e..65f56e01 100644 --- a/test/e2e/__tests__/__snapshots__/report-needless-disables.ts.snap +++ b/test/e2e/__tests__/__snapshots__/report-needless-disables.ts.snap @@ -7,7 +7,7 @@ Array [ "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 3, + "character": 55, "line": 2, }, "start": Object { @@ -23,7 +23,7 @@ Array [ "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 1, + "character": 34, "line": 6, }, "start": Object { @@ -39,7 +39,7 @@ Array [ "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 17, + "character": 55, "line": 14, }, "start": Object { @@ -55,7 +55,7 @@ Array [ "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 1, + "character": 34, "line": 17, }, "start": Object { @@ -71,7 +71,7 @@ Array [ "message": "Needless disable for \\"unknown\\"", "range": Object { "end": Object { - "character": 3, + "character": 55, "line": 2, }, "start": Object { diff --git a/test/e2e/__tests__/__snapshots__/validate.ts.snap b/test/e2e/__tests__/__snapshots__/validate.ts.snap index 8827f0d1..560d6bc4 100644 --- a/test/e2e/__tests__/__snapshots__/validate.ts.snap +++ b/test/e2e/__tests__/__snapshots__/validate.ts.snap @@ -10,7 +10,7 @@ Array [ "message": "Expected indentation of 4 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 13, "line": 2, }, "start": Object { diff --git a/test/integration/stylelint-vscode/__snapshots__/test.ts.snap b/test/integration/stylelint-vscode/__snapshots__/test.ts.snap index 06849453..d14ca119 100644 --- a/test/integration/stylelint-vscode/__snapshots__/test.ts.snap +++ b/test/integration/stylelint-vscode/__snapshots__/test.ts.snap @@ -1,29 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`StylelintRunner should be resolved with diagnostic plugin rule URL 1`] = ` -Array [ - Object { - "code": "scss/at-rule-no-unknown", - "codeDescription": Object { - "href": "https://github.com/stylelint-scss/stylelint-scss/blob/master/src/rules/at-rule-no-unknown", - }, - "message": "Unexpected unknown at-rule \\"@unknown\\" (scss/at-rule-no-unknown)", - "range": Object { - "end": Object { - "character": 1, - "line": 0, - }, - "start": Object { - "character": 0, - "line": 0, - }, - }, - "severity": 1, - "source": "Stylelint", - }, -] -`; - exports[`StylelintRunner should be resolved with diagnostics when it lints CSS successfully 1`] = ` Array [ Object { @@ -53,7 +29,7 @@ Array [ "message": "Expected indentation of 0 tabs (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 14, "line": 0, }, "start": Object { @@ -74,7 +50,7 @@ Array [ "message": "Unknown rule this-rule-does-not-exist.", "range": Object { "end": Object { - "character": 1, + "character": 4, "line": 0, }, "start": Object { @@ -90,7 +66,7 @@ Array [ "message": "Unknown rule this-rule-also-does-not-exist.", "range": Object { "end": Object { - "character": 1, + "character": 4, "line": 0, }, "start": Object { @@ -182,7 +158,7 @@ Array [ "message": "Expected \\"bold\\" to be \\"700\\" (font-weight-notation)", "range": Object { "end": Object { - "character": 30, + "character": 33, "line": 2, }, "start": Object { @@ -201,7 +177,7 @@ Array [ "message": "Expected \\"normal\\" to be \\"400\\" (font-weight-notation)", "range": Object { "end": Object { - "character": 7, + "character": 12, "line": 4, }, "start": Object { @@ -225,7 +201,7 @@ Array [ "message": "Unexpected unit (length-zero-no-unit)", "range": Object { "end": Object { - "character": 11, + "character": 12, "line": 3, }, "start": Object { @@ -250,7 +226,7 @@ Object { "message": "Unexpected unknown type selector \\"unknown\\" (selector-type-no-unknown)", "range": Object { "end": Object { - "character": 1, + "character": 7, "line": 1, }, "start": Object { @@ -306,7 +282,7 @@ Object { "message": "Expected indentation of 2 spaces (indentation)", "range": Object { "end": Object { - "character": 4, + "character": 12, "line": 1, }, "start": Object { @@ -329,7 +305,7 @@ Object { "message": "Disable for \\"indentation\\" is missing a description", "range": Object { "end": Object { - "character": 5, + "character": 48, "line": 2, }, "start": Object { @@ -345,7 +321,7 @@ Object { "message": "Disable for \\"indentation\\" is missing a description", "range": Object { "end": Object { - "character": 1, + "character": 34, "line": 5, }, "start": Object { @@ -361,7 +337,7 @@ Object { "message": "Disable for \\"indentation\\" is missing a description", "range": Object { "end": Object { - "character": 15, + "character": 53, "line": 11, }, "start": Object { @@ -384,7 +360,7 @@ Object { "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 36, "line": 1, }, "start": Object { @@ -400,7 +376,7 @@ Object { "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 31, "line": 3, }, "start": Object { @@ -416,7 +392,7 @@ Object { "message": "Rule \\"foo\\" isn't enabled", "range": Object { "end": Object { - "character": 1, + "character": 26, "line": 5, }, "start": Object { @@ -442,7 +418,7 @@ Object { "message": "Expected indentation of 4 spaces (indentation)", "range": Object { "end": Object { - "character": 3, + "character": 47, "line": 2, }, "start": Object { @@ -458,7 +434,7 @@ Object { "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 3, + "character": 46, "line": 2, }, "start": Object { @@ -474,7 +450,7 @@ Object { "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 1, + "character": 34, "line": 6, }, "start": Object { @@ -490,7 +466,7 @@ Object { "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 17, + "character": 55, "line": 13, }, "start": Object { @@ -506,7 +482,7 @@ Object { "message": "Needless disable for \\"indentation\\"", "range": Object { "end": Object { - "character": 1, + "character": 34, "line": 16, }, "start": Object { @@ -555,7 +531,7 @@ Object { "message": "Expected indentation of 2 spaces (indentation)", "range": Object { "end": Object { - "character": 4, + "character": 12, "line": 1, }, "start": Object { diff --git a/test/integration/stylelint-vscode/test.ts b/test/integration/stylelint-vscode/test.ts index 36e2e651..a3bcb9d9 100644 --- a/test/integration/stylelint-vscode/test.ts +++ b/test/integration/stylelint-vscode/test.ts @@ -3,6 +3,7 @@ import { pathToFileURL } from 'url'; import { TextDocument } from 'vscode-languageserver-textdocument'; import { StylelintRunner } from '../../../src/utils/stylelint'; import { version as stylelintVersion } from 'stylelint/package.json'; +import { version as stylelintScssVersion } from 'stylelint-scss/package.json'; import semver from 'semver'; const createDocument = (uri: string | null, languageId: string, contents: string): TextDocument => @@ -264,23 +265,45 @@ a { color: #000 } expect(result.diagnostics).toMatchSnapshot(); }); - test('should be resolved with diagnostic plugin rule URL', async () => { - expect.assertions(1); - const runner = new StylelintRunner(); - const result = await runner.lintDocument( - createDocument('unknown-rule.scss', 'scss', '@unknown (max-width: 960px) {}'), - { - config: { - plugins: ['stylelint-scss'], - rules: { - 'scss/at-rule-no-unknown': true, + if (semver.satisfies(stylelintScssVersion, '^15')) { + test('should be resolved with diagnostic plugin rule URL', async () => { + expect.assertions(1); + const runner = new StylelintRunner(); + const result = await runner.lintDocument( + createDocument('unknown-rule.scss', 'scss', '@unknown (max-width: 960px) {}'), + { + config: { + plugins: ['stylelint-scss'], + rules: { + 'scss/at-rule-no-unknown': true, + }, }, }, - }, - ); + ); - expect(result.diagnostics).toMatchSnapshot(); - }); + expect(result.diagnostics).toEqual([ + { + code: 'scss/at-rule-no-unknown', + codeDescription: { + href: 'https://github.com/stylelint-scss/stylelint-scss/blob/master/src/rules/at-rule-no-unknown', + }, + message: 'Unexpected unknown at-rule "@unknown" (scss/at-rule-no-unknown)', + range: { + end: { + character: 8, + line: 0, + }, + start: { + character: 0, + line: 0, + }, + }, + severity: 1, + source: 'Stylelint', + }, + ]); + }); + } }); describe('StylelintRunner with a configuration file', () => {