@@ -0,0 +1,32 @@
---
name: "\U0001F4DD Non-rule change request"
about: Request a change that is not a bug fix, rule change, or new rule
title: ''
labels: enhancement, triage, core
assignees: ''

---

<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
This template is for requesting a change that is not a bug fix, rule change, or new rule. If you are here for another reason, please see below:
1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
3. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**The version of ESLint you are using.**


**The problem you want to solve.**


**Your take on the correct solution to problem.**


**Are you willing to submit a pull request to implement this change?**
@@ -0,0 +1,42 @@
---
name: "\U0001F680 New rule proposal"
about: Propose a new rule to be added to ESLint
title: ''
labels: triage, rule, feature
assignees: ''

---

<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
This template is for new rule proposals. If you are proposing a new rule, please continue on. If you are here for another reason, please see below:
1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
2. To request a rule change: https://eslint.org/docs/developer-guide/contributing/rule-changes
3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**Please describe what the rule should do:**

**What category of rule is this? (place an "X" next to just one item)**

[ ] Warns about a potential error (problem)
[ ] Suggests an alternate way of doing something (suggestion)
[ ] Enforces code style (layout)
[ ] Other (please specify:)

**Provide 2-3 code examples that this rule will warn about:**

<!-- Put your code examples here -->
```js
```

**Why should this rule be included in ESLint (instead of a plugin)?**


**Are you willing to submit a pull request to implement this rule?**
@@ -0,0 +1,25 @@
---
name: "â›” Question"
about: Please go to https://gitter.im/eslint/eslint
title: ''
labels: ''
assignees: ''

---

<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
Please do not use GitHub for asking questions. Instead,
please visit our chatroom:
https://gitter.im/eslint/eslint
Or our mailing list:
https://groups.google.com/group/eslint
Thanks in advance for helping us keep the issue tracker
clean!
-->
@@ -0,0 +1,40 @@
---
name: "\U0001F4DD Rule change request"
about: Request a change to an existing rule
title: ''
labels: enhancement, triage, rule
assignees: ''

---

<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
This template is for requesting a rule change. If you are here for another reason, please see below:
1. To report a bug: https://eslint.org/docs/developer-guide/contributing/reporting-bugs
2. To propose a new rule: https://eslint.org/docs/developer-guide/contributing/new-rules
3. To request a change that is not a bug fix, rule change, or new rule: https://eslint.org/docs/developer-guide/contributing/changes
4. If you have any questions, please stop by our chatroom: https://gitter.im/eslint/eslint
Note that leaving sections blank will make it difficult for us to troubleshoot and we may have to close the issue.
-->

**What rule do you want to change?**

**Does this change cause the rule to produce more or fewer warnings?**

**How will the change be implemented? (New option, new default behavior, etc.)?**

**Please provide some example code that this change will affect:**

<!-- Put your code examples here -->
```js
```

**What does the rule currently do for this code?**

**What will the rule do after it's changed?**

**Are you willing to submit a pull request to implement this change?**
@@ -0,0 +1,22 @@
---
name: "â›” Security issue"
about: Please file security issues at https://hackerone.com/eslint
title: ''
labels: ''
assignees: ''

---

<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
STOP! Please do not use GitHub for filing security issues.
Doing so is insecure and may put other ESLint users at risk.
To securely notify us of a security issue, please go to:
https://hackerone.com/eslint
Thanks in advance for helping us keep the ESLint community
safe and secure.
-->
@@ -1,3 +1,7 @@
<!--
ESLint adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
-->

**What is the purpose of this pull request? (put an "X" next to item)**

[ ] Documentation update
@@ -16,7 +20,7 @@
<!--
Please ensure your pull request is ready:
- Read the pull request guide (http://eslint.org/docs/developer-guide/contributing/pull-requests)
- Read the pull request guide (https://eslint.org/docs/developer-guide/contributing/pull-requests)
- Include tests for this change
- Update documentation for this change (if appropriate)
-->
@@ -0,0 +1,63 @@
name: CI
on:
push:
branches: [master]
pull_request:
branches: [master]

jobs:
verify_files:
name: Verify Files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- name: Install Packages
run: npm install
- name: Lint Files
run: node Makefile lint
- name: Check Rule Files
run: node Makefile checkRuleFiles
- name: Check Licenses
run: node Makefile checkLicenses

test_on_node:
name: Test
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
node: [8.x, 10.x, 12.x]
exclude:
- os: windows-latest
node: 8.x
- os: windows-latest
node: 10.x
- os: macOS-latest
node: 8.x
- os: macOS-latest
node: 10.x
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- name: Install Packages
run: npm install
- name: Test
run: node Makefile mocha
- name: Fuzz Test
run: node Makefile fuzz

test_on_browser:
name: Browser Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- name: Install Packages
run: npm install
- name: Test
run: node Makefile karma
- name: Fuzz Test
run: node Makefile fuzz
@@ -5,12 +5,19 @@ build/
npm-debug.log
.DS_Store
tmp/
debug/
.idea
jsdoc/
versions.json
*.iml
.eslintcache
.cache
/packages/**/node_modules
/tools/internal-rules/node_modules
/.vscode
.sublimelinterrc
.eslint-release-info.json
.nyc_output
/test-results.xml
.temp-eslintcache
/tests/fixtures/autofix-integration/temp.js
@@ -0,0 +1,21 @@
default: true

# Exclusions for deliberate/widespread violations
MD001: false # Header levels should only increment by one level at a time
MD002: false # First header should be a h1 header
MD007: # Unordered list indentation
indent: 4
MD012: false # Multiple consecutive blank lines
MD013: false # Line length
MD014: false # Dollar signs used before commands without showing output
MD019: false # Multiple spaces after hash on atx style header
MD021: false # Multiple spaces inside hashes on closed atx style header
MD024: false # Multiple headers with the same content
MD026: false # Trailing punctuation in header
MD029: false # Ordered list item prefix
MD030: false # Spaces after list markers
MD033: false # Allow inline HTML
MD034: false # Bare URL used
MD040: false # Fenced code blocks should have a language specified
MD041: false # First line in file should be a top level header
MD046: false # Code block style
1 .npmrc
@@ -0,0 +1 @@
package-lock = false
13 .nycrc
@@ -0,0 +1,13 @@
{
"include": [
"bin/**/*.js",
"conf/**/*.js",
"lib/**/*.js"
],
"reporter": [
"lcov",
"text-summary",
"cobertura"
],
"sourceMap": true
}

This file was deleted.

1,544 CHANGELOG.md

Large diffs are not rendered by default.

@@ -0,0 +1 @@
This project adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct).
@@ -2,20 +2,26 @@

Please be sure to read the contribution guidelines before making or requesting a change.

## Code of Conduct

This project adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct). We kindly request that you read over our code of conduct before contributing.

## Filing Issues

Before filing an issue, please be sure to read the guidelines for what you're reporting:

