Repository: eslint/eslint
Pull request #9513 (2017-10-25 07:09:53)

Chore: remove `npm run check-commit` script
<!--
    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)**

[x] Other, please explain:

<!--
    If the item you've checked above has a template, please paste the template questions below and answer them. (If this pull request is addressing an issue, you can just paste a link to the issue here instead.)
-->

<!--
    Please ensure your pull request is ready:

    - 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)
-->

<!--
    The following is required for all pull requests:
-->

**What changes did you make? (Give an overview)**

The check-commit npm script seems useful in theory, but it doesn't accurately reflect the current commit conventions. For example, it still instructs users to squash their commits, when we no longer advise this. Additionally, the commit message on a branch is sometimes irrelevant to the commit message that gets created when a PR is merged (only the PR title matters when a branch has more than two commits).

**Is there anything you'd like reviewers to focus on?**

Do you use `check-commit`? It seems like it could be useful in the case when there is only one commit on a branch, even though it's misleading when there is more than one commit.

platinumazure: Does the new bot check PR titles and/or sole commit messages so that this is completely obsolete for us?
not-an-aardvark: The new bot does check those things, yes.

Of course, the new bot only works after a PR has already been created, so I wouldn't say the script is completely obsolete (it could be useful id someone wants to check their commit message length before creating a PR).

Patch:
diff --git a/Makefile.js b/Makefile.js
index 81d4d34d0..30220062d 100644
--- a/Makefile.js
+++ b/Makefile.js
@@ -85,9 +85,6 @@ const NODE = "node ", // intentional extra space
     PERF_MULTIFILES_TARGET_DIR = path.join(PERF_TMP_DIR, "eslint"),
     PERF_MULTIFILES_TARGETS = `"${PERF_MULTIFILES_TARGET_DIR + path.sep}{lib,tests${path.sep}lib}${path.sep}**${path.sep}*.js"`,
 
-    // Regex
-    TAG_REGEX = /^(?:Breaking|Build|Chore|Docs|Fix|New|Update|Upgrade):/,
-
     // Settings
     MOCHA_TIMEOUT = 10000;
 
@@ -383,24 +380,6 @@ function getFirstVersionOfDeletion(filePath) {
         .sort(semver.compare)[0];
 }
 
