From 5d60812d440762dff72420714273c714c4c5d074 Mon Sep 17 00:00:00 2001 From: Yiwei Ding <87166810+Yiwei-Ding@users.noreply.github.com> Date: Fri, 28 Jan 2022 06:49:06 +0800 Subject: [PATCH] feat: implement rfc 2021-suppression-support (#15459) * feat: implement rfc 2021-suppression-support * fix --report-unused-disable-directives not working in some cases. * modify the JSDoc comments of applyDirectives(). * fix not working with processors * update the return type of _verifyXX methods * fix the issue that only string after the first -- is treated as justification * fix eslint-disable-next-line not working after /* eslint-disable */ * refactor applyDirectives() to process usedDisableDirectives properly * fix another unused-disable-directive issue, and add more test cases to cover * apply the simpler implementation of applyDirective() * update doc * filter out suppressedMessages in getErrorResults() * add meta for rules in suppressedMessages for getRulesMetaForResults() * update ESLint.getErrorResults() to keep the current behavior --- docs/developer-guide/nodejs-api.md | 47 + lib/cli-engine/cli-engine.js | 6 + lib/eslint/eslint.js | 5 + lib/linter/apply-disable-directives.js | 79 +- lib/linter/linter.js | 107 +- lib/shared/types.js | 15 + tests/bin/eslint.js | 1 + tests/lib/cli-engine/cli-engine.js | 154 +- tests/lib/eslint/eslint.js | 30 + tests/lib/linter/apply-disable-directives.js | 588 +++++-- tests/lib/linter/linter.js | 1552 +++++++++++++++++- 11 files changed, 2277 insertions(+), 307 deletions(-) diff --git a/docs/developer-guide/nodejs-api.md b/docs/developer-guide/nodejs-api.md index 0bce3055519..826e012ae70 100644 --- a/docs/developer-guide/nodejs-api.md +++ b/docs/developer-guide/nodejs-api.md @@ -19,6 +19,7 @@ While ESLint is designed to be run on the command line, it's possible to use ESL * [static getErrorResults()][eslint-geterrorresults] * [LintResult type][lintresult] * [LintMessage type][lintmessage] + * [SuppressedLintMessage type][suppressedlintmessage] * [EditInfo type][editinfo] * [Formatter type][formatter] * [SourceCode](#sourcecode) @@ -347,6 +348,8 @@ The `LintResult` value is the information of the linting result of each file. Th The absolute path to the file of this result. This is the string `""` if the file path is unknown (when you didn't pass the `options.filePath` option to the [`eslint.lintText()`][eslint-linttext] method). * `messages` (`LintMessage[]`)
The array of [LintMessage] objects. +* `suppressedMessages` (`SuppressedLintMessage[]`)
+ The array of [SuppressedLintMessage] objects. * `fixableErrorCount` (`number`)
The number of errors that can be fixed automatically by the `fix` constructor option. * `fixableWarningCount` (`number`)
@@ -389,6 +392,33 @@ The `LintMessage` value is the information of each linting error. The `messages` * `suggestions` (`{ desc: string; fix: EditInfo }[] | undefined`)
The list of suggestions. Each suggestion is the pair of a description and an [EditInfo] object to fix code. API users such as editor integrations can choose one of them to fix the problem of this message. This property is undefined if this message doesn't have any suggestions. +### ◆ SuppressedLintMessage type + +The `SuppressedLintMessage` value is the information of each suppressed linting error. The `suppressedMessages` property of the [LintResult] type contains it. It has the following properties: + +* `ruleId` (`string` | `null`)
+ Same as `ruleId` in [LintMessage] type. +* `severity` (`1 | 2`)
+ Same as `severity` in [LintMessage] type. +* `fatal` (`boolean | undefined`)
+ Same as `fatal` in [LintMessage] type. +* `message` (`string`)
+ Same as `message` in [LintMessage] type. +* `line` (`number | undefined`)
+ Same as `line` in [LintMessage] type. +* `column` (`number | undefined`)
+ Same as `column` in [LintMessage] type. +* `endLine` (`number | undefined`)
+ Same as `endLine` in [LintMessage] type. +* `endColumn` (`number | undefined`)
+ Same as `endColumn` in [LintMessage] type. +* `fix` (`EditInfo | undefined`)
+ Same as `fix` in [LintMessage] type. +* `suggestions` (`{ desc: string; fix: EditInfo }[] | undefined`)
+ Same as `suggestions` in [LintMessage] type. +* `suppressions` (`{ kind: string; justification: string}[]`)
+ The list of suppressions. Each suppression is the pair of a kind and a justification. + ### ◆ EditInfo type The `EditInfo` value is information to edit text. The `fix` and `suggestions` properties of [LintMessage] type contain it. It has following properties: @@ -551,6 +581,22 @@ The information available for each linting message is: * `fix` - an object describing the fix for the problem (this property is omitted if no fix is available). * `suggestions` - an array of objects describing possible lint fixes for editors to programmatically enable (see details in the [Working with Rules docs](./working-with-rules.md#providing-suggestions)). +You can get the suppressed messages from the previous run by `getSuppressedMessages()` method. If there is not a previous run, `getSuppressedMessage()` will return an empty list. + +```js +const Linter = require("eslint").Linter; +const linter = new Linter(); + +const messages = linter.verify("var foo = bar; // eslint-disable-line -- Need to suppress", { + rules: { + semi: ["error", "never"] + } +}, { filename: "foo.js" }); +const suppressedMessages = linter.getSuppressedMessages(); + +console.log(suppressedMessages[0].suppressions); // [{ "kind": "directive", "justification": "Need to suppress" }] +``` + Linting message objects have a deprecated `source` property. This property **will be removed** from linting messages in an upcoming breaking release. If you depend on this property, you should now use the `SourceCode` instance provided by the linter. You can also get an instance of the `SourceCode` object used inside of `linter` by using the `getSourceCode()` method: @@ -912,6 +958,7 @@ ruleTester.run("my-rule", myRule, { [eslint-geterrorresults]: #-eslintgeterrorresultsresults [lintresult]: #-lintresult-type [lintmessage]: #-lintmessage-type +[suppressedlintmessage]: #-suppressedlintmessage-type [editinfo]: #-editinfo-type [formatter]: #-formatter-type [linter]: #linter diff --git a/lib/cli-engine/cli-engine.js b/lib/cli-engine/cli-engine.js index 0aff182f0ff..3ae8b685cf3 100644 --- a/lib/cli-engine/cli-engine.js +++ b/lib/cli-engine/cli-engine.js @@ -51,6 +51,7 @@ const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]); /** @typedef {import("../shared/types").ConfigData} ConfigData */ /** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ /** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */ /** @typedef {import("../shared/types").ParserOptions} ParserOptions */ /** @typedef {import("../shared/types").Plugin} Plugin */ /** @typedef {import("../shared/types").RuleConf} RuleConf */ @@ -91,6 +92,7 @@ const validFixTypes = new Set(["directive", "problem", "suggestion", "layout"]); * @typedef {Object} LintResult * @property {string} filePath The path to the file that was linted. * @property {LintMessage[]} messages All of the messages for the result. + * @property {SuppressedLintMessage[]} suppressedMessages All of the suppressed messages for the result. * @property {number} errorCount Number of errors for the result. * @property {number} fatalErrorCount Number of fatal errors for the result. * @property {number} warningCount Number of warnings for the result. @@ -263,6 +265,7 @@ function verifyText({ const result = { filePath, messages, + suppressedMessages: linter.getSuppressedMessages(), ...calculateStatsPerFile(messages) }; @@ -309,6 +312,7 @@ function createIgnoreResult(filePath, baseDir) { message } ], + suppressedMessages: [], errorCount: 0, fatalErrorCount: 0, warningCount: 1, @@ -683,11 +687,13 @@ class CLIEngine { results.forEach(result => { const filteredMessages = result.messages.filter(isErrorMessage); + const filteredSuppressedMessages = result.suppressedMessages.filter(isErrorMessage); if (filteredMessages.length > 0) { filtered.push({ ...result, messages: filteredMessages, + suppressedMessages: filteredSuppressedMessages, errorCount: filteredMessages.length, warningCount: 0, fixableErrorCount: result.fixableErrorCount, diff --git a/lib/eslint/eslint.js b/lib/eslint/eslint.js index ee6b2ef456b..1e5a8f8b13f 100644 --- a/lib/eslint/eslint.js +++ b/lib/eslint/eslint.js @@ -32,6 +32,7 @@ const { version } = require("../../package.json"); /** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ /** @typedef {import("../shared/types").ConfigData} ConfigData */ /** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */ /** @typedef {import("../shared/types").Plugin} Plugin */ /** @typedef {import("../shared/types").Rule} Rule */ @@ -78,6 +79,7 @@ const { version } = require("../../package.json"); * @typedef {Object} LintResult * @property {string} filePath The path to the file that was linted. * @property {LintMessage[]} messages All of the messages for the result. + * @property {SuppressedLintMessage[]} suppressedMessages All of the suppressed messages for the result. * @property {number} errorCount Number of errors for the result. * @property {number} fatalErrorCount Number of fatal errors for the result. * @property {number} warningCount Number of warnings for the result. @@ -526,6 +528,9 @@ class ESLint { for (const { ruleId } of result.messages) { resultRuleIds.add(ruleId); } + for (const { ruleId } of result.suppressedMessages) { + resultRuleIds.add(ruleId); + } } // create a map of all rules in the results diff --git a/lib/linter/apply-disable-directives.js b/lib/linter/apply-disable-directives.js index f6b432399cf..f8e4aeedb29 100644 --- a/lib/linter/apply-disable-directives.js +++ b/lib/linter/apply-disable-directives.js @@ -197,62 +197,52 @@ function processUnusedDisableDirectives(allDirectives) { * for the exported function, except that `reportUnusedDisableDirectives` is not supported * (this function always reports unused disable directives). * @returns {{problems: Problem[], unusedDisableDirectives: Problem[]}} An object with a list - * of filtered problems and unused eslint-disable directives + * of problems (including suppressed ones) and unused eslint-disable directives */ function applyDirectives(options) { const problems = []; - let nextDirectiveIndex = 0; - let currentGlobalDisableDirective = null; - const disabledRuleMap = new Map(); - - // enabledRules is only used when there is a current global disable directive. - const enabledRules = new Set(); const usedDisableDirectives = new Set(); for (const problem of options.problems) { + let disableDirectivesForProblem = []; + let nextDirectiveIndex = 0; + while ( nextDirectiveIndex < options.directives.length && compareLocations(options.directives[nextDirectiveIndex], problem) <= 0 ) { const directive = options.directives[nextDirectiveIndex++]; - switch (directive.type) { - case "disable": - if (directive.ruleId === null) { - currentGlobalDisableDirective = directive; - disabledRuleMap.clear(); - enabledRules.clear(); - } else if (currentGlobalDisableDirective) { - enabledRules.delete(directive.ruleId); - disabledRuleMap.set(directive.ruleId, directive); - } else { - disabledRuleMap.set(directive.ruleId, directive); - } - break; - - case "enable": - if (directive.ruleId === null) { - currentGlobalDisableDirective = null; - disabledRuleMap.clear(); - } else if (currentGlobalDisableDirective) { - enabledRules.add(directive.ruleId); - disabledRuleMap.delete(directive.ruleId); - } else { - disabledRuleMap.delete(directive.ruleId); - } - break; - - // no default + if (directive.ruleId === null || directive.ruleId === problem.ruleId) { + switch (directive.type) { + case "disable": + disableDirectivesForProblem.push(directive); + break; + + case "enable": + disableDirectivesForProblem = []; + break; + + // no default + } } } - if (disabledRuleMap.has(problem.ruleId)) { - usedDisableDirectives.add(disabledRuleMap.get(problem.ruleId)); - } else if (currentGlobalDisableDirective && !enabledRules.has(problem.ruleId)) { - usedDisableDirectives.add(currentGlobalDisableDirective); - } else { - problems.push(problem); + if (disableDirectivesForProblem.length > 0) { + const suppressions = disableDirectivesForProblem.map(directive => ({ + kind: "directive", + justification: directive.unprocessedDirective.justification + })); + + if (problem.suppressions) { + problem.suppressions = problem.suppressions.concat(suppressions); + } else { + problem.suppressions = suppressions; + usedDisableDirectives.add(disableDirectivesForProblem[disableDirectivesForProblem.length - 1]); + } } + + problems.push(problem); } const unusedDisableDirectivesToReport = options.directives @@ -282,13 +272,14 @@ function applyDirectives(options) { /** * Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list - * of reported problems, determines which problems should be reported. + * of reported problems, adds the suppression information to the problems. * @param {Object} options Information about directives and problems * @param {{ * type: ("disable"|"enable"|"disable-line"|"disable-next-line"), * ruleId: (string|null), * line: number, - * column: number + * column: number, + * justification: string * }} options.directives Directive comments found in the file, with one-based columns. * Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable * comment for two different rules is represented as two directives). @@ -296,8 +287,8 @@ function applyDirectives(options) { * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns. * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives * @param {boolean} options.disableFixes If true, it doesn't make `fix` properties. - * @returns {{ruleId: (string|null), line: number, column: number}[]} - * A list of reported problems that were not disabled by the directive comments. + * @returns {{ruleId: (string|null), line: number, column: number, suppressions?: {kind: string, justification: string}}[]} + * An object with a list of reported problems, the suppressed of which contain the suppression information. */ module.exports = ({ directives, disableFixes, problems, reportUnusedDisableDirectives = "off" }) => { const blockDirectives = directives diff --git a/lib/linter/linter.js b/lib/linter/linter.js index 056f9cec98e..9b9f4919207 100644 --- a/lib/linter/linter.js +++ b/lib/linter/linter.js @@ -59,6 +59,7 @@ const globals = require("../../conf/globals"); /** @typedef {import("../shared/types").Environment} Environment */ /** @typedef {import("../shared/types").GlobalConf} GlobalConf */ /** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */ /** @typedef {import("../shared/types").ParserOptions} ParserOptions */ /** @typedef {import("../shared/types").LanguageOptions} LanguageOptions */ /** @typedef {import("../shared/types").Processor} Processor */ @@ -77,6 +78,7 @@ const globals = require("../../conf/globals"); * @property {number} line The line number * @property {number} column The column number * @property {(string|null)} ruleId The rule ID + * @property {string} justification The justification of directive */ /** @@ -84,6 +86,7 @@ const globals = require("../../conf/globals"); * @typedef {Object} LinterInternalSlots * @property {ConfigArray|null} lastConfigArray The `ConfigArray` instance that the last `verify()` call used. * @property {SourceCode|null} lastSourceCode The `SourceCode` instance that the last `verify()` call used. + * @property {SuppressedLintMessage[]} lastSuppressedMessages The `SuppressedLintMessage[]` instance that the last `verify()` call produced. * @property {Map} parserMap The loaded parsers. * @property {Rules} ruleMap The loaded rules. */ @@ -287,11 +290,12 @@ function createLintingProblem(options) { * @param {token} options.commentToken The Comment token * @param {string} options.value The value after the directive in the comment * comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`) + * @param {string} options.justification The justification of the directive * @param {function(string): {create: Function}} options.ruleMapper A map from rule IDs to defined rules * @returns {Object} Directives and problems from the comment */ function createDisableDirectives(options) { - const { commentToken, type, value, ruleMapper } = options; + const { commentToken, type, value, justification, ruleMapper } = options; const ruleIds = Object.keys(commentParser.parseListConfig(value)); const directiveRules = ruleIds.length ? ruleIds : [null]; const result = { @@ -306,9 +310,23 @@ function createDisableDirectives(options) { // push to directives, if the rule is defined(including null, e.g. /*eslint enable*/) if (ruleId === null || !!ruleMapper(ruleId)) { if (type === "disable-next-line") { - result.directives.push({ parentComment, type, line: commentToken.loc.end.line, column: commentToken.loc.end.column + 1, ruleId }); + result.directives.push({ + parentComment, + type, + line: commentToken.loc.end.line, + column: commentToken.loc.end.column + 1, + ruleId, + justification + }); } else { - result.directives.push({ parentComment, type, line: commentToken.loc.start.line, column: commentToken.loc.start.column + 1, ruleId }); + result.directives.push({ + parentComment, + type, + line: commentToken.loc.start.line, + column: commentToken.loc.start.column + 1, + ruleId, + justification + }); } } else { result.directiveProblems.push(createLintingProblem({ ruleId, loc: commentToken.loc })); @@ -318,12 +336,21 @@ function createDisableDirectives(options) { } /** - * Remove the ignored part from a given directive comment and trim it. - * @param {string} value The comment text to strip. - * @returns {string} The stripped text. + * Extract the directive and the justification from a given directive comment and trim them. + * @param {string} value The comment text to extract. + * @returns {{directivePart: string, justificationPart: string}} The extracted directive and justification. */ -function stripDirectiveComment(value) { - return value.split(/\s-{2,}\s/u)[0].trim(); +function extractDirectiveComment(value) { + const match = /\s-{2,}\s/u.exec(value); + + if (!match) { + return { directivePart: value.trim(), justificationPart: "" }; + } + + const directive = value.slice(0, match.index).trim(); + const justification = value.slice(match.index + match[0].length).trim(); + + return { directivePart: directive, justificationPart: justification }; } /** @@ -347,8 +374,9 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) { }); ast.comments.filter(token => token.type !== "Shebang").forEach(comment => { - const trimmedCommentText = stripDirectiveComment(comment.value); - const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText); + const { directivePart, justificationPart } = extractDirectiveComment(comment.value); + + const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(directivePart); if (!match) { return; @@ -383,7 +411,7 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) { return; } - const directiveValue = trimmedCommentText.slice(match.index + directiveText.length); + const directiveValue = directivePart.slice(match.index + directiveText.length); switch (directiveText) { case "eslint-disable": @@ -391,7 +419,7 @@ function getDirectiveComments(ast, ruleMapper, warnInlineConfig) { case "eslint-disable-next-line": case "eslint-disable-line": { const directiveType = directiveText.slice("eslint-".length); - const options = { commentToken: comment, type: directiveType, value: directiveValue, ruleMapper }; + const options = { commentToken: comment, type: directiveType, value: directiveValue, justification: justificationPart, ruleMapper }; const { directives, directiveProblems } = createDisableDirectives(options); disableDirectives.push(...directives); @@ -548,7 +576,7 @@ function findEslintEnv(text) { if (match[0].endsWith("*/")) { retv = Object.assign( retv || {}, - commentParser.parseListConfig(stripDirectiveComment(match[1])) + commentParser.parseListConfig(extractDirectiveComment(match[1]).directivePart) ); } } @@ -1223,6 +1251,7 @@ class Linter { cwd: normalizeCwd(cwd), lastConfigArray: null, lastSourceCode: null, + lastSuppressedMessages: [], configType, // TODO: Remove after flat config conversion parserMap: new Map([["espree", espree]]), ruleMap: new Rules() @@ -1246,7 +1275,7 @@ class Linter { * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything. * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. * @throws {Error} If during rule execution. - * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. + * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages. */ _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { const slots = internalSlotsMap.get(this); @@ -1428,11 +1457,11 @@ class Linter { configArray.normalizeSync(); } - return this._verifyWithFlatConfigArray(textOrSourceCode, configArray, options, true); + return this._distinguishSuppressedMessages(this._verifyWithFlatConfigArray(textOrSourceCode, configArray, options, true)); } if (typeof config.extractConfig === "function") { - return this._verifyWithConfigArray(textOrSourceCode, config, options); + return this._distinguishSuppressedMessages(this._verifyWithConfigArray(textOrSourceCode, config, options)); } } @@ -1446,9 +1475,9 @@ class Linter { * So we cannot apply multiple processors. */ if (options.preprocess || options.postprocess) { - return this._verifyWithProcessor(textOrSourceCode, config, options); + return this._distinguishSuppressedMessages(this._verifyWithProcessor(textOrSourceCode, config, options)); } - return this._verifyWithoutProcessors(textOrSourceCode, config, options); + return this._distinguishSuppressedMessages(this._verifyWithoutProcessors(textOrSourceCode, config, options)); } /** @@ -1457,7 +1486,7 @@ class Linter { * @param {FlatConfig} config The config array. * @param {VerifyOptions&ProcessorOptions} options The options. * @param {FlatConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively. - * @returns {LintMessage[]} The found problems. + * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems. */ _verifyWithFlatConfigArrayAndProcessor(textOrSourceCode, config, options, configForRecursive) { const filename = options.filename || ""; @@ -1514,7 +1543,7 @@ class Linter { * @param {FlatConfig} providedConfig An ESLintConfig instance to configure everything. * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. * @throws {Error} If during rule execution. - * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. + * @returns {(LintMessage|SuppressedLintMessage)[]} The results as an array of messages or an empty array if no messages. */ _verifyWithFlatConfigArrayAndWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { const slots = internalSlotsMap.get(this); @@ -1663,7 +1692,7 @@ class Linter { * @param {string|SourceCode} textOrSourceCode The source code. * @param {ConfigArray} configArray The config array. * @param {VerifyOptions&ProcessorOptions} options The options. - * @returns {LintMessage[]} The found problems. + * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems. */ _verifyWithConfigArray(textOrSourceCode, configArray, options) { debug("With ConfigArray: %s", options.filename); @@ -1700,7 +1729,7 @@ class Linter { * @param {VerifyOptions&ProcessorOptions} options The options. * @param {boolean} [firstCall=false] Indicates if this is being called directly * from verify(). (TODO: Remove once eslintrc is removed.) - * @returns {LintMessage[]} The found problems. + * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems. */ _verifyWithFlatConfigArray(textOrSourceCode, configArray, options, firstCall = false) { debug("With flat config: %s", options.filename); @@ -1740,7 +1769,7 @@ class Linter { * @param {ConfigData|ExtractedConfig} config The config array. * @param {VerifyOptions&ProcessorOptions} options The options. * @param {ConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively. - * @returns {LintMessage[]} The found problems. + * @returns {(LintMessage|SuppressedLintMessage)[]} The found problems. */ _verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) { const filename = options.filename || ""; @@ -1792,6 +1821,30 @@ class Linter { return postprocess(messageLists, filenameToExpose); } + /** + * Given a list of reported problems, distinguish problems between normal messages and suppressed messages. + * The normal messages will be returned and the suppressed messages will be stored as lastSuppressedMessages. + * @param {Problem[]} problems A list of reported problems. + * @returns {LintMessage[]} A list of LintMessage. + */ + _distinguishSuppressedMessages(problems) { + const messages = []; + const suppressedMessages = []; + const slots = internalSlotsMap.get(this); + + for (const problem of problems) { + if (problem.suppressions) { + suppressedMessages.push(problem); + } else { + messages.push(problem); + } + } + + slots.lastSuppressedMessages = suppressedMessages; + + return messages; + } + /** * Gets the SourceCode object representing the parsed source. * @returns {SourceCode} The SourceCode object. @@ -1800,6 +1853,14 @@ class Linter { return internalSlotsMap.get(this).lastSourceCode; } + /** + * Gets the list of SuppressedLintMessage produced in the last running. + * @returns {SuppressedLintMessage[]} The list of SuppressedLintMessage + */ + getSuppressedMessages() { + return internalSlotsMap.get(this).lastSuppressedMessages; + } + /** * Defines a new linting rule. * @param {string} ruleId A unique rule identifier diff --git a/lib/shared/types.js b/lib/shared/types.js index ab59207a6b1..c407c4fb120 100644 --- a/lib/shared/types.js +++ b/lib/shared/types.js @@ -105,6 +105,21 @@ module.exports = {}; * @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions. */ +/** + * @typedef {Object} SuppressedLintMessage + * @property {number|undefined} column The 1-based column number. + * @property {number} [endColumn] The 1-based column number of the end location. + * @property {number} [endLine] The 1-based line number of the end location. + * @property {boolean} fatal If `true` then this is a fatal error. + * @property {{range:[number,number], text:string}} [fix] Information for autofix. + * @property {number|undefined} line The 1-based line number. + * @property {string} message The error message. + * @property {string|null} ruleId The ID of the rule which makes this message. + * @property {0|1|2} severity The severity of this message. + * @property {Array<{kind: string, justification: string}>} suppressions The suppression info. + * @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions. + */ + /** * @typedef {Object} SuggestionResult * @property {string} desc A short description. diff --git a/tests/bin/eslint.js b/tests/bin/eslint.js index 38f132b5839..4a929a62c11 100644 --- a/tests/bin/eslint.js +++ b/tests/bin/eslint.js @@ -104,6 +104,7 @@ describe("bin/eslint.js", () => { { filePath: "", messages: [], + suppressedMessages: [], errorCount: 0, fatalErrorCount: 0, warningCount: 0, diff --git a/tests/lib/cli-engine/cli-engine.js b/tests/lib/cli-engine/cli-engine.js index 8871ff86c00..b979bd89201 100644 --- a/tests/lib/cli-engine/cli-engine.js +++ b/tests/lib/cli-engine/cli-engine.js @@ -158,6 +158,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[4].ruleId, "eol-last"); assert.strictEqual(report.results[0].fixableErrorCount, 3); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report the total and per file warnings when using local cwd .eslintrc", () => { @@ -187,6 +188,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[4].ruleId, "eol-last"); assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 3); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report one message when using specific config file", () => { @@ -210,6 +212,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].errorCount, 1); assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].warningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report the filename when passed in", () => { @@ -222,6 +225,7 @@ describe("CLIEngine", () => { const report = engine.executeOnText("var foo = 'bar';", "test.js"); assert.strictEqual(report.results[0].filePath, getFixturePath("test.js")); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return a warning when given a filename by --stdin-filename in excluded files list if warnIgnored is true", () => { @@ -247,6 +251,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fatalErrorCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should not return a warning when given a filename by --stdin-filename in excluded files list if warnIgnored is false", () => { @@ -293,6 +298,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].ruleId, "no-undef"); assert.strictEqual(report.results[0].messages[0].severity, 2); assert.isUndefined(report.results[0].messages[0].output); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return a message and fixed text when in fix mode", () => { @@ -314,6 +320,7 @@ describe("CLIEngine", () => { { filePath: getFixturePath("passing.js"), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -343,6 +350,7 @@ describe("CLIEngine", () => { const expectedOutput = fs.readFileSync(outputPath, "utf8"); assert.strictEqual(report.results[0].output, expectedOutput); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("correctly autofixes return-conflicting-fixes", () => { @@ -357,6 +365,7 @@ describe("CLIEngine", () => { const expectedOutput = fs.readFileSync(outputPath, "utf8"); assert.strictEqual(report.results[0].output, expectedOutput); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); describe("Fix Types", () => { @@ -525,6 +534,7 @@ describe("CLIEngine", () => { nodeType: "Identifier" } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -570,6 +580,7 @@ describe("CLIEngine", () => { column: 19 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -614,6 +625,7 @@ describe("CLIEngine", () => { column: 10 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -704,6 +716,7 @@ describe("CLIEngine", () => { column: 19 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -735,6 +748,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, getFixturePath("node_modules/passing.js")); assert.strictEqual(report.results[0].messages[0].message, expectedMsg); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // @scope for @scope/eslint-plugin @@ -764,6 +778,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.filePath, getFixturePath("plugin-shorthand/basic/index.js")); assert.strictEqual(report.messages[0].ruleId, "@scope/rule"); assert.strictEqual(report.messages[0].message, "OK"); + assert.strictEqual(report.suppressedMessages.length, 0); }); it("should resolve 'extends:[\"plugin:@scope/recommended\"]' to 'node_modules/@scope/eslint-plugin'.", () => { @@ -773,6 +788,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.filePath, getFixturePath("plugin-shorthand/extends/index.js")); assert.strictEqual(report.messages[0].ruleId, "@scope/rule"); assert.strictEqual(report.messages[0].message, "OK"); + assert.strictEqual(report.suppressedMessages.length, 0); }); }); it("should warn when deprecated rules are found in a config", () => { @@ -788,6 +804,7 @@ describe("CLIEngine", () => { report.usedDeprecatedRules, [{ ruleId: "indent-legacy", replacedBy: ["indent"] }] ); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); }); @@ -809,7 +826,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].message, "Parsing error: Boom!"); - + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report zero messages when given a config file and a valid file", () => { @@ -824,6 +841,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should handle multiple patterns with overlapping files", () => { @@ -837,7 +855,9 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[1].suppressedMessages.length, 0); }); it("should report zero messages when given a config file and a valid file and espree as parser", () => { @@ -854,6 +874,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report zero messages when given a config file and a valid file and esprima as parser", () => { @@ -867,6 +888,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should throw an error when given a config file and a valid file and invalid parser", () => { @@ -890,6 +912,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should fall back to defaults when extensions is set to an empty array", () => { @@ -913,6 +936,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].warningCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report zero messages when given a directory with a .js and a .js2 file", () => { @@ -928,6 +952,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report zero messages when given a '**' pattern with a .js and a .js2 file", () => { @@ -943,6 +968,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should resolve globs when 'globInputPaths' option is true", () => { @@ -957,6 +983,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should not resolve globs when 'globInputPaths' option is false", () => { @@ -988,6 +1015,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages[0].message, expectedMsg); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report on globs with explicit inclusion of dotfiles, even though ignored by default", () => { @@ -1006,6 +1034,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].warningCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should not check default ignored files without --no-ignore flag", () => { @@ -1052,6 +1081,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages[0].message, expectedMsg); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // https://github.com/eslint/eslint/issues/12873 @@ -1074,6 +1104,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages[0].message, expectedMsg); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should check .hidden files if they are passed explicitly with --no-ignore flag", () => { @@ -1095,6 +1126,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should check .hidden files if they are unignored with an --ignore-pattern", () => { @@ -1117,6 +1149,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should report zero messages when given a pattern with a .js and a .js2 file", () => { @@ -1131,7 +1164,9 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 2); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[1].suppressedMessages.length, 0); }); it("should return one error message when given a config with rules with options and severity level set to error", () => { @@ -1154,6 +1189,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].warningCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 1); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return 3 messages when given a config file and a directory of 3 valid files", () => { @@ -1177,30 +1213,35 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); assert.strictEqual(path.relative(fixturePath, report.results[1].filePath), "broken.js"); assert.strictEqual(report.results[1].errorCount, 0); assert.strictEqual(report.results[1].warningCount, 0); assert.strictEqual(report.results[1].fixableErrorCount, 0); assert.strictEqual(report.results[1].fixableWarningCount, 0); assert.strictEqual(report.results[1].messages.length, 0); + assert.strictEqual(report.results[1].suppressedMessages.length, 0); assert.strictEqual(path.relative(fixturePath, report.results[2].filePath), "cwd.js"); assert.strictEqual(report.results[2].errorCount, 0); assert.strictEqual(report.results[2].warningCount, 0); assert.strictEqual(report.results[2].fixableErrorCount, 0); assert.strictEqual(report.results[2].fixableWarningCount, 0); assert.strictEqual(report.results[2].messages.length, 0); + assert.strictEqual(report.results[2].suppressedMessages.length, 0); assert.strictEqual(path.relative(fixturePath, report.results[3].filePath), "simple.js"); assert.strictEqual(report.results[3].errorCount, 0); assert.strictEqual(report.results[3].warningCount, 0); assert.strictEqual(report.results[3].fixableErrorCount, 0); assert.strictEqual(report.results[3].fixableWarningCount, 0); assert.strictEqual(report.results[3].messages.length, 0); + assert.strictEqual(report.results[3].suppressedMessages.length, 0); assert.strictEqual(path.relative(fixturePath, report.results[4].filePath), path.join("test", "simple.js")); assert.strictEqual(report.results[4].errorCount, 0); assert.strictEqual(report.results[4].warningCount, 0); assert.strictEqual(report.results[4].fixableErrorCount, 0); assert.strictEqual(report.results[4].fixableWarningCount, 0); assert.strictEqual(report.results[4].messages.length, 0); + assert.strictEqual(report.results[4].suppressedMessages.length, 0); }); @@ -1257,6 +1298,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when given a config with environment set to browser", () => { @@ -1270,6 +1312,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when given an option to set environment to browser", () => { @@ -1287,6 +1330,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when given a config with environment set to Node.js", () => { @@ -1300,6 +1344,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should not return results from previous call when calling more than once", () => { @@ -1322,11 +1367,13 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "semi"); assert.strictEqual(report.results[0].messages[0].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); report = engine.executeOnFiles([passFilePath]); assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, passFilePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); @@ -1380,6 +1427,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].warningCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // https://github.com/eslint/eslint/issues/3812 @@ -1431,6 +1479,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].fatalErrorCount, 0); assert.strictEqual(report.results[0].fixableErrorCount, 0); assert.strictEqual(report.results[0].fixableWarningCount, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when given a file in excluded files list while ignore is off", () => { @@ -1453,6 +1502,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].severity, 2); assert.strictEqual(report.results[0].messages[1].ruleId, "no-undef"); assert.strictEqual(report.results[0].messages[1].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when executing a file with a shebang", () => { @@ -1465,6 +1515,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should give a warning when loading a custom rule that doesn't exist", () => { @@ -1481,8 +1532,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].ruleId, "missing-rule"); assert.strictEqual(report.results[0].messages[0].severity, 2); assert.strictEqual(report.results[0].messages[0].message, "Definition for rule 'missing-rule' was not found."); - - + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should throw an error when loading a bad custom rule", () => { @@ -1517,6 +1567,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "custom-rule"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should load custom rule from the provided cwd", () => { @@ -1538,6 +1589,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "custom-rule"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return messages when multiple custom rules match a file", () => { @@ -1562,6 +1614,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].severity, 2); assert.strictEqual(report.results[0].messages[1].ruleId, "no-strings"); assert.strictEqual(report.results[0].messages[1].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when executing without useEslintrc flag", () => { @@ -1578,6 +1631,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, filePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when executing without useEslintrc flag in Node.js environment", () => { @@ -1595,6 +1649,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, filePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages when executing with base-config flag set to false", () => { @@ -1612,6 +1667,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, filePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages and ignore .eslintrc files when executing with no-eslintrc flag", () => { @@ -1629,6 +1685,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, filePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return zero messages and ignore package.json files when executing with no-eslintrc flag", () => { @@ -1646,6 +1703,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].filePath, filePath); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should warn when deprecated rules are configured", () => { @@ -1669,6 +1727,7 @@ describe("CLIEngine", () => { { ruleId: "valid-jsdoc", replacedBy: [] } ] ); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should not warn when deprecated rules are not configured", () => { @@ -1681,6 +1740,7 @@ describe("CLIEngine", () => { const report = engine.executeOnFiles(["lib/cli*.js"]); assert.deepStrictEqual(report.usedDeprecatedRules, []); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should warn when deprecated rules are found in a config", () => { @@ -1696,6 +1756,7 @@ describe("CLIEngine", () => { report.usedDeprecatedRules, [{ ruleId: "indent-legacy", replacedBy: ["indent"] }] ); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); describe("Fix Mode", () => { @@ -1734,6 +1795,7 @@ describe("CLIEngine", () => { { filePath: fs.realpathSync(path.resolve(fixtureDir, "fixmode/multipass.js")), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -1744,6 +1806,7 @@ describe("CLIEngine", () => { { filePath: fs.realpathSync(path.resolve(fixtureDir, "fixmode/ok.js")), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -1765,6 +1828,7 @@ describe("CLIEngine", () => { severity: 2 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -1787,6 +1851,7 @@ describe("CLIEngine", () => { severity: 2 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -1844,6 +1909,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // No default configuration rules - conf/environments.js (/*eslint-env node*/) @@ -1859,6 +1925,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - first level .eslintrc @@ -1872,6 +1939,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - first level .eslintrc @@ -1900,6 +1968,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - second level .eslintrc @@ -1915,6 +1984,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "no-console"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - third level .eslintrc @@ -1930,6 +2000,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - first level package.json @@ -1945,6 +2016,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - second level package.json @@ -1958,6 +2030,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - third level package.json @@ -1973,6 +2046,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Project configuration - .eslintrc overrides package.json in same directory @@ -1988,6 +2062,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 2); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --config with first level .eslintrc @@ -2006,6 +2081,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].severity, 2); assert.strictEqual(report.results[0].messages[1].ruleId, "semi"); assert.strictEqual(report.results[0].messages[1].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --config with first level .eslintrc @@ -2020,6 +2096,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --config with second level .eslintrc @@ -2038,6 +2115,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages[0].severity, 1); assert.strictEqual(report.results[0].messages[1].ruleId, "semi"); assert.strictEqual(report.results[0].messages[1].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --config with second level .eslintrc @@ -2054,6 +2132,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "no-console"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --config with first level .eslintrc @@ -2068,6 +2147,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 0); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --rule with --config and first level .eslintrc @@ -2087,6 +2167,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); // Command line configuration - --rule with --config and first level .eslintrc @@ -2106,6 +2187,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "quotes"); assert.strictEqual(report.results[0].messages[0].severity, 1); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); }); @@ -2123,6 +2205,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "example/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when executing with config file that specifies a plugin with namespace", () => { @@ -2137,6 +2220,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "@eslint/example/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when executing with config file that specifies a plugin without prefix", () => { @@ -2151,6 +2235,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "example/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when executing with config file that specifies a plugin without prefix and with namespace", () => { @@ -2165,6 +2250,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "@eslint/example/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when executing with cli option that specifies a plugin", () => { @@ -2180,6 +2266,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "example/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should return two messages when executing with cli option that specifies preloaded plugin", () => { @@ -2203,6 +2290,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 2); assert.strictEqual(report.results[0].messages[0].ruleId, "test/example-rule"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); it("should load plugins from the `loadPluginsRelativeTo` directory, if specified", () => { @@ -2221,6 +2309,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].ruleId, "with-rules/rule1"); assert.strictEqual(report.results[0].messages[0].message, "Rule report from plugin"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); }); @@ -3178,6 +3267,7 @@ describe("CLIEngine", () => { assert.strictEqual(ret.results.length, 1); assert.strictEqual(ret.results[0].messages.length, 1); assert.strictEqual(ret.results[0].messages[0].ruleId, "no-unused-vars"); + assert.strictEqual(ret.results[0].suppressedMessages.length, 0); }); }); @@ -3215,6 +3305,7 @@ describe("CLIEngine", () => { assert.strictEqual(results.length, 1); assert.deepStrictEqual(results[0].messages, []); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); @@ -3314,6 +3405,7 @@ describe("CLIEngine", () => { assert.strictEqual(results.length, 1); assert.deepStrictEqual(results[0].messages, []); assert.deepStrictEqual(results[0].output, "fixed;"); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); @@ -3388,6 +3480,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages.length, 1); assert.strictEqual(results[0].messages[0].ruleId, "semi"); assert.strictEqual(results[0].messages[0].line, 2); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should fix only JavaScript blocks if '--ext' was not given.", async () => { @@ -3414,6 +3507,7 @@ describe("CLIEngine", () => { assert.strictEqual(results.length, 1); assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[0].output, unIndent` \`\`\`js console.log("hello");${/* ← fixed */""} @@ -3457,6 +3551,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages[0].line, 2); assert.strictEqual(results[0].messages[1].ruleId, "semi"); // JS block in HTML block assert.strictEqual(results[0].messages[1].line, 7); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should fix HTML blocks as well with multiple processors if '--ext' option was given.", async () => { @@ -3483,6 +3578,7 @@ describe("CLIEngine", () => { assert.strictEqual(results.length, 1); assert.strictEqual(results[0].messages.length, 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[0].output, unIndent` \`\`\`js console.log("hello");${/* ← fixed */""} @@ -3533,6 +3629,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages[0].ruleId, "semi"); // JS Block in HTML Block assert.strictEqual(results[0].messages[0].line, 7); assert.strictEqual(results[0].messages[0].fix, void 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); assert.strictEqual(results[0].output, unIndent` \`\`\`js console.log("hello");${/* ← fixed */""} @@ -3595,6 +3692,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages[0].line, 2); assert.strictEqual(results[0].messages[1].ruleId, "no-console"); assert.strictEqual(results[0].messages[1].line, 7); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should use the same config as one which has 'processor' property in order to lint blocks in HTML if the processor was legacy style.", async () => { @@ -3644,6 +3742,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages[1].line, 7); assert.strictEqual(results[0].messages[2].ruleId, "no-console"); assert.strictEqual(results[0].messages[2].line, 10); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should throw an error if invalid processor was specified.", async () => { @@ -3707,6 +3806,7 @@ describe("CLIEngine", () => { assert.strictEqual(results[0].messages[0].line, 2); assert.strictEqual(results[0].messages[1].ruleId, "semi"); // JS block in HTML block assert.strictEqual(results[0].messages[1].line, 7); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); @@ -3845,6 +3945,7 @@ describe("CLIEngine", () => { assert.strictEqual(report.results.length, 1); assert.strictEqual(report.results[0].messages.length, 1); assert.strictEqual(report.results[0].messages[0].message, "ok"); + assert.strictEqual(report.results[0].suppressedMessages.length, 0); }); }); @@ -3937,6 +4038,7 @@ describe("CLIEngine", () => { assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "'/*globals*/' has no effect because you have 'noInlineConfig' setting in your config (.eslintrc.yml)."); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should show the config file what the 'noInlineConfig' came from.", async () => { @@ -3959,6 +4061,7 @@ describe("CLIEngine", () => { assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "'/*globals*/' has no effect because you have 'noInlineConfig' setting in your config (.eslintrc.yml » eslint-config-foo)."); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); @@ -3992,6 +4095,7 @@ describe("CLIEngine", () => { assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 1); assert.strictEqual(messages[0].message, "Unused eslint-disable directive (no problems were reported from 'eqeqeq')."); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); describe("the runtime option overrides config files.", () => { @@ -4016,6 +4120,7 @@ describe("CLIEngine", () => { const messages = results[0].messages; assert.strictEqual(messages.length, 0); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); it("should warn unused 'eslint-disable' comments as error if 'reportUnusedDisableDirectives=error' was given in runtime.", async () => { @@ -4041,6 +4146,7 @@ describe("CLIEngine", () => { assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, "Unused eslint-disable directive (no problems were reported from 'eqeqeq')."); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); }); @@ -4076,6 +4182,7 @@ describe("CLIEngine", () => { assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + assert.strictEqual(results[0].suppressedMessages.length, 0); }); }); @@ -4790,6 +4897,17 @@ describe("CLIEngine", () => { assert.strictEqual(errorResults[0].messages[3].severity, 2); assert.strictEqual(errorResults[0].messages[4].ruleId, "eol-last"); assert.strictEqual(errorResults[0].messages[4].severity, 2); + assert.lengthOf(errorResults[0].suppressedMessages, 0); + }); + + it("should report no error messages when looking for errors only", () => { + process.chdir(originalDir); + const engine = new CLIEngine(); + + const report = engine.executeOnText("var foo = 'bar'; // eslint-disable-line strict, no-var, no-unused-vars, quotes, eol-last -- justification"); + const errorResults = CLIEngine.getErrorResults(report.results); + + assert.lengthOf(errorResults, 0); }); it("should not mutate passed report.results parameter", () => { @@ -4806,6 +4924,24 @@ describe("CLIEngine", () => { assert.lengthOf(report.results[0].messages, reportResultsLength); }); + it("should report no suppressed error messages when looking for errors only", () => { + process.chdir(originalDir); + const engine = new CLIEngine({ + rules: { + quotes: [1, "double"], + "no-var": 2 + } + }); + + const report = engine.executeOnText("var foo = 'bar'; // eslint-disable-line quotes -- justification\n"); + const errorResults = CLIEngine.getErrorResults(report.results); + + assert.lengthOf(report.results[0].messages, 3); + assert.lengthOf(report.results[0].suppressedMessages, 1); + assert.lengthOf(errorResults[0].messages, 3); + assert.lengthOf(errorResults[0].suppressedMessages, 0); + }); + it("should report a warningCount of 0 when looking for errors only", () => { process.chdir(originalDir); @@ -5118,10 +5254,11 @@ describe("CLIEngine", () => { const eslintCLI = new CLIEngine(config); const report = eslintCLI.executeOnText(code); - const messages = report.results[0].messages; + const { messages, suppressedMessages } = report.results[0]; assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation by default", () => { @@ -5146,9 +5283,11 @@ describe("CLIEngine", () => { const eslintCLI = new CLIEngine(config); const report = eslintCLI.executeOnText(code); - const messages = report.results[0].messages; + const { messages, suppressedMessages } = report.results[0]; assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); }); @@ -5177,6 +5316,7 @@ describe("CLIEngine", () => { nodeType: null } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -6258,6 +6398,7 @@ describe("CLIEngine", () => { severity: 2 } ], + suppressedMessages: [], source: "a == b", warningCount: 0, fatalErrorCount: 0 @@ -6282,6 +6423,7 @@ describe("CLIEngine", () => { fixableErrorCount: 0, fixableWarningCount: 0, messages: [], + suppressedMessages: [], warningCount: 0, fatalErrorCount: 0 } @@ -6329,6 +6471,7 @@ describe("CLIEngine", () => { fixableErrorCount: 0, fixableWarningCount: 0, messages: [], + suppressedMessages: [], warningCount: 0, fatalErrorCount: 0 } @@ -6364,6 +6507,7 @@ describe("CLIEngine", () => { severity: 2 } ], + suppressedMessages: [], source: "a == b", warningCount: 0, fatalErrorCount: 0 diff --git a/tests/lib/eslint/eslint.js b/tests/lib/eslint/eslint.js index d77eac5d44c..9c84e979d9b 100644 --- a/tests/lib/eslint/eslint.js +++ b/tests/lib/eslint/eslint.js @@ -400,6 +400,7 @@ describe("ESLint", () => { { filePath: getFixturePath("passing.js"), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -601,6 +602,7 @@ describe("ESLint", () => { nodeType: "Identifier" } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -641,6 +643,7 @@ describe("ESLint", () => { column: 19 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -680,6 +683,7 @@ describe("ESLint", () => { column: 10 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -768,6 +772,7 @@ describe("ESLint", () => { column: 19 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 1, @@ -1686,6 +1691,7 @@ describe("ESLint", () => { { filePath: fs.realpathSync(path.resolve(fixtureDir, "fixmode/multipass.js")), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -1697,6 +1703,7 @@ describe("ESLint", () => { { filePath: fs.realpathSync(path.resolve(fixtureDir, "fixmode/ok.js")), messages: [], + suppressedMessages: [], errorCount: 0, warningCount: 0, fatalErrorCount: 0, @@ -1719,6 +1726,7 @@ describe("ESLint", () => { severity: 2 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -1742,6 +1750,7 @@ describe("ESLint", () => { severity: 2 } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -4894,6 +4903,22 @@ describe("ESLint", () => { assert.strictEqual(rulesMeta.semi, coreRules.get("semi").meta); }); + it("should return one rule meta when there is a suppressed linting error", async () => { + const engine = new ESLint({ + useEslintrc: false, + overrideConfig: { + rules: { + semi: 2 + } + } + }); + + const results = await engine.lintText("a // eslint-disable-line semi"); + const rulesMeta = engine.getRulesMetaForResults(results); + + assert.strictEqual(rulesMeta.semi, coreRules.get("semi").meta); + }); + it("should return multiple rule meta when there are multiple linting errors", async () => { const engine = new ESLint({ useEslintrc: false, @@ -5086,6 +5111,7 @@ describe("ESLint", () => { nodeType: null } ], + suppressedMessages: [], errorCount: 1, warningCount: 0, fatalErrorCount: 0, @@ -6141,6 +6167,7 @@ describe("ESLint", () => { severity: 2 } ], + suppressedMessages: [], source: "a == b", usedDeprecatedRules: [], warningCount: 0, @@ -6166,6 +6193,7 @@ describe("ESLint", () => { fixableErrorCount: 0, fixableWarningCount: 0, messages: [], + suppressedMessages: [], usedDeprecatedRules: [], warningCount: 0, fatalErrorCount: 0 @@ -6214,6 +6242,7 @@ describe("ESLint", () => { fixableErrorCount: 0, fixableWarningCount: 0, messages: [], + suppressedMessages: [], usedDeprecatedRules: [], warningCount: 0, fatalErrorCount: 0 @@ -6250,6 +6279,7 @@ describe("ESLint", () => { severity: 2 } ], + suppressedMessages: [], source: "a == b", usedDeprecatedRules: [], warningCount: 0, diff --git a/tests/lib/linter/apply-disable-directives.js b/tests/lib/linter/apply-disable-directives.js index 3e24b866c18..512e400832e 100644 --- a/tests/lib/linter/apply-disable-directives.js +++ b/tests/lib/linter/apply-disable-directives.js @@ -52,50 +52,50 @@ describe("apply-disable-directives", () => { it("keeps problems before the comment on the same line", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ parentComment: createParentComment([0, 7]), type: "disable", line: 1, column: 8, ruleId: null }], + directives: [{ parentComment: createParentComment([0, 7]), type: "disable", line: 1, column: 8, ruleId: null, justification: "justification" }], problems: [{ line: 1, column: 7, ruleId: "foo" }] }), - [{ ruleId: "foo", line: 1, column: 7 }] + [{ line: 1, column: 7, ruleId: "foo" }] ); }); it("keeps problems on a previous line before the comment", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ parentComment: createParentComment([21, 27]), type: "disable", line: 2, column: 1, ruleId: null }], + directives: [{ parentComment: createParentComment([21, 27]), type: "disable", line: 2, column: 1, ruleId: null, justification: "justification" }], problems: [{ line: 1, column: 10, ruleId: "foo" }] }), - [{ ruleId: "foo", line: 1, column: 10 }] + [{ line: 1, column: 10, ruleId: "foo" }] ); }); it("filters problems at the same location as the comment", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 8, ruleId: null }], + directives: [{ type: "disable", line: 1, column: 8, ruleId: null, justification: "justification" }], problems: [{ line: 1, column: 8, ruleId: null }] }), - [] + [{ line: 1, column: 8, ruleId: null, suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); it("filters out problems after the comment on the same line", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 8, ruleId: null }], + directives: [{ type: "disable", line: 1, column: 8, ruleId: null, justification: "justification" }], problems: [{ line: 1, column: 10, ruleId: "foo" }] }), - [] + [{ line: 1, column: 10, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); it("filters out problems on a later line than the comment", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 8, ruleId: null }], + directives: [{ type: "disable", line: 1, column: 8, ruleId: null, justification: "justification" }], problems: [{ line: 2, column: 3, ruleId: "foo" }] }), - [] + [{ line: 2, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); }); @@ -104,20 +104,20 @@ describe("apply-disable-directives", () => { it("filters problems after the comment that have the same ruleId", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 8, ruleId: "foo" }], + directives: [{ type: "disable", line: 1, column: 8, ruleId: "foo", justification: "justification" }], problems: [{ line: 2, column: 3, ruleId: "foo" }] }), - [] + [{ line: 2, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); it("filters problems in the same location as the comment that have the same ruleId", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 8, ruleId: "foo" }], + directives: [{ type: "disable", line: 1, column: 8, ruleId: "foo", justification: "justification" }], problems: [{ line: 1, column: 8, ruleId: "foo" }] }), - [] + [{ line: 1, column: 8, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -129,7 +129,8 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [{ line: 2, column: 3, ruleId: "not-foo" }] }), @@ -164,14 +165,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([27, 45]), type: "enable", line: 1, column: 26, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 1, column: 27, ruleId: "foo" }] @@ -189,14 +192,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([26, 40]), type: "enable", line: 1, column: 26, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 1, column: 26, ruleId: "foo" }] @@ -209,12 +214,12 @@ describe("apply-disable-directives", () => { assert.deepStrictEqual( applyDisableDirectives({ directives: [ - { type: "disable", line: 1, column: 1, ruleId: null }, - { type: "enable", line: 1, column: 26, ruleId: null } + { type: "disable", line: 1, column: 1, ruleId: null, justification: "j1" }, + { type: "enable", line: 1, column: 26, ruleId: null, justification: "j2" } ], problems: [{ line: 1, column: 3, ruleId: "foo" }] }), - [] + [{ line: 1, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j1" }] }] ); }); @@ -227,26 +232,29 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([26, 44]), type: "enable", line: 1, column: 26, - ruleId: "foo" + ruleId: "foo", + justification: "j2" }, { parentComment: createParentComment([45, 63]), type: "disable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j3" } ], problems: [{ line: 3, column: 3, ruleId: "foo" }] }), - [] + [{ line: 3, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j3" }] }] ); }); @@ -259,26 +267,29 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 44]), type: "enable", line: 1, column: 26, - ruleId: "foo" + ruleId: "foo", + justification: "j2" }, { parentComment: createParentComment([45, 63]), type: "disable", line: 2, column: 1, - ruleId: null + ruleId: null, + justification: "j3" } ], problems: [{ line: 3, column: 3, ruleId: "foo" }] }), - [] + [{ line: 3, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j3" }] }] ); }); @@ -291,14 +302,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j1" }, { parentComment: createParentComment([25, 44]), type: "enable", line: 1, column: 26, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 1, column: 3, ruleId: "not-foo" }] @@ -318,14 +331,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 44]), type: "enable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 2, column: 4, ruleId: "foo" }] @@ -343,14 +358,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 44]), type: "enable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 2, column: 1, ruleId: "foo" }] @@ -363,12 +380,26 @@ describe("apply-disable-directives", () => { assert.deepStrictEqual( applyDisableDirectives({ directives: [ - { type: "disable", line: 1, column: 1, ruleId: null }, - { type: "enable", line: 2, column: 1, ruleId: "foo" } + { + parentComment: createParentComment([0, 20]), + type: "disable", + line: 1, + column: 1, + ruleId: null, + justification: "j1" + }, + { + parentComment: createParentComment([21, 44]), + type: "enable", + line: 2, + column: 1, + ruleId: "foo", + justification: "j2" + } ], problems: [{ line: 2, column: 4, ruleId: "not-foo" }] }), - [] + [{ line: 2, column: 4, ruleId: "not-foo", suppressions: [{ kind: "directive", justification: "j1" }] }] ); }); @@ -376,9 +407,9 @@ describe("apply-disable-directives", () => { assert.deepStrictEqual( applyDisableDirectives({ directives: [ - { type: "disable", line: 1, column: 1, ruleId: null }, - { type: "enable", line: 1, column: 22, ruleId: "foo" }, - { type: "enable", line: 1, column: 46, ruleId: "bar" } + { type: "disable", line: 1, column: 1, ruleId: null, justification: "j1" }, + { type: "enable", line: 1, column: 22, ruleId: "foo", justification: "j2" }, + { type: "enable", line: 1, column: 46, ruleId: "bar", justification: "j3" } ], problems: [ { line: 1, column: 10, ruleId: "foo" }, @@ -390,7 +421,10 @@ describe("apply-disable-directives", () => { ] }), [ + { line: 1, column: 10, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j1" }] }, + { line: 1, column: 10, ruleId: "bar", suppressions: [{ kind: "directive", justification: "j1" }] }, { line: 1, column: 30, ruleId: "foo" }, + { line: 1, column: 30, ruleId: "bar", suppressions: [{ kind: "directive", justification: "j1" }] }, { line: 1, column: 50, ruleId: "foo" }, { line: 1, column: 50, ruleId: "bar" } ] @@ -407,7 +441,8 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 2, column: 1, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [{ line: 1, column: 5, ruleId: "foo" }] }), @@ -423,11 +458,12 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 8, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [{ line: 1, column: 1, ruleId: "foo" }] }), - [] + [{ line: 1, column: 1, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -439,11 +475,12 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 8, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [{ line: 1, column: 10, ruleId: "foo" }] }), - [] + [{ line: 1, column: 10, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -455,7 +492,8 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [{ line: 2, column: 1, ruleId: "foo" }] }), @@ -473,18 +511,26 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [{ line: 1, column: 2, ruleId: "foo" }] }), - [] + [{ line: 1, column: 2, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); it("keeps problems on the current line that do not match the ruleId", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ parentComment: createParentComment([0, 27]), type: "disable-line", line: 1, column: 1, ruleId: "foo" }], + directives: [{ + parentComment: createParentComment([0, 27]), + type: "disable-line", + line: 1, + column: 1, + ruleId: "foo", + justification: "justification" + }], problems: [{ line: 1, column: 2, ruleId: "not-foo" }] }), [{ line: 1, column: 2, ruleId: "not-foo" }] @@ -500,19 +546,21 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([24, 28]), type: "disable-line", line: 1, column: 22, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 1, column: 5, ruleId: "not-foo" }] }), - [] + [{ line: 1, column: 5, ruleId: "not-foo", suppressions: [{ kind: "directive", justification: "j1" }] }] ); }); @@ -525,47 +573,53 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j1" }, { parentComment: createParentComment([38, 73]), type: "disable-line", line: 2, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j2" }, { parentComment: createParentComment([76, 111]), type: "disable-line", line: 3, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j3" }, { parentComment: createParentComment([114, 149]), type: "disable-line", line: 4, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j4" }, { parentComment: createParentComment([152, 187]), type: "disable-line", line: 5, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j5" }, { parentComment: createParentComment([190, 225]), type: "disable-line", line: 6, column: 8, - ruleId: "foo" + ruleId: "foo", + justification: "j6" } ], problems: [{ line: 2, column: 1, ruleId: "foo" }] }), - [] + [{ line: 2, column: 1, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j2" }] }] ); }); }); @@ -579,11 +633,12 @@ describe("apply-disable-directives", () => { type: "disable-next-line", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [{ line: 2, column: 3, ruleId: "foo" }] }), - [] + [{ line: 2, column: 3, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -611,7 +666,8 @@ describe("apply-disable-directives", () => { type: "disable-next-line", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "justificatiion" }], problems: [{ line: 3, column: 3, ruleId: "foo" }] }), @@ -623,12 +679,12 @@ describe("apply-disable-directives", () => { assert.deepStrictEqual( applyDisableDirectives({ directives: [ - { type: "disable-next-line", line: 1, column: 1, ruleId: null }, - { type: "enable", line: 1, column: 5, ruleId: null } + { parentComment: createParentComment([0, 31]), type: "disable-next-line", line: 1, column: 1, ruleId: null, justification: "j1" }, + { type: "enable", line: 1, column: 5, ruleId: null, justification: "j2" } ], problems: [{ line: 2, column: 2, ruleId: "foo" }] }), - [] + [{ line: 2, column: 2, ruleId: "foo", suppressions: [{ kind: "directive", justification: "j1" }] }] ); }); }); @@ -637,10 +693,10 @@ describe("apply-disable-directives", () => { it("filters problems on the next line that match the ruleId", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable-next-line", line: 1, column: 1, ruleId: "foo" }], + directives: [{ type: "disable-next-line", line: 1, column: 1, ruleId: "foo", justification: "justification" }], problems: [{ line: 2, column: 1, ruleId: "foo" }] }), - [] + [{ line: 2, column: 1, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -652,7 +708,8 @@ describe("apply-disable-directives", () => { type: "disable-next-line", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [{ line: 2, column: 1, ruleId: "not-foo" }] }), @@ -666,7 +723,7 @@ describe("apply-disable-directives", () => { assert.throws( () => applyDisableDirectives({ - directives: [{ type: "foo", line: 1, column: 4, ruleId: "foo" }], + directives: [{ type: "foo", line: 1, column: 4, ruleId: "foo", justification: "justification" }], problems: [] }), "Unrecognized directive type 'foo'" @@ -682,25 +739,24 @@ describe("apply-disable-directives", () => { parentComment: createParentComment([0, 20]), type: "disable", line: 1, - column: 1 + column: 1, + justification: "justification" }], problems: [], reportUnusedDisableDirectives: "error" }), - [ - { - ruleId: null, - message: "Unused eslint-disable directive (no problems were reported).", - line: 1, - column: 1, - fix: { - range: [0, 20], - text: " " - }, - severity: 2, - nodeType: null - } - ] + [{ + ruleId: null, + message: "Unused eslint-disable directive (no problems were reported).", + line: 1, + column: 1, + fix: { + range: [0, 20], + text: " " + }, + severity: 2, + nodeType: null + }] ); }); @@ -711,33 +767,32 @@ describe("apply-disable-directives", () => { parentComment: createParentComment([0, 20]), type: "disable", line: 1, - column: 1 + column: 1, + justification: "justification" }], disableFixes: true, problems: [], reportUnusedDisableDirectives: "error" }), - [ - { - ruleId: null, - message: "Unused eslint-disable directive (no problems were reported).", - line: 1, - column: 1, - severity: 2, - nodeType: null - } - ] + [{ + ruleId: null, + message: "Unused eslint-disable directive (no problems were reported).", + line: 1, + column: 1, + severity: 2, + nodeType: null + }] ); }); it("Does not add a problem for /* eslint-disable */ /* (problem) */", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 1, ruleId: null }], + directives: [{ type: "disable", line: 1, column: 1, ruleId: null, justification: "justification" }], problems: [{ line: 2, column: 1, ruleId: "foo" }], reportUnusedDisableDirectives: "error" }), - [] + [{ line: 2, column: 1, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -749,25 +804,24 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [], reportUnusedDisableDirectives: "error" }), - [ - { - ruleId: null, - message: "Unused eslint-disable directive (no problems were reported from 'foo').", - line: 1, - column: 1, - fix: { - range: [0, 21], - text: " " - }, - severity: 2, - nodeType: null - } - ] + [{ + ruleId: null, + message: "Unused eslint-disable directive (no problems were reported from 'foo').", + line: 1, + column: 1, + fix: { + range: [0, 21], + text: " " + }, + severity: 2, + nodeType: null + }] ); }); @@ -779,7 +833,8 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "justification" }], problems: [{ line: 1, column: 20, ruleId: "not-foo" }], reportUnusedDisableDirectives: "error" @@ -815,14 +870,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 8, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([0, 21]), type: "enable", line: 1, column: 24, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 1, column: 2, ruleId: "foo" }], @@ -859,33 +916,33 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 41]), type: "enable", line: 1, column: 12, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [], reportUnusedDisableDirectives: "error" }), - [ - { - ruleId: null, - message: "Unused eslint-disable directive (no problems were reported).", - line: 1, - column: 1, - fix: { - range: [0, 20], - text: " " - }, - severity: 2, - nodeType: null - } - ] + [{ + ruleId: null, + message: "Unused eslint-disable directive (no problems were reported).", + line: 1, + column: 1, + fix: { + range: [0, 20], + text: " " + }, + severity: 2, + nodeType: null + }] ); }); @@ -898,14 +955,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 42]), type: "disable", line: 2, column: 1, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [], @@ -949,14 +1008,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([22, 45]), type: "disable", line: 2, column: 1, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 3, column: 1, ruleId: "foo" }], @@ -974,6 +1035,15 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 3, + column: 1, + ruleId: "foo", + suppressions: [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] } ] ); @@ -988,14 +1058,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j1" }, { parentComment: createParentComment([22, 45]), type: "disable", line: 2, column: 1, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 3, column: 1, ruleId: "foo" }], @@ -1013,6 +1085,15 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 3, + column: 1, + ruleId: "foo", + suppressions: [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] } ] ); @@ -1021,11 +1102,11 @@ describe("apply-disable-directives", () => { it("Does not add a problem for /* eslint-disable foo */ /* (problem from foo) */", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable", line: 1, column: 1, ruleId: "foo" }], + directives: [{ type: "disable", line: 1, column: 1, ruleId: "foo", justification: "justification" }], problems: [{ line: 1, column: 6, ruleId: "foo" }], reportUnusedDisableDirectives: "error" }), - [] + [{ line: 1, column: 6, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -1038,14 +1119,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([22, 45]), type: "disable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 3, column: 1, ruleId: "foo" }], @@ -1063,6 +1146,15 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 3, + column: 1, + ruleId: "foo", + suppressions: [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] } ] ); @@ -1077,14 +1169,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([21, 45]), type: "disable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 3, column: 1, ruleId: "bar" }], @@ -1102,6 +1196,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 3, + column: 1, + ruleId: "bar", + suppressions: [{ kind: "directive", justification: "j1" }] } ] ); @@ -1116,14 +1216,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j1" }, { parentComment: createParentComment([25, 46]), type: "enable", line: 1, column: 26, - ruleId: "foo" + ruleId: "foo", + justification: "j2" } ], problems: [{ line: 1, column: 30, ruleId: "foo" }], @@ -1160,14 +1262,16 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j1" }, { parentComment: createParentComment([25, 49]), type: "enable", line: 1, column: 26, - ruleId: null + ruleId: null, + justification: "j2" } ], problems: [{ line: 1, column: 30, ruleId: "foo" }], @@ -1204,21 +1308,24 @@ describe("apply-disable-directives", () => { type: "disable", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "j1" }, { parentComment: createParentComment([22, 45]), type: "disable", line: 2, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j2" }, { parentComment: createParentComment([46, 69]), type: "enable", line: 3, column: 1, - ruleId: "foo" + ruleId: "foo", + justification: "j3" } ], problems: [{ line: 4, column: 1, ruleId: "foo" }], @@ -1266,7 +1373,8 @@ describe("apply-disable-directives", () => { type: "disable-line", line: 1, column: 1, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [], reportUnusedDisableDirectives: "error" @@ -1292,11 +1400,11 @@ describe("apply-disable-directives", () => { it("Does not add a problem for // eslint-disable-line (problem)", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable-line", line: 1, column: 1, ruleId: null }], + directives: [{ type: "disable-line", line: 1, column: 1, ruleId: null, justification: "justification" }], problems: [{ line: 1, column: 10, ruleId: "foo" }], reportUnusedDisableDirectives: "error" }), - [] + [{ line: 1, column: 10, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -1308,7 +1416,8 @@ describe("apply-disable-directives", () => { type: "disable-next-line", line: 1, column: 2, - ruleId: null + ruleId: null, + justification: "justification" }], problems: [], reportUnusedDisableDirectives: "error" @@ -1333,11 +1442,11 @@ describe("apply-disable-directives", () => { it("Does not add a problem for // eslint-disable-next-line \\n (problem)", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ type: "disable-next-line", line: 1, column: 1, ruleId: null }], + directives: [{ type: "disable-next-line", line: 1, column: 1, ruleId: null, justification: "justification" }], problems: [{ line: 2, column: 10, ruleId: "foo" }], reportUnusedDisableDirectives: "error" }), - [] + [{ line: 2, column: 10, ruleId: "foo", suppressions: [{ kind: "directive", justification: "justification" }] }] ); }); @@ -1383,7 +1492,14 @@ describe("apply-disable-directives", () => { it("Does not add problems when reportUnusedDisableDirectives: \"off\" is used", () => { assert.deepStrictEqual( applyDisableDirectives({ - directives: [{ parentComment: createParentComment([0, 27]), type: "disable-next-line", line: 1, column: 1, ruleId: null }], + directives: [{ + parentComment: createParentComment([0, 27]), + type: "disable-next-line", + line: 1, + column: 1, + ruleId: null, + justification: "justification" + }], problems: [], reportUnusedDisableDirectives: "off" }), @@ -1404,14 +1520,16 @@ describe("apply-disable-directives", () => { ruleId: "used", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "unused", type: "disable", line: 1, - column: 22 + column: 22, + justification: "j2" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1429,6 +1547,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j1" }] } ] ); @@ -1444,14 +1568,16 @@ describe("apply-disable-directives", () => { ruleId: "used", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "unused", type: "disable", line: 1, - column: 24 + column: 24, + justification: "j2" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1469,6 +1595,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j1" }] } ] ); @@ -1485,14 +1617,16 @@ describe("apply-disable-directives", () => { ruleId: "unused", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "used", type: "disable", line: 1, - column: 25 + column: 25, + justification: "j2" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1510,6 +1644,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j2" }] } ] ); @@ -1526,14 +1666,16 @@ describe("apply-disable-directives", () => { ruleId: "unused", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "used", type: "disable", line: 1, - column: 29 + column: 29, + justification: "j2" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1551,6 +1693,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j2" }] } ] ); @@ -1567,21 +1715,24 @@ describe("apply-disable-directives", () => { ruleId: "unused-1", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "unused-2", type: "disable", line: 1, - column: 28 + column: 28, + justification: "j2" }, { parentComment, ruleId: "used", type: "disable", line: 1, - column: 38 + column: 38, + justification: "j3" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1611,6 +1762,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j3" }] } ] ); @@ -1627,28 +1784,32 @@ describe("apply-disable-directives", () => { ruleId: "unused-1", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "unused-2", type: "disable", line: 1, - column: 28 + column: 28, + justification: "j2" }, { parentComment, ruleId: "used", type: "disable", line: 1, - column: 38 + column: 38, + justification: "j3" }, { parentComment, ruleId: "unused-3", type: "disable", line: 1, - column: 43 + column: 43, + justification: "j4" } ], problems: [{ line: 2, column: 1, ruleId: "used" }], @@ -1690,6 +1851,12 @@ describe("apply-disable-directives", () => { }, severity: 2, nodeType: null + }, + { + line: 2, + column: 1, + ruleId: "used", + suppressions: [{ kind: "directive", justification: "j3" }] } ] ); @@ -1706,14 +1873,16 @@ describe("apply-disable-directives", () => { ruleId: "unused-1", type: "disable", line: 1, - column: 18 + column: 18, + justification: "j1" }, { parentComment, ruleId: "unused-2", type: "disable", line: 1, - column: 28 + column: 28, + justification: "j2" } ], problems: [], @@ -1783,5 +1952,72 @@ describe("apply-disable-directives", () => { ] ); }); + + it("Adds a problem for /* eslint-disable foo */ \\n (problem from foo and bar) // eslint-disable-line foo, bar", () => { + assert.deepStrictEqual( + applyDisableDirectives({ + directives: [ + { + parentComment: createParentComment([0, 29], " eslint-disable foo ", ["foo"]), + ruleId: "foo", + type: "disable", + line: 1, + column: 1, + justification: "j1" + }, + { + parentComment: createParentComment([41, 81], " eslint-disable-line foo, bar", ["foo", "bar"]), + ruleId: "foo", + type: "disable-line", + line: 2, + column: 11, + justification: "j2" + }, + { + parentComment: createParentComment([41, 81], " eslint-disable-line foo, bar ", ["foo", "bar"]), + ruleId: "bar", + type: "disable-line", + line: 2, + column: 11, + justification: "j2" + } + ], + problems: [ + { line: 2, column: 1, ruleId: "bar" }, + { line: 2, column: 6, ruleId: "foo" } + ], + reportUnusedDisableDirectives: "error" + }), + [ + { + ruleId: "bar", + line: 2, + column: 1, + suppressions: [{ kind: "directive", justification: "j2" }] + }, + { + ruleId: "foo", + line: 2, + column: 6, + suppressions: [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] + }, + { + ruleId: null, + message: "Unused eslint-disable directive (no problems were reported from 'foo').", + line: 2, + column: 11, + fix: { + range: [64, 69], + text: "" + }, + severity: 2, + nodeType: null + } + ] + ); + }); }); }); diff --git a/tests/lib/linter/linter.js b/tests/lib/linter/linter.js index d0f356702e0..8c121808e1b 100644 --- a/tests/lib/linter/linter.js +++ b/tests/lib/linter/linter.js @@ -217,6 +217,131 @@ describe("Linter", () => { }); + describe("getSuppressedMessages()", () => { + it("should have no suppressed messages", () => { + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(suppressedMessages.length, 0); + }); + + it("should have a suppressed message", () => { + const code = "/* eslint-disable no-alert -- justification */\nalert(\"test\");"; + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [{ kind: "directive", justification: "justification" }] + ); + }); + + it("should have a suppressed message", () => { + const code = [ + "/* eslint-disable no-alert --- j1", + " * --- j2", + " */", + "alert(\"test\");" + ].join("\n"); + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [{ kind: "directive", justification: "j1\n * --- j2" }] + ); + }); + + it("should not report a lint message", () => { + const code = [ + "/* eslint-disable -- j1 */", + "// eslint-disable-next-line -- j2", + "alert(\"test\");" + ].join("\n"); + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] + ); + }); + + it("should not report a lint message", () => { + const code = [ + "/* eslint-disable -- j1 */", + "alert(\"test\"); // eslint-disable-line -- j2" + ].join("\n"); + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" } + ] + ); + }); + + it("should have a suppressed message with multiple suppressions", () => { + const code = [ + "/* eslint-disable no-alert -- j1 */", + "/* eslint-disable no-console -- unused */", + "/* eslint-disable-next-line no-alert -- j2 */", + "alert(\"test\"); // eslint-disable-line no-alert -- j3" + ].join("\n"); + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [ + { kind: "directive", justification: "j1" }, + { kind: "directive", justification: "j2" }, + { kind: "directive", justification: "j3" } + ] + ); + }); + }); + describe("context.getSource()", () => { const code = TEST_CODE; @@ -832,8 +957,10 @@ describe("Linter", () => { })); const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); sinon.assert.calledOnce(spyVariableDeclaration); sinon.assert.calledOnce(spyVariableDeclarator); sinon.assert.calledOnce(spyIdentifier); @@ -871,9 +998,11 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hello"); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not have any settings if they were not passed in", () => { @@ -890,8 +1019,10 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -951,8 +1082,10 @@ describe("Linter", () => { linter.defineParser("test-parser", parser); const config = { rules: {}, parser: "test-parser" }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -978,8 +1111,10 @@ describe("Linter", () => { linter.defineParser("enhanced-parser", testParsers.enhancedParser); const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should expose parser services when using parseForESLint() and services are specified", () => { @@ -995,9 +1130,11 @@ describe("Linter", () => { const config = { rules: { "test-service-rule": 2 }, parser: "enhanced-parser" }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hi!"); + assert.strictEqual(suppressedMessages.length, 0); }); it("should use the same parserServices if source code object is reused", () => { @@ -1013,14 +1150,18 @@ describe("Linter", () => { const config = { rules: { "test-service-rule": 2 }, parser: "enhanced-parser" }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hi!"); + assert.strictEqual(suppressedMessages.length, 0); const messages2 = linter.verify(linter.getSourceCode(), config, filename); + const suppressedMessages2 = linter.getSuppressedMessages(); assert.strictEqual(messages2.length, 1); assert.strictEqual(messages2[0].message, "Hi!"); + assert.strictEqual(suppressedMessages2.length, 0); }); it("should pass parser as parserPath to all rules when default parser is used", () => { @@ -1046,9 +1187,12 @@ describe("Linter", () => { config.rules[rule] = 1; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by only setting the string value", () => { @@ -1058,10 +1202,13 @@ describe("Linter", () => { config.rules[rule] = "warn"; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by passing in values as an array", () => { @@ -1071,9 +1218,12 @@ describe("Linter", () => { config.rules[rule] = [1]; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by passing in string value as an array", () => { @@ -1083,10 +1233,13 @@ describe("Linter", () => { config.rules[rule] = ["warn"]; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not be configurable by setting other value", () => { @@ -1096,15 +1249,19 @@ describe("Linter", () => { config.rules[rule] = "1"; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should process empty config", () => { const config = {}; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1504,10 +1661,13 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, code); assert.strictEqual(messages[0].nodeType, "Literal"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1531,6 +1691,7 @@ describe("Linter", () => { linter.defineRules(newRules); const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, code.length); code.forEach(item => { @@ -1539,6 +1700,8 @@ describe("Linter", () => { messages.forEach(message => { assert.strictEqual(message.nodeType, "Literal"); }); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1557,8 +1720,10 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, filename); + assert.strictEqual(suppressedMessages.length, 0); }); it("has access to the physicalFilename", () => { @@ -1573,8 +1738,10 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, filename); + assert.strictEqual(suppressedMessages.length, 0); }); it("defaults filename to ''", () => { @@ -1589,8 +1756,10 @@ describe("Linter", () => { config.rules[code] = 1; const messages = linter.verify("0", config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, ""); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1601,11 +1770,14 @@ describe("Linter", () => { const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -1613,11 +1785,16 @@ describe("Linter", () => { const codeA = "/*eslint strict: 0*/ function bar() { return 2; }"; const codeB = "function foo() { return 1; }"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -1625,42 +1802,62 @@ describe("Linter", () => { const codeA = "/*eslint quotes: 0*/ function bar() { return '2'; }"; const codeB = "function foo() { return '1'; }"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { const config = { rules: { quotes: [2, "double"] } }; const codeA = "/*eslint quotes: [0, \"single\"]*/ function bar() { return '2'; }"; const codeB = "function foo() { return '1'; }"; + let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { const config = { rules: { "no-unused-vars": [2, { vars: "all" }] } }; const codeA = "/*eslint no-unused-vars: [0, {\"vars\": \"local\"}]*/ var a = 44;"; const codeB = "var b = 55;"; + let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); }); describe("when evaluating code with invalid comments to enable rules", () => { it("should report a violation when the config is not a valid rule configuration", () => { + const messages = linter.verify("/*eslint no-alert:true*/ alert('test');", {}); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/*eslint no-alert:true*/ alert('test');", {}), + messages, [ { severity: 2, @@ -1674,11 +1871,16 @@ describe("Linter", () => { } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation when the config violates a rule's schema", () => { + const messages = linter.verify("/* eslint no-alert: [error, {nonExistentPropertyName: true}]*/", {}); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint no-alert: [error, {nonExistentPropertyName: true}]*/", {}), + messages, [ { severity: 2, @@ -1692,6 +1894,8 @@ describe("Linter", () => { } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1702,52 +1906,68 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); describe("when evaluating code with comments to disable rules", () => { - let code, messages; + let code, messages, suppressedMessages; it("should report an error when disabling a non-existent rule in inline comment", () => { code = "/*eslint foo:0*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable-line foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable-next-line foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error, when disabling a non-existent rule in config", () => { messages = linter.verify("", { rules: { foo: 0 } }, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report an error, when config a non-existent rule in config", () => { messages = linter.verify("", { rules: { foo: 1 } }, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify("", { rules: { foo: 2 } }, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1758,12 +1978,15 @@ describe("Linter", () => { const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1774,11 +1997,14 @@ describe("Linter", () => { const config = { rules: { "no-console": 1, "no-alert": 0 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1799,8 +2025,10 @@ describe("Linter", () => { const code = "/*eslint test-plugin/test-rule: 2*/ var a = \"no violation\";"; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation when inline comment disables plugin rule", () => { @@ -1808,8 +2036,10 @@ describe("Linter", () => { const config = { rules: { "test-plugin/test-rule": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation when the report is right before the comment", () => { @@ -1821,9 +2051,11 @@ describe("Linter", () => { } })); const problems = linter.verify(code, { rules: { checker: "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 1); assert.strictEqual(problems[0].message, "foo"); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation when the report is right at the start of the comment", () => { @@ -1835,20 +2067,32 @@ describe("Linter", () => { } })); const problems = linter.verify(code, { rules: { checker: "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].message, "foo"); + assert.strictEqual(suppressedMessages[0].suppressions.length, 1); + assert.strictEqual(suppressedMessages[0].suppressions[0].justification, ""); }); it("rules should not change initial config", () => { const config = { rules: { "test-plugin/test-rule": 2 } }; const codeA = "/*eslint test-plugin/test-rule: 0*/ var a = \"trigger violation\";"; const codeB = "var a = \"trigger violation\";"; + let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -1864,12 +2108,20 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); assert.strictEqual(messages[0].line, 4); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].message, "Unexpected alert."); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[0].suppressions.length, 1); + assert.strictEqual(suppressedMessages[0].suppressions[0].justification, ""); }); it("should not report a violation", () => { @@ -1881,8 +2133,15 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[0].suppressions.length, 1); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[1].suppressions.length, 1); }); it("should not report a violation", () => { @@ -1895,10 +2154,15 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].column, 21); assert.strictEqual(messages[1].column, 19); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].column, 1); + assert.strictEqual(suppressedMessages[1].column, 56); }); it("should report a violation", () => { @@ -1916,8 +2180,10 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 2); }); @@ -1931,8 +2197,10 @@ describe("Linter", () => { const config = { rules: { "no-unused-vars": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 1); }); it("should not report a violation", () => { @@ -1944,8 +2212,10 @@ describe("Linter", () => { const config = { rules: { "no-unused-vars": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 1); }); }); @@ -1965,10 +2235,13 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should report a violation", () => { @@ -1985,10 +2258,14 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); }); it("should report a violation if eslint-disable-line in a block comment is not on a single line", () => { @@ -2004,10 +2281,11 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not disable rule and add an extra report if eslint-disable-line in a block comment is not on a single line", () => { @@ -2022,6 +2300,7 @@ describe("Linter", () => { }; const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages, [ { @@ -2046,6 +2325,8 @@ describe("Linter", () => { nodeType: null } ]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation for eslint-disable-line in block comment", () => { @@ -2060,8 +2341,13 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "no-alert"); }); it("should not report a violation", () => { @@ -2077,8 +2363,13 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); }); it("should not report a violation", () => { @@ -2096,8 +2387,10 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); it("should not report a violation", () => { @@ -2115,8 +2408,10 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); it("should ignore violations of multiple rules when specified in mixed comments", () => { @@ -2130,8 +2425,12 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); }); @@ -2149,9 +2448,13 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => { @@ -2167,9 +2470,13 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => { const code = [ @@ -2182,8 +2489,12 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should not ignore violation if code is not on next line", () => { @@ -2197,9 +2508,12 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore violation if block comment span multiple lines", () => { @@ -2214,8 +2528,12 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violations only of specified rule", () => { @@ -2231,10 +2549,13 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore violations of multiple rules when specified", () => { @@ -2251,9 +2572,14 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); }); it("should ignore violations of multiple rules when specified in multiple lines", () => { @@ -2290,8 +2616,13 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); }); it("should ignore violations of multiple rules when specified in mixed sinlge line and multi line comments", () => { @@ -2326,10 +2657,14 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "quotes"); }); it("should ignore violations of specified rule on next line only", () => { @@ -2346,10 +2681,14 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore all rule violations on next line if none specified", () => { @@ -2367,9 +2706,15 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); + assert.strictEqual(suppressedMessages[2].ruleId, "semi"); }); it("should ignore violations if eslint-disable-next-line is a block comment", () => { @@ -2386,10 +2731,14 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should report a violation", () => { @@ -2407,10 +2756,12 @@ describe("Linter", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not ignore violations if comment is of the type hashbang", () => { @@ -2426,10 +2777,13 @@ describe("Linter", () => { } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); }); @@ -2445,10 +2799,13 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should report no violation", () => { @@ -2461,8 +2818,15 @@ describe("Linter", () => { const config = { rules: { "no-unused-vars": 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-unused-vars"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-unused-vars"); + assert.strictEqual(suppressedMessages[1].line, 3); }); it("should report no violation", () => { @@ -2476,8 +2840,10 @@ describe("Linter", () => { const config = { rules: { "no-unused-vars": 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); it("should report no violation", () => { @@ -2489,8 +2855,10 @@ describe("Linter", () => { const config = { rules: { quotes: 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -2506,13 +2874,19 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); assert.strictEqual(messages[1].ruleId, "no-console"); assert.strictEqual(messages[1].line, 6); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); }); it("should report a violation", () => { @@ -2527,10 +2901,16 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].line, 5); }); @@ -2547,11 +2927,19 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); + + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); @@ -2577,21 +2965,23 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 4); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 6); - assert.strictEqual(messages[1].ruleId, "no-console"); assert.strictEqual(messages[1].line, 7); - assert.strictEqual(messages[2].ruleId, "no-alert"); assert.strictEqual(messages[2].line, 9); - assert.strictEqual(messages[3].ruleId, "no-console"); assert.strictEqual(messages[3].line, 10); + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 3); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 4); }); it("should report a violation", () => { @@ -2614,18 +3004,23 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); - assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].line, 8); - assert.strictEqual(messages[2].ruleId, "no-console"); assert.strictEqual(messages[2].line, 9); + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); it("should report a violation when severity is warn", () => { @@ -2648,18 +3043,23 @@ describe("Linter", () => { const config = { rules: { "no-alert": "warn", "no-console": "warn" } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); - assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].line, 8); - assert.strictEqual(messages[2].ruleId, "no-console"); assert.strictEqual(messages[2].line, 9); + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); }); @@ -2670,11 +3070,14 @@ describe("Linter", () => { const config = { rules: { "no-console": 1, "no-alert": 0 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2685,11 +3088,14 @@ describe("Linter", () => { const config = { rules: { quotes: [2, "single"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "quotes"); assert.strictEqual(messages[0].message, "Strings must use doublequote."); assert.include(messages[0].nodeType, "Literal"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2700,11 +3106,14 @@ describe("Linter", () => { const config = { rules: { quotes: [2, "single"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "quotes"); assert.strictEqual(messages[0].message, "Strings must use doublequote."); assert.include(messages[0].nodeType, "Literal"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2715,6 +3124,7 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -2732,6 +3142,8 @@ describe("Linter", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -2740,6 +3152,7 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -2757,6 +3170,8 @@ describe("Linter", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -2765,6 +3180,7 @@ describe("Linter", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -2782,6 +3198,8 @@ describe("Linter", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2793,11 +3211,14 @@ alert('test'); it("should not parse errors, should report a violation", () => { const messages = linter.verify(code, {}, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "max-len"); assert.strictEqual(messages[0].message, "This line has a length of 129. Maximum allowed is 100."); assert.include(messages[0].nodeType, "Program"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2812,6 +3233,7 @@ var a = "test2"; it("should validate correctly", () => { const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); const [message1, message2] = messages; assert.strictEqual(messages.length, 2); @@ -2825,6 +3247,8 @@ var a = "test2"; assert.strictEqual(message2.line, 5); assert.strictEqual(message2.column, 1); assert.include(message2.nodeType, "Program"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2834,11 +3258,14 @@ var a = "test2"; const code = "#!bin/program\n\nvar foo;;"; const config = { rules: { "no-extra-semi": 1 } }; const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-extra-semi"); assert.strictEqual(messages[0].nodeType, "EmptyStatement"); assert.strictEqual(messages[0].line, 3); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should have a comment with the hashbang in it", () => { @@ -2880,6 +3307,7 @@ var a = "test2"; it("should report a violation with a useful parse error prefix", () => { const messages = linter.verify(code); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); @@ -2888,6 +3316,8 @@ var a = "test2"; assert.strictEqual(messages[0].column, 4); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:/u); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report source code where the issue is present", () => { @@ -2898,11 +3328,14 @@ var a = "test2"; "}" ]; const messages = linter.verify(inValidCode.join("\n")); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:/u); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -2969,9 +3402,12 @@ var a = "test2"; it("should report the new rule", () => { const results = linter.verify(code, { rules: { "no-comma-dangle": 2 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(results[0].ruleId, "no-comma-dangle"); assert.strictEqual(results[0].message, "Rule 'no-comma-dangle' was removed and replaced by: comma-dangle"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -3015,8 +3451,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation when using Promise", () => { @@ -3025,8 +3463,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -3037,11 +3477,14 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-undef"); assert.strictEqual(messages[0].nodeType, "Identifier"); assert.strictEqual(messages[0].line, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3050,8 +3493,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); // https://github.com/eslint/eslint/issues/14652 @@ -3065,8 +3510,10 @@ var a = "test2"; for (const code of codes) { const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); } }); @@ -3077,8 +3524,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3087,8 +3536,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3097,8 +3548,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3107,8 +3560,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3117,8 +3572,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3127,8 +3584,10 @@ var a = "test2"; const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation", () => { @@ -3137,8 +3596,10 @@ var a = "test2"; const config = { rules: { "no-undef": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -3157,9 +3618,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation for global variable declarations", () => { @@ -3212,9 +3676,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation for rule changes", () => { @@ -3232,8 +3699,10 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation for disable-line", () => { @@ -3250,9 +3719,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation for env changes", () => { @@ -3265,9 +3737,12 @@ var a = "test2"; } }; const messages = linter.verify(code, config, { allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-undef"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -3286,12 +3761,15 @@ var a = "test2"; // eslint-disable-next-line no-loop-func -- No closures it(`should warn '/* ${directive} */' if 'noInlineConfig' was given.`, () => { const messages = linter.verify(`/* ${directive} */`, { noInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.deepStrictEqual(messages[0].fatal, void 0); assert.deepStrictEqual(messages[0].ruleId, null); assert.deepStrictEqual(messages[0].severity, 1); assert.deepStrictEqual(messages[0].message, `'/*${directive.split(" ")[0]}*/' has no effect because you have 'noInlineConfig' setting in your config.`); + + assert.strictEqual(suppressedMessages.length, 0); }); } @@ -3302,19 +3780,24 @@ var a = "test2"; // eslint-disable-next-line no-loop-func -- No closures it(`should warn '// ${directive}' if 'noInlineConfig' was given.`, () => { const messages = linter.verify(`// ${directive}`, { noInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.deepStrictEqual(messages[0].fatal, void 0); assert.deepStrictEqual(messages[0].ruleId, null); assert.deepStrictEqual(messages[0].severity, 1); assert.deepStrictEqual(messages[0].message, `'//${directive.split(" ")[0]}' has no effect because you have 'noInlineConfig' setting in your config.`); + + assert.strictEqual(suppressedMessages.length, 0); }); } it("should not warn if 'noInlineConfig' and '--no-inline-config' were given.", () => { const messages = linter.verify("/* globals foo */", { noInlineConfig: true }, { allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -3372,8 +3855,11 @@ var a = "test2"; describe("reportUnusedDisable option", () => { it("reports problems for unused eslint-disable comments", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: true }), + messages, [ { ruleId: null, @@ -3389,11 +3875,75 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); + }); + + it("reports problems for multiple eslint-disable comments, including unused ones", () => { + const code = [ + "/* eslint-disable no-alert -- j1 */", + "alert(\"test\"); //eslint-disable-line no-alert -- j2" + ].join("\n"); + const config = { + rules: { + "no-alert": 2 + } + }; + const messages = linter.verify(code, config, { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].suppressions.length, 2); + }); + + it("reports problems for eslint-disable-line and eslint-disable-next-line comments, including unused ones", () => { + const code = [ + "// eslint-disable-next-line no-alert -- j1 */", + "alert(\"test\"); //eslint-disable-line no-alert -- j2" + ].join("\n"); + const config = { + rules: { + "no-alert": 2 + } + }; + const messages = linter.verify(code, config, { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].suppressions.length, 2); + }); + + it("reports problems for multiple unused eslint-disable comments with mutliple ruleIds", () => { + const code = [ + "/* eslint no-undef: 2, no-void: 2 */", + "/* eslint-disable no-undef -- j1 */", + "void foo; //eslint-disable-line no-undef, no-void -- j2" + ].join("\n"); + const config = { + rules: { + "no-undef": 2, + "no-void": 2 + } + }; + const messages = linter.verify(code, config, { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-void"); + assert.strictEqual(suppressedMessages[0].suppressions.length, 1); + assert.strictEqual(suppressedMessages[1].ruleId, "no-undef"); + assert.strictEqual(suppressedMessages[1].suppressions.length, 2); }); it("reports problems for unused eslint-disable comments (error)", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "error" }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "error" }), + messages, [ { ruleId: null, @@ -3409,11 +3959,16 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for unused eslint-disable comments (warn)", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "warn" }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "warn" }), + messages, [ { ruleId: null, @@ -3429,11 +3984,16 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for unused eslint-disable comments (in config)", () => { + const messages = linter.verify("/* eslint-disable */", { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", { reportUnusedDisableDirectives: true }), + messages, [ { ruleId: null, @@ -3449,6 +4009,8 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for partially unused eslint-disable comments (in config)", () => { @@ -3465,6 +4027,7 @@ var a = "test2"; filename, allowInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual( messages, @@ -3483,6 +4046,9 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); describe("autofix", () => { @@ -4059,8 +4625,12 @@ var a = "test2"; filename, allowInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); }); @@ -4170,6 +4740,7 @@ var a = "test2"; const config = { rules: { "no-mixed-spaces-and-tabs": 1, "eol-last": 1, semi: [1, "always"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); assert.strictEqual(messages[0].line, 1); @@ -4178,22 +4749,28 @@ var a = "test2"; assert.strictEqual(messages[1].column, 18); assert.strictEqual(messages[2].line, 2); assert.strictEqual(messages[2].column, 18); + + assert.strictEqual(suppressedMessages.length, 0); }); describe("ecmaVersion", () => { it("should not support ES6 when no ecmaVersion provided", () => { const messages = linter.verify("let x = 0;"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("supports ECMAScript version 'latest'", () => { const messages = linter.verify("let x = 5 ** 7;", { parserOptions: { ecmaVersion: "latest" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("the 'latest' is equal to espree.latestEcmaVersion", () => { @@ -4314,8 +4891,10 @@ var a = "test2"; ecmaVersion: 6 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("the ECMAScript version number is 2015", () => { @@ -4324,8 +4903,10 @@ var a = "test2"; ecmaVersion: 2015 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -4335,8 +4916,10 @@ var a = "test2"; ecmaVersion: 2015 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); describe("should properly parse exponentiation operator when", () => { @@ -4346,8 +4929,10 @@ var a = "test2"; ecmaVersion: 7 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("the ECMAScript version number is 2016", () => { @@ -4356,8 +4941,10 @@ var a = "test2"; ecmaVersion: 2016 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); }); @@ -4369,8 +4956,10 @@ var a = "test2"; ecmaVersion: 2018 } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse global return when passed ecmaFeatures", () => { @@ -4382,8 +4971,10 @@ var a = "test2"; } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse global return when in Node.js environment", () => { @@ -4393,8 +4984,10 @@ var a = "test2"; node: true } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not parse global return when in Node.js environment with globalReturn explicitly off", () => { @@ -4409,24 +5002,32 @@ var a = "test2"; } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Parsing error: 'return' outside of function"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not parse global return when Node.js environment is false", () => { const messages = linter.verify("return;", {}, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Parsing error: 'return' outside of function"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse sloppy-mode code when impliedStrict is false", () => { const messages = linter.verify("var private;", {}, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not parse sloppy-mode code when impliedStrict is true", () => { @@ -4438,9 +5039,12 @@ var a = "test2"; } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Parsing error: The keyword 'private' is reserved"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse valid code when impliedStrict is true", () => { @@ -4452,8 +5056,10 @@ var a = "test2"; } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse JSX when passed ecmaFeatures", () => { @@ -4465,69 +5071,89 @@ var a = "test2"; } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report an error when JSX code is encountered and JSX is not enabled", () => { const code = "var myDivElement =
;"; const messages = linter.verify(code, {}, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].line, 1); assert.strictEqual(messages[0].column, 20); assert.strictEqual(messages[0].message, "Parsing error: Unexpected token <"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error when JSX code is encountered and JSX is enabled", () => { const code = "var myDivElement =
;"; const messages = linter.verify(code, { parserOptions: { ecmaFeatures: { jsx: true } } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error when JSX code contains a spread operator and JSX is enabled", () => { const code = "var myDivElement =
;"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 6, ecmaFeatures: { jsx: true } } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not allow the use of reserved words as variable names in ES3", () => { const code = "var char;"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:.*'char'/u); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not allow the use of reserved words as property names in member expressions in ES3", () => { const code = "obj.char;"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:.*'char'/u); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not allow the use of reserved words as property names in object literals in ES3", () => { const code = "var obj = { char: 1 };"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3 } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:.*'char'/u); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should allow the use of reserved words as variable and property names in ES3 when allowReserved is true", () => { const code = "var char; obj.char; var obj = { char: 1 };"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 3, allowReserved: true } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not allow the use of reserved words as variable names in ES > 3", () => { @@ -4536,11 +5162,14 @@ var a = "test2"; ecmaVersions.forEach(ecmaVersion => { const code = "var enum;"; const messages = linter.verify(code, { parserOptions: { ecmaVersion } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:.*'enum'/u); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -4550,8 +5179,10 @@ var a = "test2"; ecmaVersions.forEach(ecmaVersion => { const code = "obj.enum; obj.function; var obj = { enum: 1, function: 2 };"; const messages = linter.verify(code, { parserOptions: { ecmaVersion } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -4561,11 +5192,14 @@ var a = "test2"; ecmaVersions.forEach(ecmaVersion => { const code = ""; const messages = linter.verify(code, { parserOptions: { ecmaVersion, allowReserved: true } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:.*allowReserved/u); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -4594,14 +5228,18 @@ var a = "test2"; ].join("\n"); const messages = linter.verify(code, null, "eslint-env es6"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should be able to return in global if there is a comment which enables the node environment with a comment", () => { const messages = linter.verify(`/* ${ESLINT_ENV} node */ return;`, null, "node environment"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should attach a \"/*global\" comment node to declared variables", () => { @@ -4645,6 +5283,7 @@ var a = "test2"; it("should report a linting error when a global is set to an invalid value", () => { const results = linter.verify("/* global foo: AAAAA, bar: readonly */\nfoo;\nbar;", { rules: { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(results, [ { @@ -4669,6 +5308,8 @@ var a = "test2"; nodeType: "Identifier" } ]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not crash when we reuse the SourceCode object", () => { @@ -4704,8 +5345,10 @@ var a = "test2"; "obj.await", { parserOptions: { ecmaVersion: 6, sourceType: "module" } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert(result.length === 0); + assert.strictEqual(suppressedMessages.length, 0); }); @@ -4738,6 +5381,7 @@ var a = "test2"; /*eslint aaa:error -- bbb:error */ console.log("hello") `, {}); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -4745,6 +5389,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*eslint-env*/'.", () => { @@ -4753,6 +5399,7 @@ var a = "test2"; var Promise = {} var Atomics = {} `, { rules: { "no-redeclare": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `Atomics` assert.deepStrictEqual( @@ -4769,6 +5416,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*global*/'.", () => { @@ -4777,6 +5426,7 @@ var a = "test2"; var aaa = {} var bbb = {} `, { rules: { "no-redeclare": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `bbb` assert.deepStrictEqual( @@ -4793,6 +5443,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*globals*/'.", () => { @@ -4801,6 +5453,7 @@ var a = "test2"; var aaa = {} var bbb = {} `, { rules: { "no-redeclare": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `bbb` assert.deepStrictEqual( @@ -4817,6 +5470,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*exported*/'.", () => { @@ -4825,6 +5480,7 @@ var a = "test2"; var aaa = {} var bbb = {} `, { rules: { "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `aaa` assert.deepStrictEqual( @@ -4841,6 +5497,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*eslint-disable*/'.", () => { @@ -4849,6 +5507,7 @@ var a = "test2"; var aaa = {} var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -4865,6 +5524,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 4, + endColumn: 28, + line: 4, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-enable*/'.", () => { @@ -4874,6 +5549,7 @@ var a = "test2"; var aaa = {} var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-redeclare` but not `no-unused-vars` assert.deepStrictEqual( @@ -4890,6 +5566,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is assigned a value but never used.", + messageId: "unusedVar", + nodeType: "Identifier", + ruleId: "no-unused-vars", + severity: 2, + suppressions: [{ kind: "directive", justification: "" }] + }] + ); }); it("should ignore the part preceded by '--' in '//eslint-disable-line'.", () => { @@ -4897,6 +5589,7 @@ var a = "test2"; var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -4913,6 +5606,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 3, + endColumn: 28, + line: 3, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-disable-line*/'.", () => { @@ -4920,6 +5629,7 @@ var a = "test2"; var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */ var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */ `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -4936,6 +5646,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 3, + endColumn: 28, + line: 3, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '//eslint-disable-next-line'.", () => { @@ -4945,6 +5671,7 @@ var a = "test2"; //eslint-disable-next-line no-redeclare -- no-unused-vars var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -4961,6 +5688,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-disable-next-line*/'.", () => { @@ -4970,6 +5713,7 @@ var a = "test2"; /*eslint-disable-next-line no-redeclare -- no-unused-vars */ var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -4986,6 +5730,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should not ignore the part preceded by '--' if the '--' is not surrounded by whitespaces.", () => { @@ -4996,12 +5756,15 @@ var a = "test2"; /*eslint a--rule:error */ console.log("hello") `, {}); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); // Use `a--rule`. assert.strictEqual(rule.callCount, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' even if the '--' is longer than 2.", () => { @@ -5014,6 +5777,7 @@ var a = "test2"; /*eslint aaa:error -------- bbb:error */ console.log("hello") `, {}); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -5021,6 +5785,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' with line breaks.", () => { @@ -5035,6 +5801,7 @@ var a = "test2"; bbb:error */ console.log("hello") `, {}); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -5042,6 +5809,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); }); }); @@ -5658,6 +6427,7 @@ var a = "test2"; }); const messages = linter.verify("var a = 1;", { rules: { "rule-with-suggestions": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages[0].suggestions, [{ desc: "Insert space at the beginning", @@ -5672,6 +6442,8 @@ var a = "test2"; text: " " } }]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("supports messageIds for suggestions", () => { @@ -5701,6 +6473,7 @@ var a = "test2"; }); const messages = linter.verify("var a = 1;", { rules: { "rule-with-suggestions": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages[0].suggestions, [{ messageId: "suggestion1", @@ -5717,6 +6490,8 @@ var a = "test2"; text: " " } }]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should throw an error if suggestion is passed but `meta.hasSuggestions` property is not enabled", () => { @@ -6124,38 +6899,52 @@ var a = "test2"; it("should properly parse import statements when sourceType is module", () => { const code = "import foo from 'foo';"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 6, sourceType: "module" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse import all statements when sourceType is module", () => { const code = "import * as foo from 'foo';"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 6, sourceType: "module" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse default export statements when sourceType is module", () => { const code = "export default function initialize() {}"; const messages = linter.verify(code, { parserOptions: { ecmaVersion: 6, sourceType: "module" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); // https://github.com/eslint/eslint/issues/9687 it("should report an error when invalid parserOptions found", () => { let messages = linter.verify("", { parserOptions: { ecmaVersion: 222 } }); + let suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.ok(messages[0].message.includes("Invalid ecmaVersion")); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify("", { parserOptions: { sourceType: "foo" } }); + suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual(messages.length, 1); assert.ok(messages[0].message.includes("Invalid sourceType")); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify("", { parserOptions: { ecmaVersion: 5, sourceType: "module" } }); + suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual(messages.length, 1); assert.ok(messages[0].message.includes("sourceType 'module' is not supported when ecmaVersion < 2015")); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not crash when invalid parentheses syntax is encountered", () => { @@ -6172,9 +6961,12 @@ var a = "test2"; it("should report syntax error when a keyword exists in object property shorthand", () => { const messages = linter.verify("let a = {this}", { parserOptions: { ecmaVersion: 6 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].fatal, true); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not rewrite env setting in core (https://github.com/eslint/eslint/issues/4814)", () => { @@ -6229,17 +7021,22 @@ var a = "test2"; linter.defineParser("esprima", esprima); const messages = linter.verify(code, { parser: "esprima", parserOptions: { jsx: true } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should return an error when the custom parser can't be found", () => { const code = "var myDivElement =
;"; const messages = linter.verify(code, { parser: "esprima-xyz" }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, "Configured parser 'esprima-xyz' was not found."); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or report errors when the custom parser returns unrecognized operators (https://github.com/eslint/eslint/issues/10475)", () => { @@ -6249,8 +7046,10 @@ var a = "test2"; // This shouldn't throw const messages = linter.verify(code, { parser: "unknown-logical-operator" }, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or report errors when the custom parser returns nested unrecognized operators (https://github.com/eslint/eslint/issues/10560)", () => { @@ -6260,8 +7059,10 @@ var a = "test2"; // This shouldn't throw const messages = linter.verify(code, { parser: "unknown-logical-operator-nested" }, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or return errors when the custom parser returns unknown AST nodes", () => { @@ -6283,27 +7084,36 @@ var a = "test2"; "collect-node-types": "error" } }, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); assert.isTrue(nodes.length > 0); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should strip leading line: prefix from parser error", () => { linter.defineParser("line-error", testParsers.lineError); const messages = linter.verify(";", { parser: "line-error" }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, errorPrefix + testParsers.lineError.expectedError); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not modify a parser error message without a leading line: prefix", () => { linter.defineParser("no-line-error", testParsers.noLineError); const messages = linter.verify(";", { parser: "no-line-error" }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, errorPrefix + testParsers.noLineError.expectedError); + + assert.strictEqual(suppressedMessages.length, 0); }); describe("if a parser provides 'visitorKeys'", () => { @@ -6427,8 +7237,10 @@ var a = "test2"; it("should not pass any default parserOptions to the parser", () => { linter.defineParser("throws-with-options", testParsers.throwsWithOptions); const messages = linter.verify(";", { parser: "throws-with-options" }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -6447,9 +7259,11 @@ var a = "test2"; }; const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); // no parsing errors assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); }); @@ -6497,9 +7311,12 @@ describe("Linter with FlatConfigArray", () => { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "There should be one linting error."); assert.strictEqual(messages[0].ruleId, "no-undef", "The linting error should be no-undef."); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should error when accessing a global that isn't available in ecmaVersion 3", () => { @@ -6512,9 +7329,12 @@ describe("Linter with FlatConfigArray", () => { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "There should be one linting error."); assert.strictEqual(messages[0].ruleId, "no-undef", "The linting error should be no-undef."); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should add globals for ES6 when ecmaVersion is 6", () => { @@ -6526,8 +7346,10 @@ describe("Linter with FlatConfigArray", () => { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "There should be no linting errors."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should allow destructuring when ecmaVersion is 6", () => { @@ -6536,8 +7358,10 @@ describe("Linter with FlatConfigArray", () => { ecmaVersion: 6 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "There should be no linting errors."); + assert.strictEqual(suppressedMessages.length, 0); }); it("ecmaVersion should be normalized to year name for ES 6", () => { @@ -6700,8 +7524,10 @@ describe("Linter with FlatConfigArray", () => { sourceType: "module" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "There should no linting errors."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should error when return is used at the top-level outside of commonjs", () => { @@ -6711,9 +7537,12 @@ describe("Linter with FlatConfigArray", () => { sourceType: "script" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "There should be one parsing error."); assert.strictEqual(messages[0].message, "Parsing error: 'return' outside of function"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not error when top-level return is used in commonjs", () => { @@ -6723,8 +7552,10 @@ describe("Linter with FlatConfigArray", () => { sourceType: "commonjs" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "There should no linting errors."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should error when accessing a Node.js global outside of commonjs", () => { @@ -6736,9 +7567,12 @@ describe("Linter with FlatConfigArray", () => { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "There should be one linting error."); assert.strictEqual(messages[0].ruleId, "no-undef", "The linting error should be no-undef."); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should add globals for Node.js when sourceType is commonjs", () => { @@ -6751,8 +7585,10 @@ describe("Linter with FlatConfigArray", () => { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "There should be no linting errors."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should allow 'await' as a property name in modules", () => { @@ -6765,8 +7601,10 @@ describe("Linter with FlatConfigArray", () => { } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert(result.length === 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -6804,8 +7642,10 @@ describe("Linter with FlatConfigArray", () => { const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should pass parser as context.languageOptions.parser to all rules when provided on config", () => { @@ -6846,8 +7686,10 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should expose parser services when using parseForESLint() and services are specified", () => { @@ -6879,9 +7721,12 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hi!"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should use the same parserServices if source code object is reused", () => { @@ -6913,14 +7758,18 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hi!"); + assert.strictEqual(suppressedMessages.length, 0); const messages2 = linter.verify(linter.getSourceCode(), config, filename); + const suppressedMessages2 = linter.getSuppressedMessages(); assert.strictEqual(messages2.length, 1); assert.strictEqual(messages2[0].message, "Hi!"); + assert.strictEqual(suppressedMessages2.length, 0); }); it("should pass parser as context.languageOptions.parser to all rules when default parser is used", () => { @@ -6986,8 +7835,10 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or report errors when the custom parser returns unrecognized operators (https://github.com/eslint/eslint/issues/10475)", () => { @@ -7000,8 +7851,10 @@ describe("Linter with FlatConfigArray", () => { // This shouldn't throw const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or report errors when the custom parser returns nested unrecognized operators (https://github.com/eslint/eslint/issues/10560)", () => { @@ -7014,8 +7867,10 @@ describe("Linter with FlatConfigArray", () => { // This shouldn't throw const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not throw or return errors when the custom parser returns unknown AST nodes", () => { @@ -7042,9 +7897,11 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); assert.isTrue(nodes.length > 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should strip leading line: prefix from parser error", () => { @@ -7053,10 +7910,13 @@ describe("Linter with FlatConfigArray", () => { parser: testParsers.lineError } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, errorPrefix + testParsers.lineError.expectedError); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not modify a parser error message without a leading line: prefix", () => { @@ -7065,10 +7925,13 @@ describe("Linter with FlatConfigArray", () => { parser: testParsers.noLineError } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.strictEqual(messages[0].message, errorPrefix + testParsers.noLineError.expectedError); + + assert.strictEqual(suppressedMessages.length, 0); }); describe("if a parser provides 'visitorKeys'", () => { @@ -7330,9 +8193,12 @@ describe("Linter with FlatConfigArray", () => { } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Parsing error: The keyword 'private' is reserved"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse valid code when impliedStrict is true", () => { @@ -7346,8 +8212,10 @@ describe("Linter with FlatConfigArray", () => { } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse JSX when passed ecmaFeatures", () => { @@ -7361,18 +8229,23 @@ describe("Linter with FlatConfigArray", () => { } } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report an error when JSX code is encountered and JSX is not enabled", () => { const code = "var myDivElement =
;"; const messages = linter.verify(code, {}, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].line, 1); assert.strictEqual(messages[0].column, 20); assert.strictEqual(messages[0].message, "Parsing error: Unexpected token <"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error when JSX code is encountered and JSX is enabled", () => { @@ -7385,10 +8258,11 @@ describe("Linter with FlatConfigArray", () => { } } } - }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error when JSX code contains a spread operator and JSX is enabled", () => { @@ -7404,8 +8278,10 @@ describe("Linter with FlatConfigArray", () => { } }, "filename"); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not allow the use of reserved words as variable names in ES3", () => { @@ -7524,9 +8400,7 @@ describe("Linter with FlatConfigArray", () => { assert.match(messages[0].message, /^Parsing error:.*allowReserved/u); }); }); - }); - }); describe("settings", () => { @@ -7555,9 +8429,12 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].message, "Hello"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not have any settings if they were not passed in", () => { @@ -7584,8 +8461,10 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -7599,9 +8478,12 @@ describe("Linter with FlatConfigArray", () => { config.rules[rule] = 1; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by only setting the string value", () => { @@ -7611,10 +8493,13 @@ describe("Linter with FlatConfigArray", () => { config.rules[rule] = "warn"; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by passing in values as an array", () => { @@ -7624,9 +8509,12 @@ describe("Linter with FlatConfigArray", () => { config.rules[rule] = [1]; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should be configurable by passing in string value as an array", () => { @@ -7636,10 +8524,13 @@ describe("Linter with FlatConfigArray", () => { config.rules[rule] = ["warn"]; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 1); assert.strictEqual(messages[0].ruleId, rule); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not be configurable by setting other value", () => { @@ -7656,8 +8547,10 @@ describe("Linter with FlatConfigArray", () => { it("should process empty config", () => { const config = {}; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -7671,6 +8564,7 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-mixed-spaces-and-tabs": 1, "eol-last": 1, semi: [1, "always"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); assert.strictEqual(messages[0].line, 1); @@ -7679,6 +8573,8 @@ describe("Linter with FlatConfigArray", () => { assert.strictEqual(messages[1].column, 18); assert.strictEqual(messages[2].line, 2); assert.strictEqual(messages[2].column, 18); + + assert.strictEqual(suppressedMessages.length, 0); }); describe("Plugins", () => { @@ -7825,6 +8721,7 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify(code, config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); sinon.assert.calledOnce(spyVariableDeclaration); @@ -7832,6 +8729,8 @@ describe("Linter with FlatConfigArray", () => { sinon.assert.calledOnce(spyIdentifier); sinon.assert.calledTwice(spyLiteral); sinon.assert.calledOnce(spyBinaryExpression); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should throw an error if a rule reports a problem without a message", () => { @@ -7888,8 +8787,10 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, filename); + assert.strictEqual(suppressedMessages.length, 0); }); it("defaults filename to ''", () => { @@ -7913,8 +8814,10 @@ describe("Linter with FlatConfigArray", () => { const messages = linter.verify("0", config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, ""); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -7942,8 +8845,10 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("0", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages[0].message, filename); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -9710,9 +10615,12 @@ describe("Linter with FlatConfigArray", () => { configs.normalizeSync(); const messages = linter.verify("foo", configs, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "Message length is wrong"); assert.strictEqual(messages[0].ruleId, ruleId); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rule should run as warning when set to 1 with a plain array", () => { @@ -9725,9 +10633,12 @@ describe("Linter with FlatConfigArray", () => { }]; const messages = linter.verify("foo", configs, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "Message length is wrong"); assert.strictEqual(messages[0].ruleId, ruleId); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rule should run as warning when set to 1 with an object", () => { @@ -9740,9 +10651,12 @@ describe("Linter with FlatConfigArray", () => { }; const messages = linter.verify("foo", config, filename, true); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "Message length is wrong"); assert.strictEqual(messages[0].ruleId, ruleId); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -9752,11 +10666,14 @@ describe("Linter with FlatConfigArray", () => { it("should preserve line numbers", () => { const config = { rules: { "no-extra-semi": 1 } }; const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-extra-semi"); assert.strictEqual(messages[0].nodeType, "EmptyStatement"); assert.strictEqual(messages[0].line, 3); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should have a comment with the hashbang in it", () => { @@ -10172,6 +11089,7 @@ describe("Linter with FlatConfigArray", () => { it("should report a linting error when a global is set to an invalid value", () => { const results = linter.verify("/* global foo: AAAAA, bar: readonly */\nfoo;\nbar;", { rules: { "no-undef": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(results, [ { @@ -10196,6 +11114,8 @@ describe("Linter with FlatConfigArray", () => { nodeType: "Identifier" } ]); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10370,11 +11290,14 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -10387,11 +11310,16 @@ describe("Linter with FlatConfigArray", () => { const codeA = "/*eslint strict: 0*/ function bar() { return 2; }"; const codeB = "function foo() { return 1; }"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -10404,11 +11332,16 @@ describe("Linter with FlatConfigArray", () => { const codeA = "/*eslint quotes: 0*/ function bar() { return '2'; }"; const codeB = "function foo() { return '1'; }"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -10416,11 +11349,16 @@ describe("Linter with FlatConfigArray", () => { const codeA = "/*eslint quotes: [0, \"single\"]*/ function bar() { return '2'; }"; const codeB = "function foo() { return '1'; }"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); it("rules should not change initial config", () => { @@ -10433,18 +11371,26 @@ describe("Linter with FlatConfigArray", () => { const codeA = "/*eslint no-unused-vars: [0, {\"vars\": \"local\"}]*/ var a = 44;"; const codeB = "var b = 55;"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); }); describe("when evaluating code with invalid comments to enable rules", () => { it("should report a violation when the config is not a valid rule configuration", () => { + const messages = linter.verify("/*eslint no-alert:true*/ alert('test');", {}); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/*eslint no-alert:true*/ alert('test');", {}), + messages, [ { severity: 2, @@ -10458,11 +11404,16 @@ describe("Linter with FlatConfigArray", () => { } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation when the config violates a rule's schema", () => { + const messages = linter.verify("/* eslint no-alert: [error, {nonExistentPropertyName: true}]*/", {}); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint no-alert: [error, {nonExistentPropertyName: true}]*/", {}), + messages, [ { severity: 2, @@ -10476,6 +11427,8 @@ describe("Linter with FlatConfigArray", () => { } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10484,37 +11437,49 @@ describe("Linter with FlatConfigArray", () => { it("should not report a violation", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify("/*eslint no-alert:0*/ alert('test');", config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report an error when disabling a non-existent rule in inline comment", () => { let code = "/*eslint foo:0*/ ;"; let messages = linter.verify(code, {}, filename); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "/*eslint*/ comment should report problem."); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "/*eslint-disable*/ comment should report problem."); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable-line foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "/*eslint-disable-line*/ comment should report problem."); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); code = "/*eslint-disable-next-line foo*/ ;"; messages = linter.verify(code, {}, filename); + suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1, "/*eslint-disable-next-line*/ comment should report problem."); assert.strictEqual(messages[0].message, "Definition for rule 'foo' was not found."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report an error, when disabling a non-existent rule in config", () => { const messages = linter.verify("", { rules: { foo: 0 } }, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should throw an error when a non-existent rule in config", () => { @@ -10536,12 +11501,15 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: {} }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10552,11 +11520,14 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-console": 1, "no-alert": 0 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10590,8 +11561,10 @@ describe("Linter with FlatConfigArray", () => { const code = "/*eslint test-plugin/test-rule: 2*/ var a = \"no violation\";"; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation when inline comment disables plugin rule", () => { @@ -10599,8 +11572,10 @@ describe("Linter with FlatConfigArray", () => { const config = { ...baseConfig, rules: { "test-plugin/test-rule": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation when the report is right before the comment", () => { @@ -10624,9 +11599,12 @@ describe("Linter with FlatConfigArray", () => { }; const problems = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 1); assert.strictEqual(problems[0].message, "foo"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation when the report is right at the start of the comment", () => { @@ -10650,8 +11628,13 @@ describe("Linter with FlatConfigArray", () => { }; const problems = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].message, "foo"); + assert.deepStrictEqual(suppressedMessages[0].suppressions, [{ kind: "directive", justification: "" }]); }); it("rules should not change initial config", () => { @@ -10659,11 +11642,16 @@ describe("Linter with FlatConfigArray", () => { const codeA = "/*eslint test-plugin/test-rule: 0*/ var a = \"trigger violation\";"; const codeB = "var a = \"trigger violation\";"; let messages = linter.verify(codeA, config, filename, false); + let suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); messages = linter.verify(codeB, config, filename, false); + suppressedMessages = linter.getSuppressedMessages(); + assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10679,12 +11667,17 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); assert.strictEqual(messages[0].line, 4); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); }); it("should not report a violation", () => { @@ -10696,8 +11689,10 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 2); }); it("should not report a violation", () => { @@ -10710,10 +11705,15 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].column, 21); assert.strictEqual(messages[1].column, 19); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].column, 1); + assert.strictEqual(suppressedMessages[1].column, 56); }); it("should report a violation", () => { @@ -10731,8 +11731,10 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); + assert.strictEqual(suppressedMessages.length, 2); }); @@ -10746,8 +11748,12 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-unused-vars": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-unused-vars"); }); it("should not report a violation", () => { @@ -10759,8 +11765,12 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-unused-vars": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-unused-vars"); }); }); @@ -10771,11 +11781,14 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-console": 1, "no-alert": 0 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].message, "Unexpected alert."); assert.include(messages[0].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10786,11 +11799,14 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { quotes: [2, "single"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "quotes"); assert.strictEqual(messages[0].message, "Strings must use doublequote."); assert.include(messages[0].nodeType, "Literal"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10801,11 +11817,14 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { quotes: [2, "single"] } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "quotes"); assert.strictEqual(messages[0].message, "Strings must use doublequote."); assert.include(messages[0].nodeType, "Literal"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10816,6 +11835,7 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -10833,6 +11853,8 @@ describe("Linter with FlatConfigArray", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -10841,6 +11863,7 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -10858,6 +11881,8 @@ describe("Linter with FlatConfigArray", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -10866,6 +11891,7 @@ describe("Linter with FlatConfigArray", () => { const config = { rules: { "no-alert": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); @@ -10883,6 +11909,8 @@ describe("Linter with FlatConfigArray", () => { assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].message, "Unexpected alert."); assert.include(messages[1].nodeType, "CallExpression"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10894,11 +11922,14 @@ alert('test'); it("should not parse errors, should report a violation", () => { const messages = linter.verify(code, {}, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "max-len"); assert.strictEqual(messages[0].message, "This line has a length of 129. Maximum allowed is 100."); assert.include(messages[0].nodeType, "Program"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10914,6 +11945,7 @@ var a = "test2"; const config = { rules: {} }; const messages = linter.verify(code, config, filename); const [message1, message2] = messages; + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(message1.ruleId, "max-len"); @@ -10926,6 +11958,8 @@ var a = "test2"; assert.strictEqual(message2.line, 5); assert.strictEqual(message2.column, 1); assert.include(message2.nodeType, "Program"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -10941,10 +11975,13 @@ var a = "test2"; const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should report no violation", () => { @@ -10956,8 +11993,10 @@ var a = "test2"; const config = { rules: { quotes: 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation", () => { @@ -10973,31 +12012,42 @@ var a = "test2"; const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); assert.strictEqual(messages[1].ruleId, "no-console"); assert.strictEqual(messages[1].line, 6); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); }); it("should report a violation", () => { const code = [ "/*eslint-disable no-alert */", "alert('test');", - "console.log('test');", + "console.log('test');", // here "/*eslint-enable no-console */", - - "alert('test');" // here + "alert('test');" ].join("\n"); const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].line, 5); }); @@ -11014,11 +12064,19 @@ var a = "test2"; const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); + + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); @@ -11044,21 +12102,23 @@ var a = "test2"; const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 4); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 6); - assert.strictEqual(messages[1].ruleId, "no-console"); assert.strictEqual(messages[1].line, 7); - assert.strictEqual(messages[2].ruleId, "no-alert"); assert.strictEqual(messages[2].line, 9); - assert.strictEqual(messages[3].ruleId, "no-console"); assert.strictEqual(messages[3].line, 10); + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 3); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 4); }); it("should report a violation", () => { @@ -11081,18 +12141,23 @@ var a = "test2"; const config = { rules: { "no-alert": 1, "no-console": 1 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); - assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].line, 8); - assert.strictEqual(messages[2].ruleId, "no-console"); assert.strictEqual(messages[2].line, 9); + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); it("should report a violation when severity is warn", () => { @@ -11115,18 +12180,23 @@ var a = "test2"; const config = { rules: { "no-alert": "warn", "no-console": "warn" } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 3); - assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[0].line, 5); - assert.strictEqual(messages[1].ruleId, "no-alert"); assert.strictEqual(messages[1].line, 8); - assert.strictEqual(messages[2].ruleId, "no-console"); assert.strictEqual(messages[2].line, 9); + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 3); + assert.strictEqual(suppressedMessages[2].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[2].line, 6); }); it("should report no violation", () => { @@ -11139,8 +12209,15 @@ var a = "test2"; const config = { rules: { "no-unused-vars": 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-unused-vars"); + assert.strictEqual(suppressedMessages[0].line, 2); + assert.strictEqual(suppressedMessages[1].ruleId, "no-unused-vars"); + assert.strictEqual(suppressedMessages[1].line, 3); }); }); @@ -11160,10 +12237,15 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-console"); + assert.strictEqual(messages[0].line, 2); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 1); }); it("should report a violation", () => { @@ -11180,10 +12262,17 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); - assert.strictEqual(messages[0].ruleId, "no-alert"); + assert.strictEqual(messages[0].line, 3); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[0].line, 1); + assert.strictEqual(suppressedMessages[1].ruleId, "no-console"); + assert.strictEqual(suppressedMessages[1].line, 2); }); it("should report a violation if eslint-disable-line in a block comment is not on a single line", () => { @@ -11199,10 +12288,12 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not disable rule and add an extra report if eslint-disable-line in a block comment is not on a single line", () => { @@ -11217,6 +12308,7 @@ var a = "test2"; }; const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages, [ { @@ -11241,6 +12333,8 @@ var a = "test2"; nodeType: null } ]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation for eslint-disable-line in block comment", () => { @@ -11255,8 +12349,10 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 2); }); it("should not report a violation", () => { @@ -11272,8 +12368,10 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 2); }); it("should not report a violation", () => { @@ -11291,8 +12389,10 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); it("should not report a violation", () => { @@ -11310,8 +12410,10 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); it("should ignore violations of multiple rules when specified in mixed comments", () => { @@ -11325,8 +12427,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); }); it("should report no violation", () => { @@ -11340,8 +12447,10 @@ var a = "test2"; const config = { rules: { "no-unused-vars": 2 } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 5); }); }); @@ -11360,9 +12469,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => { @@ -11378,9 +12491,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violation of specified rule if eslint-disable-next-line is a block comment", () => { const code = [ @@ -11393,8 +12510,12 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should not ignore violation if code is not on next line", () => { @@ -11408,9 +12529,12 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore violation if block comment span multiple lines", () => { @@ -11425,8 +12549,12 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); // For https://github.com/eslint/eslint/issues/14284 @@ -11444,8 +12572,12 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore violations only of specified rule", () => { @@ -11461,10 +12593,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore violations only of specified rule when block comment span multiple lines", () => { @@ -11501,9 +12636,14 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); }); it("should ignore violations of multiple rules when specified in multiple lines", () => { @@ -11540,8 +12680,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 2); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); }); it("should ignore violations of multiple rules when specified in mixed sinlge line and multi line comments", () => { @@ -11576,10 +12721,14 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "quotes"); }); it("should ignore violations of specified rule on next line only", () => { @@ -11596,10 +12745,14 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should ignore all rule violations on next line if none specified", () => { @@ -11617,9 +12770,15 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 3); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.strictEqual(suppressedMessages[1].ruleId, "quotes"); + assert.strictEqual(suppressedMessages[2].ruleId, "semi"); }); it("should ignore violations if eslint-disable-next-line is a block comment", () => { @@ -11636,10 +12795,14 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("should report a violation", () => { @@ -11657,10 +12820,12 @@ var a = "test2"; }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); - assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not ignore violations if comment is of the type hashbang", () => { @@ -11676,10 +12841,13 @@ var a = "test2"; } }; const messages = linter.verify(code, config, filename); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 2); assert.strictEqual(messages[0].ruleId, "no-alert"); assert.strictEqual(messages[1].ruleId, "no-console"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -11702,6 +12870,7 @@ var a = "test2"; /*eslint test/aaa:error -- test/bbb:error */ console.log("hello") `, config); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -11709,6 +12878,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*globals*/'.", () => { @@ -11722,6 +12893,7 @@ var a = "test2"; }, rules: { "no-redeclare": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `bbb` assert.deepStrictEqual( @@ -11738,6 +12910,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*exported*/'.", () => { @@ -11751,6 +12925,7 @@ var a = "test2"; }, rules: { "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include `aaa` assert.deepStrictEqual( @@ -11767,6 +12942,8 @@ var a = "test2"; severity: 2 }] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' in '/*eslint-disable*/'.", () => { @@ -11775,6 +12952,7 @@ var a = "test2"; var aaa = {} var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -11791,6 +12969,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endColumn: 28, + endLine: 4, + line: 4, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-enable*/'.", () => { @@ -11800,6 +12994,7 @@ var a = "test2"; var aaa = {} var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-redeclare` but not `no-unused-vars` assert.deepStrictEqual( @@ -11816,6 +13011,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is assigned a value but never used.", + messageId: "unusedVar", + nodeType: "Identifier", + ruleId: "no-unused-vars", + severity: 2, + suppressions: [{ kind: "directive", justification: "" }] + }] + ); }); it("should ignore the part preceded by '--' in '//eslint-disable-line'.", () => { @@ -11823,6 +13034,7 @@ var a = "test2"; var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars var aaa = {} //eslint-disable-line no-redeclare -- no-unused-vars `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -11839,6 +13051,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 3, + endColumn: 28, + line: 3, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-disable-line*/'.", () => { @@ -11846,6 +13074,7 @@ var a = "test2"; var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */ var aaa = {} /*eslint-disable-line no-redeclare -- no-unused-vars */ `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -11862,6 +13091,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 3, + endColumn: 28, + line: 3, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '//eslint-disable-next-line'.", () => { @@ -11871,6 +13116,7 @@ var a = "test2"; //eslint-disable-next-line no-redeclare -- no-unused-vars var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -11887,6 +13133,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should ignore the part preceded by '--' in '/*eslint-disable-next-line*/'.", () => { @@ -11896,6 +13158,7 @@ var a = "test2"; /*eslint-disable-next-line no-redeclare -- no-unused-vars */ var aaa = {} `, { rules: { "no-redeclare": "error", "no-unused-vars": "error" } }); + const suppressedMessages = linter.getSuppressedMessages(); // Do include `no-unused-vars` but not `no-redeclare` assert.deepStrictEqual( @@ -11912,6 +13175,22 @@ var a = "test2"; severity: 2 }] ); + + assert.deepStrictEqual( + suppressedMessages, + [{ + column: 25, + endLine: 5, + endColumn: 28, + line: 5, + message: "'aaa' is already defined.", + messageId: "redeclared", + nodeType: "Identifier", + ruleId: "no-redeclare", + severity: 2, + suppressions: [{ kind: "directive", justification: "no-unused-vars" }] + }] + ); }); it("should not ignore the part preceded by '--' if the '--' is not surrounded by whitespaces.", () => { @@ -11930,12 +13209,15 @@ var a = "test2"; /*eslint test/a--rule:error */ console.log("hello") `, config); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); // Use `a--rule`. assert.strictEqual(rule.callCount, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' even if the '--' is longer than 2.", () => { @@ -11956,6 +13238,7 @@ var a = "test2"; /*eslint test/aaa:error -------- test/bbb:error */ console.log("hello") `, config); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -11963,6 +13246,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should ignore the part preceded by '--' with line breaks.", () => { @@ -11985,6 +13270,7 @@ var a = "test2"; test/bbb:error */ console.log("hello") `, config); + const suppressedMessages = linter.getSuppressedMessages(); // Don't include syntax error of the comment. assert.deepStrictEqual(messages, []); @@ -11992,6 +13278,8 @@ var a = "test2"; // Use only `aaa`. assert.strictEqual(aaa.callCount, 1); assert.strictEqual(bbb.callCount, 0); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -12011,9 +13299,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation for global variable declarations", () => { @@ -12069,9 +13360,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not report a violation for rule changes", () => { @@ -12089,8 +13383,10 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); it("should report a violation for disable-line", () => { @@ -12107,9 +13403,12 @@ var a = "test2"; filename, allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].ruleId, "no-alert"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -12132,12 +13431,15 @@ var a = "test2"; noInlineConfig: true } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.deepStrictEqual(messages[0].fatal, void 0); assert.deepStrictEqual(messages[0].ruleId, null); assert.deepStrictEqual(messages[0].severity, 1); assert.deepStrictEqual(messages[0].message, `'/*${directive.split(" ")[0]}*/' has no effect because you have 'noInlineConfig' setting in your config.`); + + assert.strictEqual(suppressedMessages.length, 0); }); } @@ -12152,12 +13454,15 @@ var a = "test2"; noInlineConfig: true } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.deepStrictEqual(messages[0].fatal, void 0); assert.deepStrictEqual(messages[0].ruleId, null); assert.deepStrictEqual(messages[0].severity, 1); assert.deepStrictEqual(messages[0].message, `'//${directive.split(" ")[0]}' has no effect because you have 'noInlineConfig' setting in your config.`); + + assert.strictEqual(suppressedMessages.length, 0); }); } @@ -12167,8 +13472,10 @@ var a = "test2"; noInlineConfig: true } }, { allowInlineConfig: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 0); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -12187,8 +13494,12 @@ var a = "test2"; filename, allowInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); }); @@ -12196,8 +13507,11 @@ var a = "test2"; describe("reportUnusedDisableDirectives option", () => { it("reports problems for unused eslint-disable comments", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: true }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: true }), + messages, [ { ruleId: null, @@ -12213,11 +13527,16 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for unused eslint-disable comments (error)", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "error" }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "error" }), + messages, [ { ruleId: null, @@ -12233,11 +13552,16 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for unused eslint-disable comments (warn)", () => { + const messages = linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "warn" }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", {}, { reportUnusedDisableDirectives: "warn" }), + messages, [ { ruleId: null, @@ -12253,15 +13577,20 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for unused eslint-disable comments (in config)", () => { + const messages = linter.verify("/* eslint-disable */", { + linterOptions: { + reportUnusedDisableDirectives: true + } + }); + const suppressedMessages = linter.getSuppressedMessages(); + assert.deepStrictEqual( - linter.verify("/* eslint-disable */", { - linterOptions: { - reportUnusedDisableDirectives: true - } - }), + messages, [ { ruleId: null, @@ -12277,6 +13606,8 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 0); }); it("reports problems for partially unused eslint-disable comments (in config)", () => { @@ -12295,6 +13626,7 @@ var a = "test2"; filename, allowInlineConfig: true }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual( messages, @@ -12313,6 +13645,9 @@ var a = "test2"; } ] ); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); }); it("reports problems for unused eslint-disable-next-line comments (in config)", () => { @@ -13115,6 +14450,7 @@ var a = "test2"; }; const messages = linter.verify("var a = 1;", config); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages[0].suggestions, [{ desc: "Insert space at the beginning", @@ -13129,6 +14465,8 @@ var a = "test2"; text: " " } }]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("supports messageIds for suggestions", () => { @@ -13170,6 +14508,7 @@ var a = "test2"; }; const messages = linter.verify("var a = 1;", config); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages[0].suggestions, [{ messageId: "suggestion1", @@ -13186,6 +14525,8 @@ var a = "test2"; text: " " } }]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should throw an error if suggestion is passed but `meta.hasSuggestions` property is not enabled", () => { @@ -13258,6 +14599,7 @@ var a = "test2"; it("should report a violation with a useful parse error prefix", () => { const messages = linter.verify(code); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); @@ -13266,6 +14608,8 @@ var a = "test2"; assert.strictEqual(messages[0].column, 4); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:/u); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should report source code where the issue is present", () => { @@ -13276,11 +14620,14 @@ var a = "test2"; "}" ]; const messages = linter.verify(inValidCode.join("\n")); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].severity, 2); assert.isTrue(messages[0].fatal); assert.match(messages[0].message, /^Parsing error:/u); + + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -13324,6 +14671,55 @@ var a = "test2"; }); + describe("getSuppressedMessages()", () => { + it("should have no suppressed messages", () => { + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(suppressedMessages.length, 0); + }); + + it("should have a suppressed message", () => { + const code = "/* eslint-disable no-alert -- justification */\nalert(\"test\");"; + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [{ kind: "directive", justification: "justification" }] + ); + }); + + it("should have a suppressed message", () => { + const code = [ + "/* eslint-disable no-alert -- j1", + " * j2", + " */", + "alert(\"test\");" + ].join("\n"); + const config = { + rules: { "no-alert": 1 } + }; + const messages = linter.verify(code, config); + const suppressedMessages = linter.getSuppressedMessages(); + + assert.strictEqual(messages.length, 0); + + assert.strictEqual(suppressedMessages.length, 1); + assert.strictEqual(suppressedMessages[0].ruleId, "no-alert"); + assert.deepStrictEqual( + suppressedMessages[0].suppressions, + [{ kind: "directive", justification: "j1\n * j2" }] + ); + }); + }); + describe("defineRule()", () => { it("should throw an error when called in flat config mode", () => { assert.throws(() => { @@ -13372,9 +14768,12 @@ var a = "test2"; semi: 2 } }, { filename: "test.js" }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.output, "var a;", "Fixes were applied correctly"); assert.isTrue(messages.fixed); + + assert.strictEqual(suppressedMessages.length, 0); }); it("does not require a third argument", () => { @@ -13383,12 +14782,15 @@ var a = "test2"; semi: 2 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(fixResult, { fixed: true, messages: [], output: "var a;" }); + + assert.strictEqual(suppressedMessages.length, 0); }); it("does not include suggestions in autofix results", () => { @@ -13398,10 +14800,13 @@ var a = "test2"; "no-useless-escape": 2 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(fixResult.output, "var foo = /\\#/;"); assert.strictEqual(fixResult.fixed, true); assert.strictEqual(fixResult.messages[0].suggestions.length > 0, true); + + assert.strictEqual(suppressedMessages.length, 0); }); it("does not apply autofixes when fix argument is `false`", () => { @@ -13410,8 +14815,10 @@ var a = "test2"; semi: 2 } }, { fix: false }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(fixResult.fixed, false); + assert.strictEqual(suppressedMessages.length, 0); }); it("stops fixing after 10 passes", () => { @@ -13445,10 +14852,13 @@ var a = "test2"; }; const fixResult = linter.verifyAndFix("a", config); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(fixResult.fixed, true); assert.strictEqual(fixResult.output, `${" ".repeat(10)}a`); assert.strictEqual(fixResult.messages.length, 1); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should throw an error if fix is passed but meta has no `fixable` property", () => { @@ -13647,9 +15057,12 @@ var a = "test2"; } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 3); assert.deepStrictEqual(problems.map(problem => problem.message), ["foo", "bar", "baz"]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should apply a preprocessor to the code even if the preprocessor returned code block objects.", () => { @@ -13676,10 +15089,13 @@ var a = "test2"; } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 3); assert.deepStrictEqual(problems.map(problem => problem.message), ["foo", "bar", "baz"]); + assert.strictEqual(suppressedMessages.length, 0); + // filename assert.strictEqual(receivedFilenames.length, 3); assert(/^filename\.js[/\\]0_block\.js/u.test(receivedFilenames[0])); @@ -13786,10 +15202,13 @@ var a = "test2"; } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(problems.length, 3); assert.deepStrictEqual(problems.map(problem => problem.message), ["FOO", "BAR", "BAZ"]); assert.deepStrictEqual(problems.map(problem => problem.column), [1, 5, 9]); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should use postprocessed problem ranges when applying autofixes", () => { @@ -13856,10 +15275,13 @@ var a = "test2"; } } ); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(fixResult.fixed, true); assert.strictEqual(fixResult.messages.length, 0); assert.strictEqual(fixResult.output, "FOO BAR BAZ"); + + assert.strictEqual(suppressedMessages.length, 0); }); }); }); @@ -13877,22 +15299,28 @@ var a = "test2"; it("should properly parse import statements when sourceType is module", () => { const code = "import foo from 'foo';"; const messages = linter.verify(code, moduleConfig); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "Unexpected linting error."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse import all statements when sourceType is module", () => { const code = "import * as foo from 'foo';"; const messages = linter.verify(code, moduleConfig); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "Unexpected linting error."); + assert.strictEqual(suppressedMessages.length, 0); }); it("should properly parse default export statements when sourceType is module", () => { const code = "export default function initialize() {}"; const messages = linter.verify(code, moduleConfig); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 0, "Unexpected linting error."); + assert.strictEqual(suppressedMessages.length, 0); }); }); @@ -13911,9 +15339,12 @@ var a = "test2"; messages = linter.verify("", { languageOptions: { ecmaVersion: 5, sourceType: "module" } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.deepStrictEqual(messages.length, 1); assert.ok(messages[0].message.includes("sourceType 'module' is not supported when ecmaVersion < 2015")); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not crash when invalid parentheses syntax is encountered", () => { @@ -13930,9 +15361,12 @@ var a = "test2"; it("should report syntax error when a keyword exists in object property shorthand", () => { const messages = linter.verify("let a = {this}", { languageOptions: { ecmaVersion: 6 } }); + const suppressedMessages = linter.getSuppressedMessages(); assert.strictEqual(messages.length, 1); assert.strictEqual(messages[0].fatal, true); + + assert.strictEqual(suppressedMessages.length, 0); }); it("should not crash when we reuse the SourceCode object", () => {