* [Bug Report](http://eslint.org/docs/developer-guide/contributing/reporting-bugs)
* [Propose a New Rule](http://eslint.org/docs/developer-guide/contributing/new-rules)
* [Proposing a Rule Change](http://eslint.org/docs/developer-guide/contributing/rule-changes)
* [Request a Change](http://eslint.org/docs/developer-guide/contributing/changes)
* [Bug Report](https://eslint.org/docs/developer-guide/contributing/reporting-bugs)
* [Propose a New Rule](https://eslint.org/docs/developer-guide/contributing/new-rules)
* [Proposing a Rule Change](https://eslint.org/docs/developer-guide/contributing/rule-changes)
* [Request a Change](https://eslint.org/docs/developer-guide/contributing/changes)

To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint).

## Contributing Code

Please sign our [Contributor License Agreement](https://contribute.jquery.org/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](https://eslint.org/docs/developer-guide/contributing/pull-requests).

## Full Documentation

Our full contribution guidelines can be found at:
http://eslint.org/docs/developer-guide/contributing/
https://eslint.org/docs/developer-guide/contributing/
@@ -1,4 +1,3 @@
ESLint
Copyright JS Foundation and other contributors, https://js.foundation

Permission is hereby granted, free of charge, to any person obtaining a copy

Large diffs are not rendered by default.

315 README.md

Large diffs are not rendered by default.

@@ -0,0 +1 @@
If you have a question about how to use ESLint, please ask it in our [Gitter channel](https://gitter.im/eslint/eslint).

This file was deleted.

@@ -0,0 +1,38 @@
trigger:
- master

jobs:
- template: .azure-pipelines/job.yml
parameters:
name: test_on_linux_node12
displayName: Test on Node.js 12 (Linux)
vmImage: Ubuntu-16.04
nodeVersion: 12.x

- template: .azure-pipelines/job.yml
parameters:
name: test_on_linux_node10
displayName: Test on Node.js 10 (Linux)
vmImage: Ubuntu-16.04
nodeVersion: 10.x

- template: .azure-pipelines/job.yml
parameters:
name: test_on_linux_node8
displayName: Test on Node.js 8 (Linux)
vmImage: Ubuntu-16.04
nodeVersion: 8.x

- template: .azure-pipelines/job.yml
parameters:
name: test_on_windows_node12
displayName: Test on Node.js 12 (Windows)
vmImage: Windows-2019
nodeVersion: 12.x

- template: .azure-pipelines/job.yml
parameters:
name: test_on_macos_node12
displayName: Test on Node.js 12 (macOS)
vmImage: macOS-10.14
nodeVersion: 12.x
@@ -9,13 +9,16 @@

"use strict";

// to use V8's code cache to speed up instantiation time
require("v8-compile-cache");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const useStdIn = (process.argv.indexOf("--stdin") > -1),
init = (process.argv.indexOf("--init") > -1),
debug = (process.argv.indexOf("--debug") > -1);
const useStdIn = process.argv.includes("--stdin"),
init = process.argv.includes("--init"),
debug = process.argv.includes("--debug");

// must do this initialization *before* other requires in order to work
if (debug) {
@@ -27,10 +30,9 @@ if (debug) {
//------------------------------------------------------------------------------

// now we can safely include the other modules that use debug
const concat = require("concat-stream"),
cli = require("../lib/cli"),
path = require("path"),
fs = require("fs");
const path = require("path"),
fs = require("fs"),
cli = require("../lib/cli");

//------------------------------------------------------------------------------
// Execution
@@ -43,33 +45,64 @@ process.once("uncaughtException", err => {

if (typeof err.messageTemplate === "string" && err.messageTemplate.length > 0) {
const template = lodash.template(fs.readFileSync(path.resolve(__dirname, `../messages/${err.messageTemplate}.txt`), "utf-8"));
const pkg = require("../package.json");

console.log("\nOops! Something went wrong! :(");
console.log(`\n${template(err.messageData || {})}`);
console.error("\nOops! Something went wrong! :(");
console.error(`\nESLint: ${pkg.version}.\n\n${template(err.messageData || {})}`);
} else {
console.log(err.message);
console.log(err.stack);
console.error(err.stack);
}

process.exitCode = 1;
process.exitCode = 2;
});

if (useStdIn) {
process.stdin.pipe(concat({ encoding: "string" }, text => {
process.exitCode = cli.execute(process.argv, text);
}));
} else if (init) {
const configInit = require("../lib/config/config-initializer");

configInit.initializeConfig(err => {
if (err) {
process.exitCode = 1;
console.error(err.message);
console.error(err.stack);
} else {
process.exitCode = 0;

/*
* Note: See
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#processstdin
* - https://github.com/nodejs/node/blob/master/doc/api/process.md#a-note-on-process-io
* - https://lists.gnu.org/archive/html/bug-gnu-emacs/2016-01/msg00419.html
* - https://github.com/nodejs/node/issues/7439 (historical)
*
* On Windows using `fs.readFileSync(STDIN_FILE_DESCRIPTOR, "utf8")` seems
* to read 4096 bytes before blocking and never drains to read further data.
*
* The investigation on the Emacs thread indicates:
*
* > Emacs on MS-Windows uses pipes to communicate with subprocesses; a
* > pipe on Windows has a 4K buffer. So as soon as Emacs writes more than
* > 4096 bytes to the pipe, the pipe becomes full, and Emacs then waits for
* > the subprocess to read its end of the pipe, at which time Emacs will
* > write the rest of the stuff.
*
* Using the nodejs code example for reading from stdin.
*/
let contents = "",
chunk = "";

process.stdin.setEncoding("utf8");
process.stdin.on("readable", () => {

// Use a loop to make sure we read all available data.
while ((chunk = process.stdin.read()) !== null) {
contents += chunk;
}
});

process.stdin.on("end", () => {
process.exitCode = cli.execute(process.argv, contents, "utf8");
});
} else if (init) {
const configInit = require("../lib/init/config-initializer");

configInit.initializeConfig().then(() => {
process.exitCode = 0;
}).catch(err => {
process.exitCode = 1;
console.error(err.message);
console.error(err.stack);
});
} else {
process.exitCode = cli.execute(process.argv);
}

This file was deleted.

@@ -10,12 +10,12 @@
],
"deprecated": {
"name": "Deprecated",
"description": "These rules have been deprecated and replaced by newer rules:",
"description": "These rules have been deprecated in accordance with the [deprecation policy](/docs/user-guide/rule-deprecation), and replaced by newer rules:",
"rules": []
},
"removed": {
"name": "Removed",
"description": "These rules from older versions of ESLint have been replaced by newer rules:",
"description": "These rules from older versions of ESLint (before the [deprecation policy](/docs/user-guide/rule-deprecation) existed) have been replaced by newer rules:",
"rules": [
{ "removed": "generator-star", "replacedBy": ["generator-star-spacing"] },
{ "removed": "global-strict", "replacedBy": ["strict"] },
@@ -0,0 +1,79 @@
/**
* @fileoverview Defines a schema for configs.
* @author Sylvan Mably
*/

"use strict";

const baseConfigProperties = {
env: { type: "object" },
extends: { $ref: "#/definitions/stringOrStrings" },
globals: { type: "object" },
overrides: {
type: "array",
items: { $ref: "#/definitions/overrideConfig" },
additionalItems: false
},
parser: { type: ["string", "null"] },
parserOptions: { type: "object" },
plugins: { type: "array" },
processor: { type: "string" },
rules: { type: "object" },
settings: { type: "object" },
noInlineConfig: { type: "boolean" },
reportUnusedDisableDirectives: { type: "boolean" },

ecmaFeatures: { type: "object" } // deprecated; logs a warning when used
};

const configSchema = {
definitions: {
stringOrStrings: {
oneOf: [
{ type: "string" },
{
type: "array",
items: { type: "string" },
additionalItems: false
}
]
},
stringOrStringsRequired: {
oneOf: [
{ type: "string" },
{
type: "array",
items: { type: "string" },
additionalItems: false,
minItems: 1
}
]
},

// Config at top-level.
objectConfig: {
type: "object",
properties: {
root: { type: "boolean" },
...baseConfigProperties
},
additionalProperties: false
},

// Config in `overrides`.
overrideConfig: {
type: "object",
properties: {
excludedFiles: { $ref: "#/definitions/stringOrStrings" },
files: { $ref: "#/definitions/stringOrStringsRequired" },
...baseConfigProperties
},
required: ["files"],
additionalProperties: false
}
},

$ref: "#/definitions/objectConfig"
};

module.exports = configSchema;
@@ -12,18 +12,20 @@ module.exports = {
useEslintrc: true,
envs: [],
globals: [],
rules: {},
extensions: [".js"],
ignore: true,
ignorePath: null,
parser: "", // must be empty
cache: false,

// in order to honor the cacheFile option if specified
// this option should not have a default value otherwise
// it will always be used
/*
* in order to honor the cacheFile option if specified
* this option should not have a default value otherwise
* it will always be used
*/
cacheLocation: "",
cacheFile: ".eslintcache",
fix: false,
allowInlineConfig: true
allowInlineConfig: true,
reportUnusedDisableDirectives: void 0,
globInputPaths: true
};
@@ -10,12 +10,76 @@

const globals = require("globals");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
* Get the object that has differentce.
* @param {Record<string,boolean>} current The newer object.
* @param {Record<string,boolean>} prev The older object.
* @returns {Record<string,boolean>} The difference object.
*/
function getDiff(current, prev) {
const retv = {};

for (const [key, value] of Object.entries(current)) {
if (!Object.hasOwnProperty.call(prev, key)) {
retv[key] = value;
}
}

return retv;
}

const newGlobals2015 = getDiff(globals.es2015, globals.es5); // 19 variables such as Promise, Map, ...
const newGlobals2017 = {
Atomics: false,
SharedArrayBuffer: false
};
const newGlobals2020 = {
BigInt: false,
BigInt64Array: false,
BigUint64Array: false
};

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

module.exports = {
builtin: globals.es5,
/** @type {Map<string, import("../lib/shared/types").Environment>} */
module.exports = new Map(Object.entries({

// Language
builtin: {
globals: globals.es5
},
es6: {
globals: newGlobals2015,
parserOptions: {
ecmaVersion: 6
}
},
es2015: {
globals: newGlobals2015,
parserOptions: {
ecmaVersion: 6
}
},
es2017: {
globals: { ...newGlobals2015, ...newGlobals2017 },
parserOptions: {
ecmaVersion: 8
}
},
es2020: {
globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 },
parserOptions: {
ecmaVersion: 11
}
},

// Platforms
browser: {
globals: globals.browser
},
@@ -27,6 +91,17 @@ module.exports = {
}
}
},
"shared-node-browser": {
globals: globals["shared-node-browser"]
},
worker: {
globals: globals.worker
},
serviceworker: {
globals: globals.serviceworker
},

// Frameworks
commonjs: {
globals: globals.commonjs,
parserOptions: {
@@ -35,12 +110,6 @@ module.exports = {
}
}
},
"shared-node-browser": {
globals: globals["shared-node-browser"]
},
worker: {
globals: globals.worker
},
amd: {
globals: globals.amd
},
@@ -83,9 +152,6 @@ module.exports = {
nashorn: {
globals: globals.nashorn
},
serviceworker: {
globals: globals.serviceworker
},
atomtest: {
globals: globals.atomtest
},
@@ -95,13 +161,7 @@ module.exports = {
webextensions: {
globals: globals.webextensions
},
es6: {
globals: globals.es6,
parserOptions: {
ecmaVersion: 6
}
},
greasemonkey: {
globals: globals.greasemonkey
}
};
}));
@@ -9,22 +9,23 @@
// Requirements
//------------------------------------------------------------------------------

const load = require("../lib/load-rules"),
rules = require("../lib/rules");
const builtInRules = require("../lib/rules");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

const enabledRules = Object.keys(load()).reduce((result, ruleId) => {
if (!rules.get(ruleId).meta.deprecated) {
result[ruleId] = "error";
const allRules = {};

for (const [ruleId, rule] of builtInRules) {
if (!rule.meta.deprecated) {
allRules[ruleId] = "error";
}
return result;
}, {});
}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

module.exports = { rules: enabledRules };
/** @type {import("../lib/shared/types").ConfigData} */
module.exports = { rules: allRules };
222 conf/eslint-recommended.js 100755 → 100644
@@ -6,259 +6,65 @@

"use strict";

/* eslint sort-keys: ["error", "asc"], quote-props: ["error", "consistent"] */
/* eslint-disable sort-keys */
/* eslint sort-keys: ["error", "asc"] */

/** @type {import("../lib/shared/types").ConfigData} */
module.exports = {
parser: "espree",
ecmaFeatures: {},

rules: {

/* eslint-enable sort-keys */
"accessor-pairs": "off",
"array-bracket-spacing": "off",
"array-callback-return": "off",
"arrow-body-style": "off",
"arrow-parens": "off",
"arrow-spacing": "off",
"block-scoped-var": "off",
"block-spacing": "off",
"brace-style": "off",
"callback-return": "off",
"camelcase": "off",
"capitalized-comments": "off",
"class-methods-use-this": "off",
"comma-dangle": "off",
"comma-spacing": "off",
"comma-style": "off",
"complexity": "off",
"computed-property-spacing": "off",
"consistent-return": "off",
"consistent-this": "off",
"constructor-super": "error",
"curly": "off",
"default-case": "off",
"dot-location": "off",
"dot-notation": "off",
"eol-last": "off",
"eqeqeq": "off",
"func-call-spacing": "off",
"func-name-matching": "off",
"func-names": "off",
"func-style": "off",
"generator-star-spacing": "off",
"global-require": "off",
"guard-for-in": "off",
"handle-callback-err": "off",
"id-blacklist": "off",
"id-length": "off",
"id-match": "off",
"indent": "off",
"init-declarations": "off",
"jsx-quotes": "off",
"key-spacing": "off",
"keyword-spacing": "off",
"line-comment-position": "off",
"linebreak-style": "off",
"lines-around-comment": "off",
"lines-around-directive": "off",
"max-depth": "off",
"max-len": "off",
"max-lines": "off",
"max-nested-callbacks": "off",
"max-params": "off",
"max-statements": "off",
"max-statements-per-line": "off",
"multiline-ternary": "off",
"new-cap": "off",
"new-parens": "off",
"newline-after-var": "off",
"newline-before-return": "off",
"newline-per-chained-call": "off",
"no-alert": "off",
"no-array-constructor": "off",
"no-await-in-loop": "off",
"no-bitwise": "off",
"no-caller": "off",
"for-direction": "error",
"getter-return": "error",
"no-async-promise-executor": "error",
"no-case-declarations": "error",
"no-catch-shadow": "off",
"no-class-assign": "error",
"no-compare-neg-zero": "off",
"no-compare-neg-zero": "error",
"no-cond-assign": "error",
"no-confusing-arrow": "off",
"no-console": "error",
"no-const-assign": "error",
"no-constant-condition": "error",
"no-continue": "off",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-div-regex": "off",
"no-dupe-args": "error",
"no-dupe-class-members": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-duplicate-imports": "off",
"no-else-return": "off",
"no-empty": "error",
"no-empty-character-class": "error",
"no-empty-function": "off",
"no-empty-pattern": "error",
"no-eq-null": "off",
"no-eval": "off",
"no-ex-assign": "error",
"no-extend-native": "off",
"no-extra-bind": "off",
"no-extra-boolean-cast": "error",
"no-extra-label": "off",
"no-extra-parens": "off",
"no-extra-semi": "error",
"no-fallthrough": "error",
"no-floating-decimal": "off",
"no-func-assign": "error",
"no-global-assign": "error",
"no-implicit-coercion": "off",
"no-implicit-globals": "off",
"no-implied-eval": "off",
"no-inline-comments": "off",
"no-inner-declarations": "error",
"no-invalid-regexp": "error",
"no-invalid-this": "off",
"no-irregular-whitespace": "error",
"no-iterator": "off",
"no-label-var": "off",
"no-labels": "off",
"no-lone-blocks": "off",
"no-lonely-if": "off",
"no-loop-func": "off",
"no-magic-numbers": "off",
"no-mixed-operators": "off",
"no-mixed-requires": "off",
"no-misleading-character-class": "error",
"no-mixed-spaces-and-tabs": "error",
"no-multi-assign": "off",
"no-multi-spaces": "off",
"no-multi-str": "off",
"no-multiple-empty-lines": "off",
"no-native-reassign": "off",
"no-negated-condition": "off",
"no-negated-in-lhs": "off",
"no-nested-ternary": "off",
"no-new": "off",
"no-new-func": "off",
"no-new-object": "off",
"no-new-require": "off",
"no-new-symbol": "error",
"no-new-wrappers": "off",
"no-obj-calls": "error",
"no-octal": "error",
"no-octal-escape": "off",
"no-param-reassign": "off",
"no-path-concat": "off",
"no-plusplus": "off",
"no-process-env": "off",
"no-process-exit": "off",
"no-proto": "off",
"no-prototype-builtins": "off",
"no-prototype-builtins": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-restricted-globals": "off",
"no-restricted-imports": "off",
"no-restricted-modules": "off",
"no-restricted-properties": "off",
"no-restricted-syntax": "off",
"no-return-assign": "off",
"no-return-await": "off",
"no-script-url": "off",
"no-self-assign": "error",
"no-self-compare": "off",
"no-sequences": "off",
"no-shadow": "off",
"no-shadow-restricted-names": "off",
"no-spaced-func": "off",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-sync": "off",
"no-tabs": "off",
"no-template-curly-in-string": "off",
"no-ternary": "off",
"no-this-before-super": "error",
"no-throw-literal": "off",
"no-trailing-spaces": "off",
"no-undef": "error",
"no-undef-init": "off",
"no-undefined": "off",
"no-underscore-dangle": "off",
"no-unexpected-multiline": "error",
"no-unmodified-loop-condition": "off",
"no-unneeded-ternary": "off",
"no-unreachable": "error",
"no-unsafe-finally": "error",
"no-unsafe-negation": "error",
"no-unused-expressions": "off",
"no-unused-labels": "error",
"no-unused-vars": "error",
"no-use-before-define": "off",
"no-useless-call": "off",
"no-useless-computed-key": "off",
"no-useless-concat": "off",
"no-useless-constructor": "off",
"no-useless-escape": "off",
"no-useless-rename": "off",
"no-useless-return": "off",
"no-var": "off",
"no-void": "off",
"no-warning-comments": "off",
"no-whitespace-before-property": "off",
"no-with": "off",
"nonblock-statement-body-position": "off",
"object-curly-newline": "off",
"object-curly-spacing": ["off", "never"],
"object-property-newline": "off",
"object-shorthand": "off",
"one-var": "off",
"one-var-declaration-per-line": "off",
"operator-assignment": "off",
"operator-linebreak": "off",
"padded-blocks": "off",
"prefer-arrow-callback": "off",
"prefer-const": "off",
"prefer-destructuring": "off",
"prefer-numeric-literals": "off",
"prefer-promise-reject-errors": "off",
"prefer-reflect": "off",
"prefer-rest-params": "off",
"prefer-spread": "off",
"prefer-template": "off",
"quote-props": "off",
"quotes": "off",
"radix": "off",
"require-await": "off",
"require-jsdoc": "off",
"no-useless-catch": "error",
"no-useless-escape": "error",
"no-with": "error",
"require-atomic-updates": "error",
"require-yield": "error",
"rest-spread-spacing": "off",
"semi": "off",
"semi-spacing": "off",
"sort-imports": "off",
"sort-keys": "off",
"sort-vars": "off",
"space-before-blocks": "off",
"space-before-function-paren": "off",
"space-in-parens": "off",
"space-infix-ops": "off",
"space-unary-ops": "off",
"spaced-comment": "off",
"strict": "off",
"symbol-description": "off",
"template-curly-spacing": "off",
"template-tag-spacing": "off",
"unicode-bom": "off",
"use-isnan": "error",
"valid-jsdoc": "off",
"valid-typeof": "error",
"vars-on-top": "off",
"wrap-iife": "off",
"wrap-regex": "off",
"yield-star-spacing": "off",
"yoda": "off"
"valid-typeof": "error"
}
};

This file was deleted.

@@ -0,0 +1,17 @@
# Documentation

Welcome to our documentation pages! What would you like to view?

## [User Guide](user-guide)

Intended for end users of ESLint. Contains information about core rules, configuration, command line options, formatters, and integrations,
as well as guides for migrating from earlier versions of ESLint.

## [Developer Guide](developer-guide)

Intended for contributors to ESLint and people who wish to extend ESLint. Contains information about contributing to ESLint; creating custom
rules, configurations, plugins, and formatters; and information about our architecture and Node.js API.

## [Maintainer Guide](maintainer-guide)

Intended for maintainers of ESLint.
@@ -8,8 +8,8 @@ The primary reason ESLint was created was to allow developers to create their ow

ESLint is written using Node.js to provide a fast runtime environment and easy installation via [npm][].

[linting]: http://en.wikipedia.org/wiki/Lint_(software)
[npm]: http://npmjs.org/
[linting]: https://en.wikipedia.org/wiki/Lint_(software)
[npm]: https://npmjs.org/

## Philosophy

@@ -23,8 +23,8 @@ Everything is pluggable:
Every rule:

* Is standalone
* Can be able to be turned off or on (nothing can be deemed "too important to turn off")
* Can be set to be a warning or error individually
* Can be turned off or on (nothing can be deemed "too important to turn off")
* Can be set to a warning or error individually

Additionally:

@@ -14,30 +14,34 @@ In order to work with ESLint as a developer, it's recommended that:

If that sounds like you, then continue reading to get started.

## Section 1: Get the [Source Code](source-code)
## Section 1: Get the [Source Code](source-code.md)

Before you can get started, you'll need to get a copy of the ESLint source code. This section explains how to do that and a little about the source code structure.

## Section 2: Set up a [Development Environment](development-environment)
## Section 2: Set up a [Development Environment](development-environment.md)

Developing for ESLint is a bit different than running it on the command line. This section shows you how to set up a development environment and get you ready to write code.

## Section 3: Run the [Unit Tests](unit-tests)
## Section 3: Run the [Unit Tests](unit-tests.md)

There are a lot of unit tests included with ESLint to make sure that we're keeping on top of code quality. This section explains how to run the unit tests.

## Section 4: [Working with Rules](working-with-rules)
## Section 4: [Working with Rules](working-with-rules.md)

You're finally ready to start working with rules. You may want to fix an existing rule or create a new one. This section explains how to do all of that.

## Section 5: [Working with Plugins](working-with-plugins)
## Section 5: [Working with Plugins](working-with-plugins.md)

You've developed library-specific rules for ESLint and you want to share it with the community. You can publish an ESLint plugin on npm.

## Section 6: [Node.js API](nodejs-api)
## Section 6: [Working with Custom Parsers](working-with-custom-parsers.md)

If you aren't going to use the default parser of ESLint, this section explains about using custom parsers.

## Section 7: [Node.js API](nodejs-api.md)

If you're interested in writing a tool that uses ESLint, then you can use the Node.js API to get programmatic access to functionality.

## Section 7: [Contributing](contributing/)
## Section 8: [Contributing](contributing/)

Once you've made changes that you want to share with the community, the next step is to submit those changes back via a pull request.
@@ -1,10 +1,18 @@
# Architecture

<center><img alt="dependency graph" src="./architecture/dependency.svg"></center>

At a high level, there are a few key parts to ESLint:

* `bin/eslint.js` - this is the file that actually gets executed with the command line utility. It's a dumb wrapper that does nothing more than bootstrap ESLint, passing the command line arguments to `cli`. This is intentionally small so as not to require heavy testing.
* `lib/api.js` - this is the entry point of `require("eslint")`. This file exposes an object that contains public classes `Linter`, `CLIEngine`, `RuleTester`, and `SourceCode`.
* `lib/cli.js` - this is the heart of the ESLint CLI. It takes an array of arguments and then uses `eslint` to execute the commands. By keeping this as a separate utility, it allows others to effectively call ESLint from within another Node.js program as if it were done on the command line. The main call is `cli.execute()`. This is also the part that does all the file reading, directory traversing, input, and output.
* `lib/eslint.js` - this is the core `eslint` object that does code verifying based on configuration options. This file does no file I/O and does not interact with the `console` at all. For other Node.js programs that have JavaScript text to verify, they would be able to use this interface directly.
* `lib/init/` - this module contains `--init` functionality that set up a configuration file for end users.
* `lib/cli-engine/` - this module is `CLIEngine` class that finds source code files and configuration files then does code verifying with the `Linter` class. This includes the loading logic of configuration files, parsers, plugins, and formatters.
* `lib/linter/` - this module is the core `Linter` class that does code verifying based on configuration options. This file does no file I/O and does not interact with the `console` at all. For other Node.js programs that have JavaScript text to verify, they would be able to use this interface directly.
* `lib/rule-tester/` - this module is `RuleTester` class that is a wrapper around Mocha so that rules can be unit tested. This class lets us write consistently formatted tests for each rule that is implemented and be confident that each of the rules work. The RuleTester interface was modeled after Mocha and works with Mocha's global testing methods. RuleTester can also be modified to work with other testing frameworks.
* `lib/source-code/` - this module is `SourceCode` class that is used to represent the parsed source code. It takes in source code and the Program node of the AST representing the code.
* `lib/rules/` - this contains built-in rules that verify source code.

## The `cli` object

@@ -28,15 +36,14 @@ This object may not:

## The `CLIEngine` object

The `CLIEngine` type represents the core functionality of the CLI except that it reads nothing from the command line and doesn't output anything by default. Instead, it accepts many (but not all) of the arguments that are passed into the CLI. It reads both configuration and source files as well as managing the environment that is passed into the `eslint` object.
The `CLIEngine` type represents the core functionality of the CLI except that it reads nothing from the command line and doesn't output anything by default. Instead, it accepts many (but not all) of the arguments that are passed into the CLI. It reads both configuration and source files as well as managing the environment that is passed into the `Linter` object.

The main method of the `CLIEngine` is `executeOnFiles()`, which accepts an array of file and directory names to run the linter on.

This object's responsibilities include:

* Managing the execution environment for `eslint`
* Managing the execution environment for `Linter`
* Reading from the file system
* Loading rule definitions
* Reading configuration information from config files (including `.eslintrc` and `package.json`)

This object may not:
@@ -46,11 +53,11 @@ This object may not:
* Output to the console
* Use formatters

## The `eslint` object
## The `Linter` object

The main method of the `eslint` object is `verify()` and accepts two arguments: the source text to verify and a configuration object (the baked configuration of the given configuration file plus command line options). The method first parses the given text with `espree` (or whatever the configured parser is) and retrieves the AST. The AST is produced with both line/column and range locations which are useful for reporting location of issues and retrieving the source text related to an AST node, respectively.
The main method of the `Linter` object is `verify()` and accepts two arguments: the source text to verify and a configuration object (the baked configuration of the given configuration file plus command line options). The method first parses the given text with `espree` (or whatever the configured parser is) and retrieves the AST. The AST is produced with both line/column and range locations which are useful for reporting location of issues and retrieving the source text related to an AST node, respectively.

Once the AST is available, `estraverse` is used to traverse the AST from top to bottom. At each node, the `eslint` object emits an event that has the same name as the node type (i.e., "Identifier", "WithStatement", etc.). On the way back up the subtree, an event is emitted with the AST type name and suffixed with ":exit", such as "Identifier:exit" - this allows rules to take action both on the way down and on the way up in the traversal. Each event is emitted with the appropriate AST node available.
Once the AST is available, `estraverse` is used to traverse the AST from top to bottom. At each node, the `Linter` object emits an event that has the same name as the node type (i.e., "Identifier", "WithStatement", etc.). On the way back up the subtree, an event is emitted with the AST type name and suffixed with ":exit", such as "Identifier:exit" - this allows rules to take action both on the way down and on the way up in the traversal. Each event is emitted with the appropriate AST node available.

This object's responsibilities include:

Large diffs are not rendered by default.

@@ -1,6 +1,6 @@
# Code Conventions

Programming language style guides are important for the long-term maintainability of software. This guide is based on the [Code Conventions for the Java Programming Language](http://java.sun.com/docs/codeconv/) and [Douglas Crockford's Code Conventions for the JavaScript Programming Language](http://javascript.crockford.com/code.html). Modifications have been made due to my personal experience and preferences.
Programming language style guides are important for the long-term maintainability of software. This guide is based on the [Code Conventions for the Java Programming Language](https://java.sun.com/docs/codeconv/) and [Douglas Crockford's Code Conventions for the JavaScript Programming Language](http://javascript.crockford.com/code.html). Modifications have been made due to my personal experience and preferences.

## File Format

@@ -169,7 +169,7 @@ Operators with two operands must be preceded and followed by a single space to m

## Parentheses Spacing

When parentheses are used, there should be no white space immediately after the opening paren or immediately before the closing paren.
When parentheses are used, there should be no whitespace immediately after the opening paren or immediately before the closing paren.

// Good
var found = (values[i] === item);
@@ -262,7 +262,7 @@ Make frequent use of comments to aid others in understanding your code. Use comm

### Single-Line Comments

Single-line comments should be used to documentation one line of code or a group of related lines of code. A single-line comment may be used in three ways:
Single-line comments should be used to document one line of code or a group of related lines of code. A single-line comment may be used in three ways:

1. On a separate line, describing the code beneath it.
1. At the end of a line, describing the code before it.
@@ -895,7 +895,7 @@ The `try` class of statements should have the following form:
statements
}

## White Space
## Whitespace

Blank lines improve readability by setting off sections of code that are logically related.

@@ -4,30 +4,38 @@ One of the great things about open source projects is that anyone can contribute

This guide is intended for anyone who wants to contribute to an ESLint project. Please read it carefully as it answers a lot of the questions many newcomers have when first working with our projects.

## [Signing the CLA](https://contribute.jquery.org/cla)
## Read the [Code of Conduct](https://js.foundation/community/code-of-conduct)

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.
ESLint welcomes contributions from everyone and adheres to the [JS Foundation Code of Conduct](https://js.foundation/community/code-of-conduct). We kindly request that you read over our code of conduct before contributing.

## [Signing the CLA](https://js.foundation/CLA)

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)

Think you found a problem? We'd love to hear about it. This section explains how to submit a bug, the type of information we need to properly verify it, and the overall process.

## Proposing a [New Rule](new-rules)
## Proposing a [New Rule](new-rules.md)

We get a lot of proposals for new rules in ESLint. This section explains how we determine which rules are accepted and what information you should provide to help us evaluate your proposal.

## Proposing a [Rule Change](rule-changes)
## Proposing a [Rule Change](rule-changes.md)

Want to make a change to an existing rule? This section explains the process and how we evaluate such proposals.

## Requesting a [Change](changes)
## Requesting a [Change](changes.md)

If you'd like to request a change other than a bug fix or new rule, this section explains that process.

## [Working on Issues](working-on-issues)
## Reporting a security vulnerability

To report a security vulnerability in ESLint, please use our [HackerOne program](https://hackerone.com/eslint).

## [Working on Issues](working-on-issues.md)

Have some extra time and want to contribute? This section talks about the process of working on issues.

## Submitting a [Pull Request](pull-requests)
## Submitting a [Pull Request](pull-requests.md)

We're always looking for contributions from the community. This section explains the requirements for pull requests and the process of contributing code.
@@ -1,6 +1,6 @@
# Change Requests

If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new?body=**What%20version%20are%20you%20using%3F**%0A%0A**What%20did%20you%20do%3F**%0A%0A**What%20happened%3F**%0A%0A**What%20did%20you%20expect%20to%20happen%3F**%0A%0A) on GitHub. Be sure to include the following information:
If you'd like to request a change to ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new?template=CHANGE.md) on GitHub. Be sure to include the following information:

1. The version of ESLint you are using.
1. The problem you want to solve.
@@ -19,7 +19,7 @@ Even though these are the formal criteria for inclusion, each rule is evaluated

## Proposing a Rule

If you want to propose a new rule, [create a pull request](/docs/developer-guide/contributing/pull-requests) or new issue and paste the questions from the [rule proposal template](https://github.com/eslint/eslint/blob/master/templates/rule-proposal.md) into the description.
If you want to propose a new rule, please see how to [create a pull request](/docs/developer-guide/contributing/pull-requests) or submit an issue by filling out a [new rule template](https://github.com/eslint/eslint/issues/new?template=NEW_RULE.md).

We need all of this information in order to determine whether or not the rule is a good core rule candidate.

@@ -39,4 +39,4 @@ The ESLint team doesn't implement new rules that are suggested by users because

## Alternative: Creating Your Own Rules

Remember that ESLint is completely pluggable, which means you can create your own rules and distribute them using plugins. We did this on purpose because we don't want to be the gatekeepers for all possible rules. Even if we don't accept a rule into the core, that doesn't mean you can't have the exact rule that you want. See the [working with rules](../working-with-rules) and [working with plugins](../working-with-plugins) documentation for more information.
Remember that ESLint is completely pluggable, which means you can create your own rules and distribute them using plugins. We did this on purpose because we don't want to be the gatekeepers for all possible rules. Even if we don't accept a rule into the core, that doesn't mean you can't have the exact rule that you want. See the [working with rules](../working-with-rules.md) and [working with plugins](../working-with-plugins.md) documentation for more information.
@@ -6,9 +6,9 @@ If you want to contribute to an ESLint repo, please use a GitHub pull request. T

If you'd like to work on a pull request and you've never submitted code before, follow these steps:

1. Sign our [Contributor License Agreement](https://contribute.jquery.org/cla).
1. Set up a [development environment](../development-environment).
1. If you want to implement a breaking change or a change to the core, ensure there's an issue that describes what you're doing and the issue has been accepted. You can create a new issue or just indicate you're [working on an existing issue](working-on-issues). Bug fixes, documentation changes, and other pull requests do not require an issue.
1. Sign our [Contributor License Agreement](https://cla.js.foundation/eslint/eslint).
1. Set up a [development environment](../development-environment.md).
1. If you want to implement a breaking change or a change to the core, ensure there's an issue that describes what you're doing and the issue has been accepted. You can create a new issue or just indicate you're [working on an existing issue](working-on-issues.md). Bug fixes, documentation changes, and other pull requests do not require an issue.

After that, you're ready to start working on code.

@@ -40,7 +40,7 @@ You should do all of your development for the issue in this branch.

### Step 2: Make your changes<a name="step2"></a>

Make the changes to the code and tests, following the [code conventions](../code-conventions) as you go. Once you have finished, commit the changes to your branch:
Make the changes to the code and tests, following the [code conventions](../code-conventions.md) as you go. Once you have finished, commit the changes to your branch:

```
$ git add -A
@@ -60,15 +60,15 @@ The first line of the commit message (the summary) must have a specific format.
The `Tag` is one of the following:

* `Fix` - for a bug fix.
* `Update` - for a backwards-compatible enhancement or a change to a rule that increases the number of reported problems.
* `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems.
* `New` - implemented a new feature.
* `Breaking` - for a backwards-incompatible enhancement or feature.
* `Docs` - changes to documentation only.
* `Build` - changes to build process only.
* `Upgrade` - for a dependency upgrade.
* `Chore` - for refactoring, adding tests, etc. (anything that isn't user-facing).

Use the [labels of the issue you are working on](working-on-issues#issue-labels) to determine the best tag.
Use the [labels of the issue you are working on](working-on-issues.md#issue-labels) to determine the best tag.

The message summary should be a one-sentence description of the change, and it must be 72 characters in length or shorter. If the pull request addresses an issue, then the issue number should be mentioned at the end. If the commit doesn't completely fix the issue, then use `(refs #1234)` instead of `(fixes #1234)`.

@@ -77,7 +77,7 @@ Here are some good commit message summary examples:
```
Build: Update Travis to only test Node 0.10 (refs #734)
Fix: Semi rule incorrectly flagging extra semicolon (fixes #840)
Upgrade: Esprima to 1.2, switch to using Esprima comment attachment (fixes #730)
Upgrade: Esprima to 1.2, switch to using comment attachment (fixes #730)
```

The commit message format is important because these messages are used to create a changelog for each release. The tag and issue number help to create more consistent and useful changelogs.
@@ -105,7 +105,7 @@ If there are any failing tests, update your code until all tests pass.

With your code ready to go, this is a good time to double-check your submission to make sure it follows our conventions. Here are the things to check:

* Run `npm run check-commit` to double-check that your commit is formatted correctly.
* Make sure your commit is formatted correctly.
* The pull request must have a description. The description should explain what you did and how its effects can be seen.
* The commit message is properly formatted.
* The change introduces no functional regression. Be sure to run `npm test` to verify your changes before submitting a pull request.
@@ -160,15 +160,15 @@ If we ask you to make code changes, there's no need to close the pull request an

```
$ git add -A
$ git commit --amend --no-edit
$ git push origin issue1234 -f
$ git commit
$ git push origin issue1234
```

This snippets adds all your new changes, then amends the previous commit with them. The `--no-edit` means you don't want to edit the commit message; you can omit that option if you need to make commit message changes as well.
When updating the code, it's usually better to add additional commits to your branch rather than amending the original commit, because reviewers can easily tell which changes were made in response to a particular review. When we merge pull requests, we will squash all the commits from your branch into a single commit on the `master` branch.

### Rebasing

If your code is out-of-date, we might ask you to rebase. That means we want you to apply your changes on top of the latest upstream code. Make sure you have set up a [development environment](../development-environment) and then you can rebase using these commands:
If your code is out-of-date, we might ask you to rebase. That means we want you to apply your changes on top of the latest upstream code. Make sure you have set up a [development environment](../development-environment.md) and then you can rebase using these commands:

```
$ git fetch upstream
@@ -1,6 +1,6 @@
# Reporting Bugs

If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests) on GitHub. Be sure to copy the questions from the [bug report template](https://github.com/eslint/eslint/blob/master/templates/bug-report.md).
If you think you've found a bug in ESLint, please [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests.md) on GitHub.

Please include as much detail as possible to help us properly address your issue. If we need to triage issues and constantly ask people for more detail, that's time taken away from actually fixing issues. Help us be as efficient as possible by including a lot of detail in your issues.

@@ -4,15 +4,15 @@ Occasionally, a core ESLint rule needs to be changed. This is not necessarily a

## Proposing a Rule Change

To propose a change to an existing rule, [create a new issue](https://github.com/eslint/eslint/issues/new) or a [pull request](/docs/developer-guide/contributing/pull-requests) on GitHub. Be sure to copy the questions from the [rule change proposal template](https://github.com/eslint/eslint/blob/master/templates/rule-change-proposal.md).
To propose a change to an existing rule, [create a pull request](/docs/developer-guide/contributing/pull-requests.md) or [new issue](https://github.com/eslint/eslint/issues/new?template=RULE_CHANGE.md) and fill out the template.

We need all of this information in order to determine whether or not the change is a good candidate for inclusion.

## Accepting a Rule Change

In order for a rule change to be accepted into ESLint, it must:

1. Adhere to the [Core Rule Guidelines](new-rules#core-rule-guidelines)
1. Adhere to the [Core Rule Guidelines](new-rules.md#core-rule-guidelines)
1. Have an ESLint team member champion the change
1. Be important enough that rule is deemed incomplete without this change

@@ -4,29 +4,19 @@ Our public [issues tracker](https://github.com/eslint/eslint/issues) lists all o

## Issue Labels

We use labels to indicate the status of issues. The most important labels are:
We use labels to indicate the status of issues. The most complete documentation on the labels is found in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#when-an-issue-is-opened), but most contributors should find the information on this page sufficient. The most important questions that labels can help you, as a contributor, answer are:

1. [`triage`](https://github.com/eslint/eslint/issues?labels=triage&milestone=&page=1&state=open) - When an issue is first submitted, it is labeled as `triage`, which means the ESLint team needs to investigate and determine if the request is a bug report, a feature request, or something else. It's best not to work on tickets marked as `triage`, because we're not yet sure if we will accept the issue to work on.
1. [`accepted`](https://github.com/eslint/eslint/issues?labels=accepted&milestone=&page=1&state=open) - Once an issue has been properly triaged and the team decides it must be addressed, someone will assign the `accepted` label to an issue. When an issue is accepted, anyone is free to work on it.
1. [`bug`](https://github.com/eslint/eslint/issues?labels=bug&milestone=&page=1&state=open) - Indicates that the issue is reporting a problem. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "Fix:".
1. [`feature`](https://github.com/eslint/eslint/issues?labels=feature&milestone=&page=1&state=open) - Indicates that the issue is requesting a new feature. Features are functionality that doesn't already exist in the project. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "New:".
1. [`enhancement`](https://github.com/eslint/eslint/issues?labels=enhancement&milestone=&page=1&state=open) - Indicates that the issue is requesting a change to existing functionality. When submitting a pull request to work on this type of issue, be sure to prefix the commit message with "Update:".
1. [`beginner`](https://github.com/eslint/eslint/issues?labels=beginner&milestone=&page=1&state=open) - Indicates that the issue is simple enough that it would be a good first contribution for a new contributor. If you're looking to get started helping out with ESLint, take a look at the beginner issues.
1. [`help wanted`](https://github.com/eslint/eslint/issues?labels=help%20wanted&milestone=&page=1&state=open) - Indicates that the core team won't be working on this issue, however, we will accept pull requests from contributors. This basically means the issue isn't on the formal roadmap but it will be accepted if a contributor wants to implement it.
1. Is this issue available for me to work on? If you have little or no experience contributing to ESLint, the [`good first issue`](https://github.com/eslint/eslint/labels/good%20first%20issue) label marks appropriate issues. Otherwise, the [`help wanted`](https://github.com/eslint/eslint/labels/help%20wanted) label is an invitation to work on the issue. If you have more experience, you can try working on other issues labeled [`accepted`](https://github.com/eslint/eslint/labels/accepted). Conversely, issues not yet ready to work on are labeled `triage`, `evaluating`, and/or `needs bikeshedding`, and issues that cannot currently be worked on because of something else, such as a bug in a dependency, are labeled `blocked`.
1. What is this issue about? Labels describing the nature of issues include `bug`, `enhancement`, `feature`, `question`, `rule`, `documentation`, `core`, `build`, `cli`, `infrastructure`, `breaking`, and `chore`. These are documented in the [Maintainer Guide](https://eslint.org/docs/maintainer-guide/issues.html#types-of-issues).
1. What is the priority of this issue? Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest:

## Bounty Issues
1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible.
1. **Documentation** - documentation issues are a type of bug in that they actively affect current users. As such, we want to address documentation issues as quickly as possible.
1. **Features** - new functionality that will aid users in the future.
1. **Enhancements** - requested improvements for existing functionality.
1. **Other** - anything else.

We accept and assign issue bounties using [BountySource](https://www.bountysource.com/teams/eslint/issues).

## Issue Priority

Because we have a lot of issues, we prioritize certain issues above others. The following is the list of priorities, from highest to lowest:

1. **Bugs** - problems with the project are actively affecting users. We want to get these resolved as quickly as possible.
1. **Documentation** - documentation issues are a type of bug in that they actively affect current users. As such, we want to address documentation issues as quickly as possible.
1. **Features** - new functionality that will aid users in the future.
1. **Enhancements** - requested improvements for existing functionality.
1. **Other** - anything else.
Some issues have had monetary rewards attached to them. Those are labeled `bounty`. Bounties are assigned via [BountySource](https://www.bountysource.com/teams/eslint/issues).

## Starting Work

@@ -4,9 +4,9 @@ ESLint has a very lightweight development environment that makes updating code f

## Step 1: Install Node.js

Go to <http://nodejs.org/> to download and install the latest stable version for your operating system.
Go to <https://nodejs.org/> to download and install the latest stable version for your operating system.

Most of the installers come with [npm](http://npmjs.org/) already installed, but if for some reason it doesn't work on your system, you can install it manually using the instructions on the website.
Most of the installers come with [npm](https://www.npmjs.com/) already installed, but if for some reason it doesn't work on your system, you can install it manually using the instructions on the site.

## Step 2: Fork and checkout your own ESLint repository

@@ -53,15 +53,19 @@ Running the tests is the best way to ensure you have correctly set up your devel
npm test
```

The testing takes a few seconds to complete. If any tests fail, that likely means one or more parts of the environment setup didn't complete correctly. The upstream tests always pass.
The testing takes a few minutes to complete. If any tests fail, that likely means one or more parts of the environment setup didn't complete correctly. The upstream tests always pass.

## Reference Information

### Workflow

## Build Scripts
Once you have your development environment installed, you can make and submit changes to the ESLint source files. Doing this successfully requires careful adherence to our [pull-request submission workflow](contributing/pull-requests.md).

### Build Scripts

ESLint has several build scripts that help with various parts of development.

### npm test
#### npm test

The primary script to use is `npm test`, which does several things:

@@ -75,19 +79,19 @@ Be sure to run this after making changes and before sending a pull request with

**Note:** The full code coverage report is output into `/coverage`.

### npm run lint
#### npm run lint

Runs just the JavaScript and JSON linting on the repository

### npm run browserify
#### npm run webpack

Generates `build/eslint.js`, a version of ESLint for use in the browser

### npm run docs
#### npm run docs

Generates JSDoc documentation and places it into `/jsdoc`.

### npm run profile
#### npm run profile

This command is used for intensive profiling of ESLint using Chrome Developer Tools. It starts a development server that runs through three profiles:

@@ -101,12 +105,3 @@ Your browser should automatically open to the page in question. When that happen
1. Click on Profiles

You should start to see profiles for each run show up on the left side. If not, reload the page in the browser. Once all three profiles have completed, they will be available for inspection.

## Workflow

Whenever you make changes to the ESLint source files, you'll need to run `npm test` to rerun the tests. The workflow is:

1. Make changes
2. Run `npm test` to run tests on the command line

You'll have to do this each time you make a change. The tests are run automatically whenever a pull request is received, so make sure to verify your changes work before submitting them.

Large diffs are not rendered by default.

@@ -0,0 +1,386 @@
# ScopeManager

This document was written based on the implementation of [eslint-scope](https://github.com/eslint/eslint-scope), a fork of [escope](https://github.com/estools/escope), and deprecates some members ESLint is not using.

----

## ScopeManager interface

`ScopeManager` object has all variable scopes.

### Fields

#### scopes

* **Type:** `Scope[]`
* **Description:** All scopes.

#### globalScope

* **Type:** `Scope`
* **Description:** The root scope.

### Methods

#### acquire(node, inner = false)

* **Parameters:**
* `node` (`ASTNode`) ... An AST node to get their scope.
* `inner` (`boolean`) ... If the node has multiple scope, this returns the outermost scope normally. If `inner` is `true` then this returns the innermost scope. Default is `false`.
* **Return type:** `Scope | null`
* **Description:** Get the scope of a given AST node. The gotten scope's `block` property is the node. This method never returns `function-expression-name` scope. If the node does not have their scope, this returns `null`.

#### getDeclaredVariables(node)

* **Parameters:**
* `node` (`ASTNode`) ... An AST node to get their variables.
* **Return type:** `Variable[]`
* **Description:** Get the variables that a given AST node defines. The gotten variables' `def[].node`/`def[].parent` property is the node. If the node does not define any variable, this returns an empty array.

### Deprecated members

Those members are defined but not used in ESLint.

#### isModule()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this program is module.

#### isImpliedStrict()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this program is strict mode implicitly. I.e., `options.impliedStrict === true`.

#### isStrictModeSupported()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this program supports strict mode. I.e., `options.ecmaVersion >= 5`.

#### acquireAll(node)

* **Parameters:**
* `node` (`ASTNode`) ... An AST node to get their scope.
* **Return type:** `Scope[] | null`
* **Description:** Get the scopes of a given AST node. The gotten scopes' `block` property is the node. If the node does not have their scope, this returns `null`.

----

## Scope interface

`Scope` object has all variables and references in the scope.

### Fields

#### type

* **Type:** `string`
* **Description:** The type of this scope. This is one of `"block"`, `"catch"`, `"class"`, `"for"`, `"function"`, `"function-expression-name"`, `"global"`, `"module"`, `"switch"`, `"with"`

#### isStrict

* **Type:** `boolean`
* **Description:** `true` if this scope is strict mode.

#### upper

* **Type:** `Scope | null`
* **Description:** The parent scope. If this is the global scope then this property is `null`.

#### childScopes

* **Type:** `Scope[]`
* **Description:** The array of child scopes. This does not include grandchild scopes.

#### variableScope

* **Type:** `Scope`
* **Description:** The scope which hosts variables which are defined by `var` declarations.

#### block

* **Type:** `ASTNode`
* **Description:** The AST node which created this scope.

#### variables

* **Type:** `Variable[]`
* **Description:** The array of all variables which are defined on this scope. This does not include variables which are defined in child scopes.

#### set

* **Type:** `Map<string, Variable>`
* **Description:** The map from variable names to variable objects.

> I hope to rename `set` field or replace by a method.
#### references

* **Type:** `Reference[]`
* **Description:** The array of all references on this scope. This does not include references in child scopes.

#### through

* **Type:** `Reference[]`
* **Description:** The array of references which could not be resolved in this scope.

#### functionExpressionScope

* **Type:** `boolean`
* **Description:** `true` if this scope is `"function-expression-name"` scope.

> I hope to deprecate `functionExpressionScope` field as replacing by `scope.type === "function-expression-name"`.
### Deprecated members

Those members are defined but not used in ESLint.

#### taints

* **Type:** `Map<string, boolean>`
* **Description:** The map from variable names to `tainted` flag.

#### dynamic

* **Type:** `boolean`
* **Description:** `true` if this scope is dynamic. I.e., the type of this scope is `"global"` or `"with"`.

#### directCallToEvalScope

* **Type:** `boolean`
* **Description:** `true` if this scope contains `eval()` invocations.

#### thisFound

* **Type:** `boolean`
* **Description:** `true` if this scope contains `this`.

#### resolve(node)

* **Parameters:**
* `node` (`ASTNode`) ... An AST node to get their reference object. The type of the node must be `"Identifier"`.
* **Return type:** `Reference | null`
* **Description:** Returns `this.references.find(r => r.identifier === node)`.

#### isStatic()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** Returns `!this.dynamic`.

#### isArgumentsMaterialized()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this is a `"function"` scope which has used `arguments` variable.

#### isThisMaterialized()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** Returns `this.thisFound`.

#### isUsedName(name)

* **Parameters:**
* `name` (`string`) ... The name to check.
* **Return type:** `boolean`
* **Description:** `true` if a given name is used in variable names or reference names.

----

## Variable interface

`Variable` object is variable's information.

### Fields

#### name

* **Type:** `string`
* **Description:** The name of this variable.

#### identifiers

* **Type:** `ASTNode[]`
* **Description:** The array of `Identifier` nodes which define this variable. If this variable is redeclared, this array includes two or more nodes.

> I hope to deprecate `identifiers` field as replacing by `defs[].name` field.
#### references

* **Type:** `Reference[]`
* **Description:** The array of the references of this variable.

#### defs

* **Type:** `Definition[]`
* **Description:** The array of the definitions of this variable.

### Deprecated members

Those members are defined but not used in ESLint.

#### tainted

* **Type:** `boolean`
* **Description:** The `tainted` flag. (always `false`)

#### stack

* **Type:** `boolean`
* **Description:** The `stack` flag. (I'm not sure what this means.)

----

## Reference interface

`Reference` object is reference's information.

### Fields

#### identifier

* **Type:** `ASTNode`
* **Description:** The `Identifier` node of this reference.

#### from

* **Type:** `Scope`
* **Description:** The `Scope` object that this reference is on.

#### resolved

* **Type:** `Variable | null`
* **Description:** The `Variable` object that this reference refers. If such variable was not defined, this is `null`.

#### writeExpr

* **Type:** `ASTNode | null`
* **Description:** The ASTNode object which is right-hand side.

#### init

* **Type:** `boolean`
* **Description:** `true` if this writing reference is a variable initializer or a default value.

### Methods

#### isWrite()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is writing.

#### isRead()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is reading.

#### isWriteOnly()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is writing but not reading.

#### isReadOnly()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is reading but not writing.

#### isReadWrite()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is reading and writing.

### Deprecated members

Those members are defined but not used in ESLint.

#### tainted

* **Type:** `boolean`
* **Description:** The `tainted` flag. (always `false`)

#### flag

* **Type:** `number`
* **Description:** `1` is reading, `2` is writing, `3` is reading/writing.

#### partial

* **Type:** `boolean`
* **Description:** The `partial` flag.

#### isStatic()

* **Parameters:**
* **Return type:** `boolean`
* **Description:** `true` if this reference is resolved statically.

----

## Definition interface

`Definition` object is variable definition's information.

### Fields

#### type

* **Type:** `string`
* **Description:** The type of this definition. One of `"CatchClause"`, `"ClassName"`, `"FunctionName"`, `"ImplicitGlobalVariable"`, `"ImportBinding"`, `"Parameter"`, and `"Variable"`.

#### name

* **Type:** `ASTNode`
* **Description:** The `Identifier` node of this definition.

#### node

* **Type:** `ASTNode`
* **Description:** The enclosing node of the name.

| type | node |
|:---------------------------|:-----|
| `"CatchClause"` | `CatchClause`
| `"ClassName"` | `ClassDeclaration` or `ClassExpression`
| `"FunctionName"` | `FunctionDeclaration` or `FunctionExpression`
| `"ImplicitGlobalVariable"` | `Program`
| `"ImportBinding"` | `ImportSpecifier`, `ImportDefaultSpecifier`, or `ImportNamespaceSpecifier`
| `"Parameter"` | `FunctionDeclaration`, `FunctionExpression`, or `ArrowFunctionExpression`
| `"Variable"` | `VariableDeclarator`

#### parent

* **Type:** `ASTNode | undefined | null`
* **Description:** The enclosing statement node of the name.

| type | parent |
|:---------------------------|:-------|
| `"CatchClause"` | `null`
| `"ClassName"` | `null`
| `"FunctionName"` | `null`
| `"ImplicitGlobalVariable"` | `null`
| `"ImportBinding"` | `ImportDeclaration`
| `"Parameter"` | `null`
| `"Variable"` | `VariableDeclaration`

### Deprecated members

Those members are defined but not used in ESLint.

#### index

* **Type:** `number | undefined | null`
* **Description:** The index in the declaration statement.

#### kind

* **Type:** `string | undefined | null`
* **Description:** The kind of the declaration statement.
@@ -32,7 +32,7 @@ The following selectors are supported:
* attribute existence: `[attr]`
* attribute value: `[attr="foo"]` or `[attr=123]`
* attribute regex: `[attr=/foo.*/]`
* attribute conditons: `[attr!="foo"]`, `[attr>2]`, `[attr<3]`, `[attr>=2]`, or `[attr<=3]`
* attribute conditions: `[attr!="foo"]`, `[attr>2]`, `[attr<3]`, `[attr>=2]`, or `[attr<=3]`
* nested attribute: `[attr.level2="foo"]`
* field: `FunctionDeclaration > Identifier.id`
* First or last child: `:first-child` or `:last-child`
@@ -90,7 +90,7 @@ If multiple selectors have equal specificity, their listeners will be called in

### Restricting syntax with selectors

With the [no-restricted-syntax](/docs/rules/no-restricted-syntax) rule, you can restrict the usage of particular syntax in your code. For example, you can use the following configuration to disallow using `if` statements that do not have block statements as their body:
With the [no-restricted-syntax](/docs/rules/no-restricted-syntax.md) rule, you can restrict the usage of particular syntax in your code. For example, you can use the following configuration to disallow using `if` statements that do not have block statements as their body:

```json
{
@@ -1,10 +1,14 @@
# Shareable Configs

The configuration that you have in your `.eslintrc` file is an important part of your project, and as such, you may want to share it with other projects or people. Shareable configs allow you to publish your configuration settings on [npm](https://npmjs.com) and have others download and use it in their ESLint projects.
The configuration that you have in your `.eslintrc` file is an important part of your project, and as such, you may want to share it with other projects or people. Shareable configs allow you to publish your configuration settings on [npm](https://www.npmjs.com/) and have others download and use it in their ESLint projects.

## Creating a Shareable Config

Shareable configs are simply npm packages that export a configuration object. To start, [create a Node.js module](https://docs.npmjs.com/getting-started/creating-node-modules) like you normally would. Make sure the module name begins with `eslint-config-`, such as `eslint-config-myconfig`. Create a new `index.js` file and export an object containing your settings:
Shareable configs are simply npm packages that export a configuration object. To start, [create a Node.js module](https://docs.npmjs.com/getting-started/creating-node-modules) like you normally would. Make sure the module name begins with `eslint-config-`, such as `eslint-config-myconfig`.

npm [scoped modules](https://docs.npmjs.com/misc/scope) are also supported, by naming or prefixing the module with `@scope/eslint-config`, such as `@scope/eslint-config` or `@scope/eslint-config-myconfig`.

Create a new `index.js` file and export an object containing your settings:

```js
module.exports = {
@@ -26,14 +30,16 @@ Since `index.js` is just JavaScript, you can optionally read these settings from

Once your shareable config is ready, you can [publish to npm](https://docs.npmjs.com/getting-started/publishing-npm-packages) to share with others. We recommend using the `eslint` and `eslintconfig` keywords so others can easily find your module.

You should declare your dependency on eslint in `package.json` using the [peerDependencies](https://docs.npmjs.com/files/package.json#peerdependencies) field. The recommended way to declare a dependency for future proof compatibility is with the ">=" range syntax, using the lowest required eslint version. For example:
You should declare your dependency on ESLint in `package.json` using the [peerDependencies](https://docs.npmjs.com/files/package.json#peerdependencies) field. The recommended way to declare a dependency for future proof compatibility is with the ">=" range syntax, using the lowest required ESLint version. For example:

```
peerDependencies: {
"peerDependencies": {
"eslint": ">= 3"
}
```

If your shareable config depends on a plugin, you should also specify it as a `peerDependency` (plugins will be loaded relative to the end user's project, so the end user is required to install the plugins they need). However, if your shareable config depends on a third-party parser or another shareable config, you can specify these packages as `dependencies`.

You can also test your shareable config on your computer before publishing by linking your module globally. Type:

```bash
@@ -66,6 +72,35 @@ You can also omit the `eslint-config-` and it will be automatically assumed by E
}
```

### npm scoped modules

npm [scoped modules](https://docs.npmjs.com/misc/scope) are also supported in a number of ways.


By using the module name:

```json
{
"extends": "@scope/eslint-config"
}
```

You can also omit the `eslint-config` and it will be automatically assumed by ESLint:

```json
{
"extends": "@scope"
}
```

The module name can also be customized, just note that when using [scoped modules](https://docs.npmjs.com/misc/scope) it is not possible to omit the `eslint-config-` prefix. Doing so would result in package naming conflicts, and thus in resolution errors in most of cases. For example a package named `@scope/eslint-config-myconfig` vs `@scope/my-config`, since both are valid scoped package names, the configuration should be specified as:

```json
{
"extends": "@scope/eslint-config-myconfig"
}
```

You can override settings from the shareable config by adding them directly into your `.eslintrc` file.

## Sharing Multiple Configs
@@ -77,7 +112,7 @@ As an example, you can create a file called `my-special-config.js` in the root o
```js
module.exports = {
rules: {
quotes: [2, "double"];
quotes: [2, "double"]
}
};
```
@@ -90,6 +125,14 @@ Then, assuming you're using the package name `eslint-config-myconfig`, you can a
}
```

When using [scoped modules](https://docs.npmjs.com/misc/scope) it is not possible to omit the `eslint-config` namespace. Doing so would result in resolution errors as explained above. Assuming the package name is `@scope/eslint-config`, the additional config can be accessed as:

```json
{
"extends": "@scope/eslint-config/my-special-config"
}
```

Note that you can leave off the `.js` from the filename. In this way, you can add as many additional configs to your package as you'd like.

**Important:** We strongly recommend always including a default config for your plugin to avoid errors.
@@ -1,19 +1,19 @@
# Source Code

ESLint is hosted at [GitHub](https://github.com/eslint/eslint) and uses [Git](http://git-scm.com/) for source control. In order to obtain the source code, you must first install Git on your system. Instructions for installing and setting up Git can be found at [http://help.github.com/set-up-git-redirect](http://help.github.com/set-up-git-redirect).
ESLint is hosted at [GitHub](https://github.com/eslint/eslint) and uses [Git](https://git-scm.com/) for source control. In order to obtain the source code, you must first install Git on your system. Instructions for installing and setting up Git can be found at [https://help.github.com/articles/set-up-git/](https://help.github.com/articles/set-up-git/).

If you simply want to create a local copy of the source to play with, you can clone the main repository using this command:

git clone git://github.com/eslint/eslint.git

If you're planning on contributing to ESLint, then it's a good idea to fork the repository. You can find instructions for forking a repository at [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/). After forking the ESLint repository, you'll want to create a local copy of your fork.
If you're planning on contributing to ESLint, then it's a good idea to fork the repository. You can find instructions for forking a repository at [https://help.github.com/articles/fork-a-repo/](https://help.github.com/articles/fork-a-repo/). After forking the ESLint repository, you'll want to create a local copy of your fork.

## Start Developing

Before you can get started developing, you'll need to have a couple of things installed:

* [Node.JS](http://nodejs.org)
* [npm](http://npmjs.org)
* [Node.JS](https://nodejs.org)
* [npm](https://www.npmjs.com/)

Once you have a local copy and have Node.JS and npm installed, you'll need to install the ESLint dependencies:

@@ -1,6 +1,6 @@
# Unit Tests

Most parts of ESLint have unit tests associated with them. Unit tests are written using [Mocha](http://mochajs.org/) and are required when making contributions to ESLint. You'll find all of the unit tests in the `tests` directory.
Most parts of ESLint have unit tests associated with them. Unit tests are written using [Mocha](https://mochajs.org/) and are required when making contributions to ESLint. You'll find all of the unit tests in the `tests` directory.

When you first get the source code, you need to run `npm install` once initially to set ESLint for development. Once you've done that, you can run the tests via:

@@ -12,6 +12,10 @@ This automatically starts Mocha and runs all tests in the `tests` directory. You

If you want to quickly run just one test, you can do so by running Mocha directly and passing in the filename. For example:

./node_modules/.bin/mocha tests/lib/rules/no-wrap-func.js
npm test:cli tests/lib/rules/no-wrap-func.js

Running individual tests is useful when you're working on a specific bug and iterating on the solution. You should be sure to run `npm test` before submitting a pull request.

## More Control on Unit Testing

`npm test:cli` is an alias of the Mocha cli in `./node_modules/.bin/mocha`. [Options](https://mochajs.org/#command-line-usage) are available to be provided to help to better control the test to run.