Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update: no-restricted-globals custom error messages (fixes #8315) (#8932
)

* Update: no-restricted-globals custom error messages (fixes #8315)

* Using option "name" instead of "global"
  • Loading branch information
platinumazure authored and ilyavolodin committed Jul 16, 2017
1 parent a747b6f commit fb8005d
Show file tree
Hide file tree
Showing 3 changed files with 217 additions and 25 deletions.
41 changes: 40 additions & 1 deletion docs/rules/no-restricted-globals.md
Expand Up @@ -13,7 +13,35 @@ This rule allows you to specify global variable names that you don't want to use

## Options

This rule takes a list of strings which are the global variable names.
This rule takes a list of strings, where each string is a global to be restricted:

```json
{
"rules": {
"no-restricted-globals": ["error", "event", "fdescribe"]
}
}
```

Alternatively, the rule also accepts objects, where the global name and an optional custom message are specified:

```json
{
"rules": {
"no-restricted-globals": [
"error",
{
"name": "event",
"message": "Use local parameter instead."
},
{
"name": "fdescribe",
"message": "Do not commit fdescribe. Use describe instead."
}
]
}
}
```

Examples of **incorrect** code for sample `"event", "fdescribe"` global variable names:

Expand Down Expand Up @@ -45,6 +73,17 @@ import event from "event-module";
var event = 1;
```

Examples of **incorrect** code for a sample `"event"` global variable name, along with a custom error message:

```js
/*global event*/
/* eslint no-restricted-globals: [{ name: "error", message: "Use local parameter instead." }] */

function onClick() {
console.log(event); // Unexpected global variable 'event'. Use local parameter instead.
}
```

## Related Rules

* [no-restricted-properties](no-restricted-properties.md)
Expand Down
59 changes: 50 additions & 9 deletions lib/rules/no-restricted-globals.js
Expand Up @@ -4,6 +4,13 @@
*/
"use strict";

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

const DEFAULT_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'.",
CUSTOM_MESSAGE_TEMPLATE = "Unexpected use of '{{name}}'. {{customMessage}}";

//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
Expand All @@ -19,30 +26,64 @@ module.exports = {
schema: {
type: "array",
items: {
type: "string"
oneOf: [
{
type: "string"
},
{
type: "object",
properties: {
name: { type: "string" },
message: { type: "string" }
},
required: ["name"],
additionalProperties: false
}
]
},
uniqueItems: true
uniqueItems: true,
minItems: 0
}
},

create(context) {
const restrictedGlobals = context.options;

// if no globals are restricted we don't need to check
if (restrictedGlobals.length === 0) {
// If no globals are restricted, we don't need to do anything
if (context.options.length === 0) {
return {};
}

const restrictedGlobalMessages = context.options.reduce((memo, option) => {
if (typeof option === "string") {
memo[option] = null;
} else {
memo[option.name] = option.message;
}

return memo;
}, {});

/**
* Report a variable to be used as a restricted global.
* @param {Reference} reference the variable reference
* @returns {void}
* @private
*/
function reportReference(reference) {
context.report({ node: reference.identifier, message: "Unexpected use of '{{name}}'.", data: {
name: reference.identifier.name
} });
const name = reference.identifier.name,
customMessage = restrictedGlobalMessages[name],
message = customMessage
? CUSTOM_MESSAGE_TEMPLATE
: DEFAULT_MESSAGE_TEMPLATE;

context.report({
node: reference.identifier,
message,
data: {
name,
customMessage
}
});
}

/**
Expand All @@ -52,7 +93,7 @@ module.exports = {
* @private
*/
function isRestricted(name) {
return restrictedGlobals.indexOf(name) >= 0;
return restrictedGlobalMessages.hasOwnProperty(name);
}

return {
Expand Down
142 changes: 127 additions & 15 deletions tests/lib/rules/no-restricted-globals.js
Expand Up @@ -20,46 +20,158 @@ const ruleTester = new RuleTester();

ruleTester.run("no-restricted-globals", rule, {
valid: [
{ code: "foo" },
{ code: "foo", options: ["bar"] },
{ code: "var foo = 1;", options: ["foo"] },
{ code: "event", env: { browser: true }, options: ["bar"] },
{ code: "import foo from 'bar';", options: ["foo"], parserOptions: { ecmaVersion: 6, sourceType: "module" } },
{ code: "function foo() {}", options: ["foo"] },
{ code: "function fn() { var foo; }", options: ["foo"] },
{ code: "foo.bar", options: ["bar"] }
{
code: "foo"
},
{
code: "foo",
options: ["bar"]
},
{
code: "var foo = 1;",
options: ["foo"]
},
{
code: "event",
env: { browser: true },
options: ["bar"]
},
{
code: "import foo from 'bar';",
options: ["foo"],
parserOptions: { ecmaVersion: 6, sourceType: "module" }
},
{
code: "function foo() {}",
options: ["foo"]
},
{
code: "function fn() { var foo; }",
options: ["foo"]
},
{
code: "foo.bar",
options: ["bar"]
},
{
code: "foo",
options: [{ name: "bar", message: "Use baz instead." }]
}
],
invalid: [
{
code: "foo", options: ["foo"],
code: "foo",
options: ["foo"],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: ["foo"],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: ["foo"],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "event",
options: ["foo", "event"],
env: { browser: true },
errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }]
},
{
code: "foo",
options: ["foo"],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "foo()",
options: ["foo"],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }", options: ["foo"],
code: "foo.bar()",
options: ["foo"],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }", options: ["foo"],
code: "foo",
options: [{ name: "foo" }],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: [{ name: "foo" }],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: [{ name: "foo" }],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "event", options: ["foo", "event"],
code: "event",
options: ["foo", { name: "event" }],
env: { browser: true },
errors: [{ message: "Unexpected use of 'event'.", type: "Identifier" }]
},
{
code: "foo", options: ["foo"],
code: "foo",
options: [{ name: "foo" }],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "foo()", options: ["foo"],
code: "foo()",
options: [{ name: "foo" }],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "foo.bar()", options: ["foo"],
code: "foo.bar()",
options: [{ name: "foo" }],
errors: [{ message: "Unexpected use of 'foo'.", type: "Identifier" }]
},
{
code: "foo",
options: [{ name: "foo", message: "Use bar instead." }],
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: [{ name: "foo", message: "Use bar instead." }],
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
},
{
code: "function fn() { foo; }",
options: [{ name: "foo", message: "Use bar instead." }],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
},
{
code: "event",
options: ["foo", { name: "event", message: "Use local event parameter." }],
env: { browser: true },
errors: [{ message: "Unexpected use of 'event'. Use local event parameter.", type: "Identifier" }]
},
{
code: "foo",
options: [{ name: "foo", message: "Use bar instead." }],
globals: { foo: false },
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
},
{
code: "foo()",
options: [{ name: "foo", message: "Use bar instead." }],
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
},
{
code: "foo.bar()",
options: [{ name: "foo", message: "Use bar instead." }],
errors: [{ message: "Unexpected use of 'foo'. Use bar instead.", type: "Identifier" }]
}
]
});

0 comments on commit fb8005d

Please sign in to comment.