-
-/**
- * Returns all the branch names
- * @returns {string[]} branch names
- * @private
- */
-function getBranches() {
-    const branchesRaw = splitCommandResultToLines(execSilent("git branch --list")),
-        branches = [];
-
-    for (let i = 0; i < branchesRaw.length; i++) {
-        const branchName = branchesRaw[i].replace(/^\*(.*)/, "$1").trim();
-
-        branches.push(branchName);
-    }
-    return branches;
-}
-
 /**
  * Lints Markdown files.
  * @param {array} files Array of file names to lint.
@@ -445,18 +424,6 @@ function lintMarkdown(files) {
     return { code: returnCode };
 }
 
-/**
- * Check if the branch name is valid
- * @param {string} branchName Branch name to check
- * @returns {boolean} true is branch exists
- * @private
- */
-function hasBranch(branchName) {
-    const branches = getBranches();
-
-    return branches.indexOf(branchName) !== -1;
-}
-
 /**
  * Gets linting results from every formatter, based on a hard-coded snippet and config
  * @returns {Object} Output from each formatter
@@ -954,57 +921,6 @@ target.checkLicenses = function() {
     });
 };
 
-target.checkGitCommit = function() {
-    let commitMsgs,
-        failed;
-
-    if (hasBranch("master")) {
-        commitMsgs = splitCommandResultToLines(execSilent("git log HEAD --not master --format=format:%s --no-merges"));
-    } else {
-        commitMsgs = [execSilent("git log -1 --format=format:%s --no-merges")];
-    }
-
-    echo("Validating Commit Message");
-
-    // No commit since master should not cause test to fail
-    if (commitMsgs[0] === "") {
-        return;
-    }
-
-    // Check for more than one commit
-    if (commitMsgs.length > 1) {
-        echo(" - More than one commit found, please squash.");
-        failed = true;
-    }
-
-    // Only check non-release messages
-    if (!semver.valid(commitMsgs[0]) && !commitMsgs[0].startsWith("Revert")) {
-        if (commitMsgs[0].split(/\r?\n/)[0].length > 72) {
-            echo(" - First line of commit message must not exceed 72 characters");
-            failed = true;
-        }
-
-        // Check for tag at start of message
-        if (!TAG_REGEX.test(commitMsgs[0])) {
-            echo([" - Commit summary must start with one of:",
-                "    'Fix:'",
-                "    'Update:'",
-                "    'Breaking:'",
-                "    'Docs:'",
-                "    'Build:'",
-                "    'New:'",
-                "    'Upgrade:'",
-                "    'Chore:'",
-                "   Please refer to the contribution guidelines for more details."].join("\n"));
-            failed = true;
-        }
-    }
-
-    if (failed) {
-        exit(1);
-    }
-};
-
 /**
  * Downloads a repository which has many js files to test performance with multi files.
  * Here, it's eslint@1.10.3 (450 files)
diff --git a/docs/developer-guide/contributing/pull-requests.md b/docs/developer-guide/contributing/pull-requests.md
index efeca5fcd..84990a758 100644
--- a/docs/developer-guide/contributing/pull-requests.md
+++ b/docs/developer-guide/contributing/pull-requests.md
@@ -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.
diff --git a/docs/developer-guide/contributing/working-on-issues.md b/docs/developer-guide/contributing/working-on-issues.md
index 95282aa9c..c1878dbea 100644
--- a/docs/developer-guide/contributing/working-on-issues.md
+++ b/docs/developer-guide/contributing/working-on-issues.md
@@ -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 [`beginner`](https://github.com/eslint/eslint/labels/beginner) 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
 
diff --git a/lib/cli.js b/lib/cli.js
index f04448097..6a5482bf9 100644
--- a/lib/cli.js
+++ b/lib/cli.js
@@ -144,6 +144,8 @@ const cli = {
 
         const files = currentOptions._;
 
+        const useStdin = typeof text === "string";
+
         if (currentOptions.version) { // version from package.json
 
             log.info(`v${require("../package.json").version}`);
@@ -153,7 +155,7 @@ const cli = {
                 log.error("The --print-config option must be used with exactly one file name.");
                 return 1;
             }
-            if (text) {
+            if (useStdin) {
                 log.error("The --print-config option is not available for piped-in code.");
                 return 1;
             }
@@ -164,27 +166,27 @@ const cli = {
 
             log.info(JSON.stringify(fileConfig, null, "  "));
             return 0;
-        } else if (currentOptions.help || (!files.length && !text)) {
+        } else if (currentOptions.help || (!files.length && !useStdin)) {
 
             log.info(options.generateHelp());
 
         } else {
 
-            debug(`Running on ${text ? "text" : "files"}`);
+            debug(`Running on ${useStdin ? "text" : "files"}`);
 
             if (currentOptions.fix && currentOptions.fixDryRun) {
                 log.error("The --fix option and the --fix-dry-run option cannot be used together.");
                 return 1;
             }
 
-            if (text && currentOptions.fix) {
+            if (useStdin && currentOptions.fix) {
                 log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead.");
                 return 1;
             }
 
             const engine = new CLIEngine(translateOptions(currentOptions));
 
-            const report = text ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);
+            const report = useStdin ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);
 
             if (currentOptions.fix) {
                 debug("Fix mode enabled - applying fixes");
diff --git a/lib/rules/no-var.js b/lib/rules/no-var.js
index c74e0b9ad..d3c163e55 100644
--- a/lib/rules/no-var.js
+++ b/lib/rules/no-var.js
@@ -15,6 +15,15 @@ const astUtils = require("../ast-utils");
 // Helpers
 //------------------------------------------------------------------------------
 
+/**
+ * Check whether a given variable is a global variable or not.
+ * @param {eslint-scope.Variable} variable The variable to check.
+ * @returns {boolean} `true` if the variable is a global variable.
+ */
+function isGlobal(variable) {
+    return Boolean(variable.scope) && variable.scope.type === "global";
+}
+
 /**
  * Finds the nearest function scope or global scope walking up the scope
  * hierarchy.
@@ -203,6 +212,7 @@ module.exports = {
          * Checks whether it can fix a given variable declaration or not.
          * It cannot fix if the following cases:
          *
+         * - A variable is a global variable.
          * - A variable is declared on a SwitchCase node.
          * - A variable is redeclared.
          * - A variable is used from outside the scope.
@@ -256,6 +266,7 @@ module.exports = {
 
             if (node.parent.type === "SwitchCase" ||
                 node.declarations.some(hasSelfReferenceInTDZ) ||
+                variables.some(isGlobal) ||
                 variables.some(isRedeclared) ||
                 variables.some(isUsedFromOutsideOf(scopeNode))
             ) {
diff --git a/package.json b/package.json
index 9bc6d9ed4..6db06e806 100644
--- a/package.json
+++ b/package.json
@@ -20,8 +20,7 @@
     "browserify": "node Makefile.js browserify",
     "perf": "node Makefile.js perf",
     "profile": "beefy tests/bench/bench.js --open -- -t brfs -t ./tests/bench/xform-rules.js -r espree",
-    "coveralls": "cat ./coverage/lcov.info | coveralls",
-    "check-commit": "node Makefile.js checkGitCommit"
+    "coveralls": "cat ./coverage/lcov.info | coveralls"
   },
   "files": [
     "LICENSE",


Test patch:
diff --git a/tests/lib/cli.js b/tests/lib/cli.js
index b77cfcde7..8a8bc938a 100644
--- a/tests/lib/cli.js
+++ b/tests/lib/cli.js
@@ -101,6 +101,13 @@ describe("cli", () => {
             assert.strictEqual(result, 1);
         });
 
+        it("should not print debug info when passed the empty string as text", () => {
+            const result = cli.execute(["--stdin", "--no-eslintrc"], "");
+
+            assert.strictEqual(result, 0);
+            assert.isTrue(log.info.notCalled);
+        });
+
         it("should return no error when --ext .js2 is specified", () => {
             const filePath = getFixturePath("files");
             const result = cli.execute(`--ext .js2 ${filePath}`);
diff --git a/tests/lib/rules/no-var.js b/tests/lib/rules/no-var.js
index 830104180..48511d825 100644
--- a/tests/lib/rules/no-var.js
+++ b/tests/lib/rules/no-var.js
@@ -21,13 +21,22 @@ const ruleTester = new RuleTester({ parserOptions: { ecmaVersion: 6 } });
 ruleTester.run("no-var", rule, {
     valid: [
         "const JOE = 'schmoe';",
-        "let moo = 'car';"
+        "let moo = 'car';",
+        {
+            code: "const JOE = 'schmoe';",
+            parserOptions: { ecmaFeatures: { globalReturn: true } }
+        },
+        {
+            code: "let moo = 'car';",
+            parserOptions: { ecmaFeatures: { globalReturn: true } }
+        }
     ],
 
     invalid: [
         {
             code: "var foo = bar;",
             output: "let foo = bar;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -38,6 +47,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var foo = bar, toast = most;",
             output: "let foo = bar, toast = most;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -48,6 +58,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var foo = bar; let toast = most;",
             output: "let foo = bar; let toast = most;",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -58,6 +69,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of b) { console.log(a); }",
             output: "for (let a of b) { console.log(a); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -68,6 +80,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a in b) { console.log(a); }",
             output: "for (let a in b) { console.log(a); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -78,6 +91,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (let a of b) { var c = 1; console.log(c); }",
             output: "for (let a of b) { let c = 1; console.log(c); }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 {
                     message: "Unexpected var, use let or const instead.",
@@ -88,6 +102,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0; i < list.length; ++i) { foo(i) }",
             output: "for (let i = 0; i < list.length; ++i) { foo(i) }",
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
@@ -95,6 +110,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0, i = 0; false;);",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
@@ -102,6 +118,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var i = 0; for (var i = 1; false;); console.log(i);",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" },
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
@@ -112,6 +129,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a, b, c; var a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -120,6 +138,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a; if (b) { var a; }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -128,6 +147,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "if (foo) { var a, b, c; } a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -135,6 +155,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var i = 0; i < 10; ++i) {} i;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -142,6 +163,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a in obj) {} a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -149,6 +171,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of list) {} a;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -156,6 +179,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "switch (a) { case 0: var b = 1 }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -165,6 +189,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (var a of b) { arr.push(() => a); }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -172,6 +197,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "for (let a of b) { var c; console.log(c); c = 'hello'; }",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -181,6 +207,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = a",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -188,7 +215,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a = a} = {}",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -196,7 +223,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a = b, b} = {}",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -204,7 +231,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var {a, b = a} = {}",
             output: "let {a, b = a} = {}",
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -212,7 +239,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = b, b = 1",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -220,7 +247,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "var a = b; var b = 1",
             output: "let a = b; var b = 1",
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead.",
                 "Unexpected var, use let or const instead."
@@ -232,7 +259,7 @@ ruleTester.run("no-var", rule, {
         {
             code: "function foo() { a } var a = 1; foo()",
             output: null,
-            parserOptions: { ecmaVersion: 2015 },
+            parserOptions: { ecmaVersion: 2015, ecmaFeatures: { globalReturn: true } },
             errors: [
                 "Unexpected var, use let or const instead."
             ]
@@ -242,9 +269,33 @@ ruleTester.run("no-var", rule, {
         {
             code: "if (foo) var bar = 1;",
             output: null,
+            parserOptions: { ecmaFeatures: { globalReturn: true } },
             errors: [
                 { message: "Unexpected var, use let or const instead.", type: "VariableDeclaration" }
             ]
+        },
+
+        // https://github.com/eslint/eslint/issues/9520
+        {
+            code: "var foo = 1",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "{ var foo = 1 }",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "if (true) { var foo = 1 }",
+            output: null,
+            errors: ["Unexpected var, use let or const instead."]
+        },
+        {
+            code: "var foo = 1",
+            output: "let foo = 1",
+            parserOptions: { sourceType: "module" },
+            errors: ["Unexpected var, use let or const instead."]
         }
     ]
 });