Node.js API
While ESLint is designed to be run on the command line, it's possible to use ESLint programmatically through the Node.js API. The purpose of the Node.js API is to allow plugin and tool authors to use the ESLint functionality directly, without going through the command line interface.
Note: Use undocumented parts of the API at your own risk. Only those parts that are specifically mentioned in this document are approved for use and will remain stable and reliable. Anything left undocumented is unstable and may change or be removed at any point.
Table of Contents
ESLint class
The ESLint
class is the primary class to use in Node.js applications.
This class depends on the Node.js fs
module and the file system, so you cannot use it in browsers. If you want to lint code on browsers, use the Linter class instead.
Here's a simple example of using the ESLint
class:
const { ESLint } = require("eslint");
(async function main() {
// 1. Create an instance.
const eslint = new ESLint();
// 2. Lint files.
const results = await eslint.lintFiles(["lib/**/*.js"]);
// 3. Format the results.
const formatter = await eslint.loadFormatter("stylish");
const resultText = formatter.format(results);
// 4. Output it.
console.log(resultText);
})().catch((error) => {
process.exitCode = 1;
console.error(error);
});
And here is an example that autofixes lint problems:
const { ESLint } = require("eslint");
(async function main() {
// 1. Create an instance with the `fix` option.
const eslint = new ESLint({ fix: true });
// 2. Lint files. This doesn't modify target files.
const results = await eslint.lintFiles(["lib/**/*.js"]);
// 3. Modify the files with the fixed code.
await ESLint.outputFixes(results);
// 4. Format the results.
const formatter = await eslint.loadFormatter("stylish");
const resultText = formatter.format(results);
// 5. Output it.
console.log(resultText);
})().catch((error) => {
process.exitCode = 1;
console.error(error);
});
◆ new ESLint(options)
const eslint = new ESLint(options);
Create a new ESLint
instance.
Parameters
The ESLint
constructor takes an options
object. If you omit the options
object then it uses default values for all options. The options
object has the following properties.
File Enumeration
options.cwd
(string
)
Default isprocess.cwd()
. The working directory. This must be an absolute path.options.errorOnUnmatchedPattern
(boolean
)
Default istrue
. Unless set tofalse
, theeslint.lintFiles()
method will throw an error when no target files are found.options.extensions
(string[] | null
)
Default isnull
. If you pass directory paths to theeslint.lintFiles()
method, ESLint checks the files in those directories that have the given extensions. For example, when passing thesrc/
directory andextensions
is[".js", ".ts"]
, ESLint will lint*.js
and*.ts
files insrc/
. Ifextensions
isnull
, ESLint checks*.js
files and files that matchoverrides[].files
patterns in your configuration.
Note: This option only applies when you pass directory paths to theeslint.lintFiles()
method. If you pass glob patterns likelib/**/*
, ESLint will lint all files matching the glob pattern regardless of extension.options.globInputPaths
(boolean
)
Default istrue
. Iffalse
is present, theeslint.lintFiles()
method doesn't interpret glob patterns.options.ignore
(boolean
)
Default istrue
. Iffalse
is present, theeslint.lintFiles()
method doesn't respect.eslintignore
files orignorePatterns
in your configuration.options.ignorePath
(string | null
)
Default isnull
. The path to a file ESLint uses instead of$CWD/.eslintignore
. If a path is present and the file doesn't exist, this constructor will throw an error.
Linting
options.allowInlineConfig
(boolean
)
Default istrue
. Iffalse
is present, ESLint suppresses directive comments in source code. If this option isfalse
, it overrides thenoInlineConfig
setting in your configurations.options.baseConfig
(ConfigData | null
)
Default isnull
. Configuration object, extended by all configurations used with this instance. You can use this option to define the default settings that will be used if your configuration files don't configure it.options.overrideConfig
(ConfigData | null
)
Default isnull
. Configuration object, overrides all configurations used with this instance. You can use this option to define the settings that will be used even if your configuration files configure it.options.overrideConfigFile
(string | null
)
Default isnull
. The path to a configuration file, overrides all configurations used with this instance. Theoptions.overrideConfig
option is applied after this option is applied.options.plugins
(Record<string, Plugin> | null
)
Default isnull
. The plugin implementations that ESLint uses for theplugins
setting of your configuration. This is a map-like object. Those keys are plugin IDs and each value is implementation.options.reportUnusedDisableDirectives
("error" | "warn" | "off" | null
)
Default isnull
. The severity to report unused eslint-disable directives. If this option is a severity, it overrides thereportUnusedDisableDirectives
setting in your configurations.options.resolvePluginsRelativeTo
(string
|null
)
Default isnull
. The path to a directory where plugins should be resolved from. Ifnull
is present, ESLint loads plugins from the location of the configuration file that contains the plugin setting. If a path is present, ESLint loads all plugins from there.options.rulePaths
(string[]
)
Default is[]
. An array of paths to directories to load custom rules from.options.useEslintrc
(boolean
)
Default istrue
. Iffalse
is present, ESLint doesn't load configuration files (.eslintrc.*
files). Only the configuration of the constructor options is valid.
Autofix
options.fix
(boolean | (message: LintMessage) => boolean
)
Default isfalse
. Iftrue
is present, theeslint.lintFiles()
andeslint.lintText()
methods work in autofix mode. If a predicate function is present, the methods pass each lint message to the function, then use only the lint messages for which the function returnedtrue
.options.fixTypes
(("directive" | "problem" | "suggestion" | "layout")[] | null
)
Default isnull
. The types of the rules that theeslint.lintFiles()
andeslint.lintText()
methods use for autofix.
Cache-related
options.cache
(boolean
)
Default isfalse
. Iftrue
is present, theeslint.lintFiles()
method caches lint results and uses it if each target file is not changed. Please mind that ESLint doesn't clear the cache when you upgrade ESLint plugins. In that case, you have to remove the cache file manually. Theeslint.lintText()
method doesn't use caches even if you pass theoptions.filePath
to the method.options.cacheLocation
(string
)
Default is.eslintcache
. Theeslint.lintFiles()
method writes caches into this file.options.cacheStrategy
(string
)
Default is"metadata"
. Strategy for the cache to use for detecting changed files. Can be either"metadata"
or"content"
.
◆ eslint.lintFiles(patterns)
const results = await eslint.lintFiles(patterns);
This method lints the files that match the glob patterns and then returns the results.
Parameters
patterns
(string | string[]
)
The lint target files. This can contain any of file paths, directory paths, and glob patterns.
Return Value
- (
Promise<LintResult[]>
)
The promise that will be fulfilled with an array of LintResult objects.
◆ eslint.lintText(code, options)
const results = await eslint.lintText(code, options);
This method lints the given source code text and then returns the results.
By default, this method uses the configuration that applies to files in the current working directory (the cwd
constructor option). If you want to use a different configuration, pass options.filePath
, and ESLint will load the same configuration that eslint.lintFiles()
would use for a file at options.filePath
.
If the options.filePath
value is configured to be ignored, this method returns an empty array. If the options.warnIgnored
option is set along with the options.filePath
option, this method returns a LintResult object. In that case, the result may contain a warning that indicates the file was ignored.
Parameters
The second parameter options
is omittable.
code
(string
)
The source code text to check.options.filePath
(string
)
Optional. The path to the file of the source code text. If omitted, theresult.filePath
becomes the string"<text>"
.options.warnIgnored
(boolean
)
Optional. Iftrue
is present and theoptions.filePath
is a file ESLint should ignore, this method returns a lint result contains a warning message.
Return Value
- (
Promise<LintResult[]>
)
The promise that will be fulfilled with an array of LintResult objects. This is an array (despite there being only one lint result) in order to keep the interfaces between this and theeslint.lintFiles()
method similar.
◆ eslint.getRulesMetaForResults(results)
const results = await eslint.lintFiles(patterns);
const rulesMeta = eslint.getRulesMetaForResults(results);
This method returns an object containing meta information for each rule that triggered a lint error in the given results
.
Parameters
results
(LintResult[]
)
An array of LintResult objects returned from a call toESLint#lintFiles()
orESLint#lintText()
.
Return Value
- (
Object
)
An object whose property names are the rule IDs from theresults
and whose property values are the rule's meta information (if available).
◆ eslint.calculateConfigForFile(filePath)
const config = await eslint.calculateConfigForFile(filePath);
This method calculates the configuration for a given file, which can be useful for debugging purposes.
- It resolves and merges
extends
andoverrides
settings into the top level configuration. - It resolves the
parser
setting to absolute paths. - It normalizes the
plugins
setting to align short names. (e.g.,eslint-plugin-foo
→foo
) - It adds the
processor
setting if a legacy file extension processor is matched. - It doesn't interpret the
env
setting to theglobals
andparserOptions
settings, so the result object contains theenv
setting as is.
Parameters
filePath
(string
)
The path to the file whose configuration you would like to calculate. Directory paths are forbidden because ESLint cannot handle theoverrides
setting.
Return Value
- (
Promise<Object>
)
The promise that will be fulfilled with a configuration object.
◆ eslint.isPathIgnored(filePath)
const isPathIgnored = await eslint.isPathIgnored(filePath);
This method checks if a given file is ignored by your configuration.
Parameters
filePath
(string
)
The path to the file you want to check.
Return Value
- (
Promise<boolean>
)
The promise that will be fulfilled with whether the file is ignored or not. If the file is ignored, then it will returntrue
.
◆ eslint.loadFormatter(nameOrPath)
const formatter = await eslint.loadFormatter(nameOrPath);
This method loads a formatter. Formatters convert lint results to a human- or machine-readable string.
Parameters
nameOrPath
(string | undefined
)
The path to the file you want to check. The following values are allowed:undefined
. In this case, loads the"stylish"
built-in formatter.- A name of built-in formatters.
- A name of third-party formatters. For examples:
"foo"
will loadeslint-formatter-foo
."@foo"
will load@foo/eslint-formatter
."@foo/bar"
will load@foo/eslint-formatter-bar
.
- A path to the file that defines a formatter. The path must contain one or more path separators (
/
) in order to distinguish if it's a path or not. For example, start with./
.
Return Value
- (
Promise<LoadedFormatter>
)
The promise that will be fulfilled with a LoadedFormatter object.
◆ ESLint.version
const version = ESLint.version;
The version string of ESLint. E.g. "7.0.0"
.
This is a static property.
◆ ESLint.outputFixes(results)
await ESLint.outputFixes(results);
This method writes code modified by ESLint's autofix feature into its respective file. If any of the modified files don't exist, this method does nothing.
This is a static method.
Parameters
results
(LintResult[]
)
The LintResult objects to write.
Return Value
- (
Promise<void>
)
The promise that will be fulfilled after all files are written.
◆ ESLint.getErrorResults(results)
const filteredResults = ESLint.getErrorResults(results);
This method copies the given results and removes warnings. The returned value contains only errors.
This is a static method.
Parameters
results
(LintResult[]
)
The LintResult objects to filter.
Return Value
- (
LintResult[]
)
The filtered LintResult objects.
◆ LintResult type
The LintResult
value is the information of the linting result of each file. The eslint.lintFiles()
and eslint.lintText()
methods return it. It has the following properties:
filePath
(string
)
The absolute path to the file of this result. This is the string"<text>"
if the file path is unknown (when you didn't pass theoptions.filePath
option to theeslint.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 thefix
constructor option.fixableWarningCount
(number
)
The number of warnings that can be fixed automatically by thefix
constructor option.errorCount
(number
)
The number of errors. This includes fixable errors and fatal errors.fatalErrorCount
(number
)
The number of fatal errors.warningCount
(number
)
The number of warnings. This includes fixable warnings.output
(string | undefined
)
The modified source code text. This property is undefined if any fixable messages didn't exist.source
(string | undefined
)
The original source code text. This property is undefined if any messages didn't exist or theoutput
property exists.usedDeprecatedRules
({ ruleId: string; replacedBy: string[] }[]
)
The information about the deprecated rules that were used to check this file.
◆ LintMessage type
The LintMessage
value is the information of each linting error. The messages
property of the LintResult type contains it. It has the following properties:
ruleId
(string
|null
)
The rule name that generates this lint message. If this message is generated by the ESLint core rather than rules, this isnull
.severity
(1 | 2
)
The severity of this message.1
means warning and2
means error.fatal
(boolean | undefined
)true
if this is a fatal error unrelated to a rule, like a parsing error.message
(string
)
The error message.line
(number | undefined
)
The 1-based line number of the begin point of this message.column
(number | undefined
)
The 1-based column number of the begin point of this message.endLine
(number | undefined
)
The 1-based line number of the end point of this message. This property is undefined if this message is not a range.endColumn
(number | undefined
)
The 1-based column number of the end point of this message. This property is undefined if this message is not a range.fix
(EditInfo | undefined
)
The EditInfo object of autofix. This property is undefined if this message is not fixable.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 asruleId
in LintMessage type.severity
(1 | 2
)
Same asseverity
in LintMessage type.fatal
(boolean | undefined
)
Same asfatal
in LintMessage type.message
(string
)
Same asmessage
in LintMessage type.line
(number | undefined
)
Same asline
in LintMessage type.column
(number | undefined
)
Same ascolumn
in LintMessage type.endLine
(number | undefined
)
Same asendLine
in LintMessage type.endColumn
(number | undefined
)
Same asendColumn
in LintMessage type.fix
(EditInfo | undefined
)
Same asfix
in LintMessage type.suggestions
({ desc: string; fix: EditInfo }[] | undefined
)
Same assuggestions
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:
range
([number, number]
)
The pair of 0-based indices in source code text to remove.text
(string
)
The text to add.
This edit information means replacing the range of the range
property by the text
property value. It's like sourceCodeText.slice(0, edit.range[0]) + edit.text + sourceCodeText.slice(edit.range[1])
. Therefore, it's an add if the range[0]
and range[1]
property values are the same value, and it's removal if the text
property value is empty string.
◆ LoadedFormatter type
The LoadedFormatter
value is the object to convert the LintResult objects to text. The eslint.loadFormatter() method returns it. It has the following method:
format
((results: LintResult[]) => string | Promise<string>
)
The method to convert the LintResult objects to text.
SourceCode
The SourceCode
type represents the parsed source code that ESLint executes on. It's used internally in ESLint and is also available so that already-parsed code can be used. You can create a new instance of SourceCode
by passing in the text string representing the code and an abstract syntax tree (AST) in ESTree format (including location information, range information, comments, and tokens):
const SourceCode = require("eslint").SourceCode;
const code = new SourceCode("var foo = bar;", ast);
The SourceCode
constructor throws an error if the AST is missing any of the required information.
The SourceCode
constructor strips Unicode BOM. Please note the AST also should be parsed from stripped text.
const SourceCode = require("eslint").SourceCode;
const code = new SourceCode("\uFEFFvar foo = bar;", ast);
assert(code.hasBOM === true);
assert(code.text === "var foo = bar;");
SourceCode#splitLines()
This is a static function on SourceCode
that is used to split the source code text into an array of lines.
const SourceCode = require("eslint").SourceCode;
const code = "var a = 1;\nvar b = 2;"
// split code into an array
const codeLines = SourceCode.splitLines(code);
/*
Value of codeLines will be
[
"var a = 1;",
"var b = 2;"
]
*/
Linter
The Linter
object does the actual evaluation of the JavaScript code. It doesn't do any filesystem operations, it simply parses and reports on the code. In particular, the Linter
object does not process configuration objects or files. Unless you are working in the browser, you probably want to use the ESLint class class instead.
The Linter
is a constructor, and you can create a new instance by passing in the options you want to use. The available options are:
cwd
- Path to a directory that should be considered as the current working directory. It is accessible to rules by callingcontext.getCwd()
(see The Context Object). Ifcwd
isundefined
, it will be normalized toprocess.cwd()
if the globalprocess
object is defined (for example, in the Node.js runtime) , orundefined
otherwise.
For example:
const Linter = require("eslint").Linter;
const linter1 = new Linter({ cwd: 'path/to/project' });
const linter2 = new Linter();
In this example, rules run on linter1
will get path/to/project
when calling context.getCwd()
. Those run on linter2
will get process.cwd()
if the global process
object is defined or undefined
otherwise (e.g. on the browser https://eslint.org/demo).
Linter#verify
The most important method on Linter
is verify()
, which initiates linting of the given text. This method accepts three arguments:
code
- the source code to lint (a string or instance ofSourceCode
).config
- a configuration object that has been processed and normalized byESLint
using eslintrc files and/or other configuration arguments.- Note: If you want to lint text and have your configuration be read and processed, use
ESLint#lintFiles()
orESLint#lintText()
instead.
- Note: If you want to lint text and have your configuration be read and processed, use
options
- (optional) Additional options for this run.filename
- (optional) the filename to associate with the source code.preprocess
- (optional) A function that Processors in Plugins documentation describes as thepreprocess
method.postprocess
- (optional) A function that Processors in Plugins documentation describes as thepostprocess
method.filterCodeBlock
- (optional) A function that decides which code blocks the linter should adopt. The function receives two arguments. The first argument is the virtual filename of a code block. The second argument is the text of the code block. If the function returnedtrue
then the linter adopts the code block. If the function was omitted, the linter adopts only*.js
code blocks. If you provided afilterCodeBlock
function, it overrides this default behavior, so the linter doesn't adopt*.js
code blocks automatically.disableFixes
- (optional) when set totrue
, the linter doesn't make either thefix
orsuggestions
property of the lint result.allowInlineConfig
- (optional) set tofalse
to disable inline comments from changing ESLint rules.reportUnusedDisableDirectives
- (optional) when set totrue
, adds reported errors for unusedeslint-disable
directives when no problems would be reported in the disabled area anyway.
If the third argument is a string, it is interpreted as the filename
.
You can call verify()
like this:
const Linter = require("eslint").Linter;
const linter = new Linter();
const messages = linter.verify("var foo;", {
rules: {
semi: 2
}
}, { filename: "foo.js" });
// or using SourceCode
const Linter = require("eslint").Linter,
linter = new Linter(),
SourceCode = require("eslint").SourceCode;
const code = new SourceCode("var foo = bar;", ast);
const messages = linter.verify(code, {
rules: {
semi: 2
}
}, { filename: "foo.js" });
The verify()
method returns an array of objects containing information about the linting warnings and errors. Here's an example:
{
fatal: false,
ruleId: "semi",
severity: 2,
line: 1,
column: 23,
message: "Expected a semicolon.",
fix: {
range: [1, 15],
text: ";"
}
}
The information available for each linting message is:
column
- the column on which the error occurred.fatal
- usually omitted, but will be set to true if there's a parsing error (not related to a rule).line
- the line on which the error occurred.message
- the message that should be output.nodeType
- the node or token type that was reported with the problem.ruleId
- the ID of the rule that triggered the messages (or null iffatal
is true).severity
- either 1 or 2, depending on your configuration.endColumn
- the end column of the range on which the error occurred (this property is omitted if it's not range).endLine
- the end line of the range on which the error occurred (this property is omitted if it's not range).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).
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.
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:
const Linter = require("eslint").Linter;
const linter = new Linter();
const messages = linter.verify("var foo = bar;", {
rules: {
semi: 2
}
}, { filename: "foo.js" });
const code = linter.getSourceCode();
console.log(code.text); // "var foo = bar;"
In this way, you can retrieve the text and AST used for the last run of linter.verify()
.
Linter#verifyAndFix()
This method is similar to verify except that it also runs autofixing logic, similar to the --fix
flag on the command line. The result object will contain the autofixed code, along with any remaining linting messages for the code that were not autofixed.
const Linter = require("eslint").Linter;
const linter = new Linter();
const messages = linter.verifyAndFix("var foo", {
rules: {
semi: 2
}
});
Output object from this method:
{
fixed: true,
output: "var foo;",
messages: []
}
The information available is:
fixed
- True, if the code was fixed.output
- Fixed code text (might be the same as input if no fixes were applied).messages
- Collection of all messages for the given code (It has the same information as explained above underverify
block).
Linter#defineRule
Each Linter
instance holds a map of rule names to loaded rule objects. By default, all ESLint core rules are loaded. If you want to use Linter
with custom rules, you should use the defineRule
method to register your rules by ID.
const Linter = require("eslint").Linter;
const linter = new Linter();
linter.defineRule("my-custom-rule", {
// (an ESLint rule)
create(context) {
// ...
}
});
const results = linter.verify("// some source text", { rules: { "my-custom-rule": "error" } });
Linter#defineRules
This is a convenience method similar to Linter#defineRule
, except that it allows you to define many rules at once using an object.
const Linter = require("eslint").Linter;
const linter = new Linter();
linter.defineRules({
"my-custom-rule": { /* an ESLint rule */ create() {} },
"another-custom-rule": { /* an ESLint rule */ create() {} }
});
const results = linter.verify("// some source text", {
rules: {
"my-custom-rule": "error",
"another-custom-rule": "warn"
}
});
Linter#getRules
This method returns a map of all loaded rules.
const Linter = require("eslint").Linter;
const linter = new Linter();
linter.getRules();
/*
Map {
'accessor-pairs' => { meta: { docs: [Object], schema: [Array] }, create: [Function: create] },
'array-bracket-newline' => { meta: { docs: [Object], schema: [Array] }, create: [Function: create] },
...
}
*/
Linter#defineParser
Each instance of Linter
holds a map of custom parsers. If you want to define a parser programmatically, you can add this function with the name of the parser as first argument and the parser object as second argument. The default "espree"
parser will already be loaded for every Linter
instance.
const Linter = require("eslint").Linter;
const linter = new Linter();
linter.defineParser("my-custom-parser", {
parse(code, options) {
// ...
}
});
const results = linter.verify("// some source text", { parser: "my-custom-parser" });
Linter#version/Linter.version
Each instance of Linter
has a version
property containing the semantic version number of ESLint that the Linter
instance is from.
const Linter = require("eslint").Linter;
const linter = new Linter();
linter.version; // => '4.5.0'
There is also a Linter.version
property that you can read without instantiating Linter
:
const Linter = require("eslint").Linter;
Linter.version; // => '4.5.0'
RuleTester
eslint.RuleTester
is a utility to write tests for ESLint rules. It is used internally for the bundled rules that come with ESLint, and it can also be used by plugins.
Example usage:
"use strict";
const rule = require("../../../lib/rules/my-rule"),
RuleTester = require("eslint").RuleTester;
const ruleTester = new RuleTester();
ruleTester.run("my-rule", rule, {
valid: [
{
code: "var foo = true",
options: [{ allowFoo: true }]
}
],
invalid: [
{
code: "var invalidVariable = true",
errors: [{ message: "Unexpected invalid variable." }]
},
{
code: "var invalidVariable = true",
errors: [{ message: /^Unexpected.+variable/ }]
}
]
});
The RuleTester
constructor accepts an optional object argument, which can be used to specify defaults for your test cases. For example, if all of your test cases use ES2015, you can set it as a default:
const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 2015 } });
The RuleTester#run()
method is used to run the tests. It should be passed the following arguments:
- The name of the rule (string)
- The rule object itself (see "working with rules")
- An object containing
valid
andinvalid
properties, each of which is an array containing test cases.
A test case is an object with the following properties:
name
(string, optional): The name to use for the test case, to make it easier to findcode
(string, required): The source code that the rule should be run onoptions
(array, optional): The options passed to the rule. The rule severity should not be included in this list.filename
(string, optional): The filename for the given case (useful for rules that make assertions about filenames).only
(boolean, optional): Run this case exclusively for debugging in supported test frameworks.
In addition to the properties above, invalid test cases can also have the following properties:
errors
(number or array, required): Asserts some properties of the errors that the rule is expected to produce when run on this code. If this is a number, asserts the number of errors produced. Otherwise, this should be a list of objects, each containing information about a single reported error. The following properties can be used for an error (all are optional):message
(string/regexp): The message for the errormessageId
(string): The Id for the error. See testing errors with messageId for detailsdata
(object): Placeholder data which can be used in combination withmessageId
type
(string): The type of the reported AST nodeline
(number): The 1-based line number of the reported locationcolumn
(number): The 1-based column number of the reported locationendLine
(number): The 1-based line number of the end of the reported locationendColumn
(number): The 1-based column number of the end of the reported locationsuggestions
(array): An array of objects with suggestion details to check. See Testing Suggestions for details
If a string is provided as an error instead of an object, the string is used to assert the
message
of the error.output
(string, required if the rule fixes code): Asserts the output that will be produced when using this rule for a single pass of autofixing (e.g. with the--fix
command line flag). If this isnull
, asserts that none of the reported problems suggest autofixes.
Any additional properties of a test case will be passed directly to the linter as config options. For example, a test case can have a parserOptions
property to configure parser behavior:
{
code: "let foo;",
parserOptions: { ecmaVersion: 2015 }
}
If a valid test case only uses the code
property, it can optionally be provided as a string containing the code, rather than an object with a code
key.
Testing errors with messageId
If the rule under test uses messageId
s, you can use messageId
property in a test case to assert reported error's messageId
instead of its message
.
{
code: "let foo;",
errors: [{ messageId: "unexpected" }]
}
For messages with placeholders, a test case can also use data
property to additionally assert reported error's message
.
{
code: "let foo;",
errors: [{ messageId: "unexpected", data: { name: "foo" } }]
}
Please note that data
in a test case does not assert data
passed to context.report
. Instead, it is used to form the expected message text which is then compared with the received message
.
Testing Suggestions
Suggestions can be tested by defining a suggestions
key on an errors object. The options to check for the suggestions are the following (all are optional):
desc
(string): The suggestiondesc
valuemessageId
(string): The suggestionmessageId
value for suggestions that usemessageId
sdata
(object): Placeholder data which can be used in combination withmessageId
output
(string): A code string representing the result of applying the suggestion fix to the input code
Example:
ruleTester.run("my-rule-for-no-foo", rule, {
valid: [],
invalid: [{
code: "var foo;",
errors: [{
suggestions: [{
desc: "Rename identifier 'foo' to 'bar'",
output: "var bar;"
}]
}]
}]
})
messageId
and data
properties in suggestion test objects work the same way as in error test objects. See testing errors with messageId for details.
ruleTester.run("my-rule-for-no-foo", rule, {
valid: [],
invalid: [{
code: "var foo;",
errors: [{
suggestions: [{
messageId: "renameFoo",
data: { newName: "bar" },
output: "var bar;"
}]
}]
}]
})
Customizing RuleTester
RuleTester
depends on two functions to run tests: describe
and it
. These functions can come from various places:
If
RuleTester.describe
andRuleTester.it
have been set to function values,RuleTester
will useRuleTester.describe
andRuleTester.it
to run tests. You can use this to customize the behavior ofRuleTester
to match a test framework that you're using.If
RuleTester.itOnly
has been set to a function value,RuleTester
will callRuleTester.itOnly
instead ofRuleTester.it
to run cases withonly: true
. IfRuleTester.itOnly
is not set butRuleTester.it
has anonly
function property,RuleTester
will fall back toRuleTester.it.only
.Otherwise, if
describe
andit
are present as globals,RuleTester
will useglobal.describe
andglobal.it
to run tests andglobal.it.only
to run cases withonly: true
. This allowsRuleTester
to work when using frameworks like Mocha without any additional configuration.Otherwise,
RuleTester#run
will simply execute all of the tests in sequence, and will throw an error if one of them fails. This means you can simply execute a test file that callsRuleTester.run
usingNode.js
, without needing a testing framework.
RuleTester#run
calls the describe
function with two arguments: a string describing the rule, and a callback function. The callback calls the it
function with a string describing the test case, and a test function. The test function will return successfully if the test passes, and throw an error if the test fails. The signature for only
is the same as it
. RuleTester
calls either it
or only
for every case even when some cases have only: true
, and the test framework is responsible for implementing test case exclusivity. (Note that this is the standard behavior for test suites when using frameworks like Mocha; this information is only relevant if you plan to customize RuleTester.describe
, RuleTester.it
, or RuleTester.itOnly
.)
Example of customizing RuleTester
:
"use strict";
const RuleTester = require("eslint").RuleTester,
test = require("my-test-runner"),
myRule = require("../../../lib/rules/my-rule");
RuleTester.describe = function(text, method) {
RuleTester.it.title = text;
return method.call(this);
};
RuleTester.it = function(text, method) {
test(RuleTester.it.title + ": " + text, method);
};
// then use RuleTester as documented
const ruleTester = new RuleTester();
ruleTester.run("my-rule", myRule, {
valid: [
// valid test cases
],
invalid: [
// invalid test cases
]
})