Skip to content

Commit

Permalink
Merge branch 'master' into ConsistentArrayBracketNewline
Browse files Browse the repository at this point in the history
  • Loading branch information
EthanRutherford committed Sep 14, 2017
2 parents f785dcb + 2731f94 commit dad11f6
Show file tree
Hide file tree
Showing 54 changed files with 2,089 additions and 1,803 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.yml
Expand Up @@ -9,7 +9,7 @@ extends:
- "plugin:eslint-plugin/recommended"
rules:
eslint-plugin/consistent-output: "error"
eslint-plugin/no-identical-tests: "error"
eslint-plugin/no-deprecated-context-methods: "error"
eslint-plugin/prefer-output-null: "error"
eslint-plugin/prefer-placeholders: "error"
eslint-plugin/report-message-format: ["error", '[^a-z].*\.$']
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
@@ -1,3 +1,10 @@
v4.6.1 - September 3, 2017

* bdec46d Build: avoid process leak when generating website (#9217) (Teddy Katz)
* cb74b87 Fix: avoid adding globals when an env is used with `false` (fixes #9202) (#9203) (Teddy Katz)
* f9b7544 Docs: Correct a typo in generator-star-spacing documentation (#9205) (Ethan Rutherford)
* e5c5e83 Build: Fixing issue with docs generation (Fixes #9199) (#9200) (Ilya Volodin)

v4.6.0 - September 1, 2017

* 56dd769 Docs: fix link format in prefer-arrow-callback.md (#9198) (Vse Mozhet Byt)
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Expand Up @@ -17,7 +17,7 @@ Before filing an issue, please be sure to read the guidelines for what you're re

## Contributing Code

Please sign our [Contributor License Agreement](https://js.foundation/CLA) and read over the [Pull Request Guidelines](http://eslint.org/docs/developer-guide/contributing/pull-requests).
Please sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint) and read over the [Pull Request Guidelines](http://eslint.org/docs/developer-guide/contributing/pull-requests).

## Full Documentation

Expand Down
30 changes: 18 additions & 12 deletions Makefile.js
Expand Up @@ -3,7 +3,7 @@
* @author nzakas
*/

/* global cat, cd, cp, echo, exec, exit, find, ls, mkdir, pwd, rm, target, test*/
/* global target */
/* eslint no-use-before-define: "off", no-console: "off" */
"use strict";

Expand All @@ -24,10 +24,24 @@ const lodash = require("lodash"),
os = require("os"),
path = require("path"),
semver = require("semver"),
shell = require("shelljs"),
ejs = require("ejs"),
loadPerf = require("load-perf"),
yaml = require("js-yaml");

const cat = shell.cat;
const cd = shell.cd;
const cp = shell.cp;
const echo = shell.echo;
const exec = shell.exec;
const exit = shell.exit;
const find = shell.find;
const ls = shell.ls;
const mkdir = shell.mkdir;
const pwd = shell.pwd;
const rm = shell.rm;
const test = shell.test;

//------------------------------------------------------------------------------
// Settings
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -146,7 +160,7 @@ function generateRulesIndex(basedir) {
* @returns {string} The result of the executed command.
*/
function execSilent(cmd) {
return exec(cmd, { silent: true }).output;
return exec(cmd, { silent: true }).stdout;
}

/**
Expand Down Expand Up @@ -329,7 +343,7 @@ function getFirstCommitOfFile(filePath) {
* @param {string} filePath The file path to check.
* @returns {string} The tag name.
*/
function getTagOfFirstOccurrence(filePath) {
function getFirstVersionOfFile(filePath) {
const firstCommit = getFirstCommitOfFile(filePath);
let tags = execSilent(`git tag --contains ${firstCommit}`);

Expand All @@ -343,15 +357,6 @@ function getTagOfFirstOccurrence(filePath) {
}, []).sort(semver.compare)[0];
}

/**
* Gets the version number where a given file was introduced first.
* @param {string} filePath The file path to check.
* @returns {string} The version number.
*/
function getFirstVersionOfFile(filePath) {
return getTagOfFirstOccurrence(filePath);
}

/**
* Gets the commit that deleted a file.
* @param {string} filePath The path to the deleted file.
Expand Down Expand Up @@ -787,6 +792,7 @@ target.gensite = function(prereleaseVersion) {
// 13. Update demos, but only for non-prereleases
if (!prereleaseVersion) {
echo("> Updating the demos (Step 13)");
target.browserify();
cp("-f", "build/eslint.js", `${SITE_DIR}js/app/eslint.js`);
} else {
echo("> Skipped updating the demos (Step 13)");
Expand Down
2 changes: 1 addition & 1 deletion docs/developer-guide/contributing/README.md
Expand Up @@ -10,7 +10,7 @@ ESLint welcomes contributions from everyone and adheres to the [JS Foundation Co

## [Signing the CLA](https://contribute.jquery.org/cla)

In order to submit code or documentation to an ESLint project, please electronically sign the [Contributor License Agreement](https://contribute.jquery.org/cla). The CLA is you giving us permission to use your contribution.
In order to submit code or documentation to an ESLint project, you will need to electronically sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint). The CLA is you giving us permission to use your contribution.

## [Bug Reporting](reporting-bugs)

Expand Down
127 changes: 123 additions & 4 deletions docs/developer-guide/nodejs-api.md
Expand Up @@ -60,16 +60,16 @@ var linter = new Linter();

### Linter#verify

The most important method on `Linter` is `verify()`, which initiates linting of the given text. This method accepts four arguments:
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 of `SourceCode`).
* `config` - a configuration object that has been processed and normalized by CLIEngine using eslintrc files and/or other configuration arguments.
* **Note**: If you want to lint text and have your configuration be read and processed, use CLIEngine's [`executeOnFiles`](#executeonfiles) or [`executeOnText`](#executeontext) instead.
* `optionsOrFilename` - (optional) Additional options for this run or a string representing the filename to associate with the code being linted.
* `options` - (optional) Additional options for this run.
* `filename` - (optional) the filename to associate with the source code.
* `saveState` - (optional) see below. This will override any value passed as the fourth argument if an options object is used here instead of the filename.
* `allowInlineConfig` - (optional) set to `false` to disable inline comments from changing eslint rules.
* `saveState` - (optional) set to true to maintain the internal state of `linter` after linting (mostly used for testing purposes)

If the third argument is a string, it is interpreted as the `filename`.

You can call `verify()` like this:

Expand Down Expand Up @@ -693,6 +693,125 @@ CLIEngine.outputFixes(report);
require("eslint").CLIEngine.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:

```js
"use strict";

const rule = require("../../../lib/rules/my-rule");
const 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:

```js
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"](./working-with-rules))
* An object containing `valid` and `invalid` properties, each of which is an array containing test cases.

A test case is an object with the following properties:

* `code` (string, required): The source code that the rule should be run on
* `options` (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).

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 error
* `type` (string): The type of the reported AST node
* `line` (number): The 1-based line number of the reported location
* `column` (number): The 0-based column number of the reported location
* `endLine` (number): The 1-based line number of the end of the reported location
* `endColumn` (number): The 0-based column number of the end of the reported location

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, optional): 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 is `null`, 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:

```js
{
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.

### Customizing RuleTester

`RuleTester` depends on two functions to run tests: `describe` and `it`. These functions can come from various places:

1. If `RuleTester.describe` and `RuleTester.it` have been set to function values, `RuleTester` will use `RuleTester.describe` and `RuleTester.it` to run tests. You can use this to customize the behavior of `RuleTester` to match a test framework that you're using.
1. Otherwise, if `describe` and `it` are present as globals, `RuleTester` will use `global.describe` and `global.it` to run tests. This allows `RuleTester` to work when using frameworks like [Mocha](https://mochajs.org/) without any additional configuration.
1. 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 calls `RuleTester.run` using `node`, 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. (Note that this is the standard behavior for test suites when using frameworks like [Mocha](https://mochajs.org/); this information is only relevant if you plan to customize `RuleTester.it` and `RuleTester.describe`.)

Example of customizing `RuleTester`:

```js
"use strict";

const RuleTester = require("eslint").RuleTester;
const test = require("my-test-runner");
const 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
]
})
```

## Deprecated APIs

* `cli` - the `cli` object has been deprecated in favor of `CLIEngine`. As of v1.0.0, `cli` is no longer exported and should not be used by external tools.
Expand Down
85 changes: 1 addition & 84 deletions docs/developer-guide/working-with-plugins.md
Expand Up @@ -119,90 +119,7 @@ The plugin support was introduced in ESLint version `0.8.0`. Ensure the `peerDep

### Testing

You can test the rules of your plugin [the same way as bundled ESLint rules](working-with-rules.md#rule-unit-tests) using RuleTester.

Example:

```js
"use strict";

var rule = require("../../../lib/rules/custom-plugin-rule"),
RuleTester = require("eslint").RuleTester;

var ruleTester = new RuleTester();
ruleTester.run("custom-plugin-rule", rule, {
valid: [
"var validVariable = 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:

```js
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"](./working-with-rules))
* An object containing `valid` and `invalid` properties, each of which is an array containing test cases.

A test case is an object with the following properties:

* `code` (string, required): The source code that the rule should be run on
* `options` (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)

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 error
* `type` (string): The type of the reported AST node
* `line` (number): The 1-based line number of the reported location
* `column` (number): The 0-based column number of the reported location
* `endLine` (number): The 1-based line number of the end of the reported location
* `endColumn` (number): The 0-based column number of the end of the reported location
* `output` (string, optional): 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 is `null`, 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.

#### Customizing RuleTester

To create tests for each valid and invalid case, `RuleTester` internally uses `describe` and `it` methods from the Mocha test framework when it is available. If you use another test framework, you can override `RuleTester.describe` and `RuleTester.it` to make `RuleTester` compatible with it and have proper individual tests and feedback.

Example:

```js
"use strict";

var RuleTester = require("eslint").RuleTester;
var test = require("my-test-runner");

RuleTester.describe = function(text, method) {
RuleTester.it.title = text;
return method.apply(this);
};

RuleTester.it = function(text, method) {
test(RuleTester.it.title + ": " + text, method);
};

// then use RuleTester as documented
```

ESLint provides the [`RuleTester`](/docs/developer-guide/nodejs-api#ruletester) utility to make it easy to test the rules of your plugin.

## Share Plugins

Expand Down

0 comments on commit dad11f6

Please sign in to comment.