Skip to content

Commit

Permalink
Update: allow custom messages in no-restricted-syntax (fixes #8298) (#…
Browse files Browse the repository at this point in the history
…8357)

* Update: add new schema to no-restricted-syntax (fixes #8298)

* Address review suggestions
  • Loading branch information
vitorbal authored and not-an-aardvark committed Mar 31, 2017
1 parent 35c93e6 commit 91baed4
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 8 deletions.
26 changes: 25 additions & 1 deletion docs/rules/no-restricted-syntax.md
Expand Up @@ -12,7 +12,7 @@ This rule disallows specified (that is, user-defined) syntax.

## Options

This rule takes a list of strings:
This rule takes a list of strings, where each string is an AST selector:

```json
{
Expand All @@ -22,6 +22,30 @@ This rule takes a list of strings:
}
```

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

```json
{
"rules": {
"no-restricted-syntax": [
"error",
{
"selector": "FunctionExpression",
"message": "Function expressions are not allowed."
},
{
"selector": "CallExpression[callee.name='setTimeout'][arguments.length!=2]",
"message": "setTimeout must always be invoked with two arguments."
}
]
}
}
```

If a custom message is specified with the `message` property, ESLint will use that message when reporting occurrences of the syntax specified in the `selector` property.

The string and object formats can be freely mixed in the configuration as needed.

Examples of **incorrect** code for this rule with the `"FunctionExpression", "WithStatement", BinaryExpression[operator='in']` options:

```js
Expand Down
39 changes: 33 additions & 6 deletions lib/rules/no-restricted-syntax.js
Expand Up @@ -18,18 +18,45 @@ module.exports = {

schema: {
type: "array",
items: [{ type: "string" }],
items: [{
oneOf: [
{
type: "string"
},
{
type: "object",
properties: {
selector: { type: "string" },
message: { type: "string" }
},
required: ["selector"],
additionalProperties: false
}
]
}],
uniqueItems: true,
minItems: 0
}
},

create(context) {
return context.options.reduce((result, selector) => Object.assign(result, {
[selector](node) {
context.report({ node, message: "Using '{{selector}}' is not allowed.", data: { selector } });
}
}), {});
return context.options.reduce((result, selectorOrObject) => {
const isStringFormat = (typeof selectorOrObject === "string");
const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message);

const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector;
const message = hasCustomMessage ? selectorOrObject.message : "Using '{{selector}}' is not allowed.";

return Object.assign(result, {
[selector](node) {
context.report({
node,
message,
data: hasCustomMessage ? {} : { selector }
});
}
});
}, {});

}
};
38 changes: 37 additions & 1 deletion tests/lib/rules/no-restricted-syntax.js
Expand Up @@ -19,16 +19,28 @@ const ruleTester = new RuleTester();

ruleTester.run("no-restricted-syntax", rule, {
valid: [

// string format
{ code: "doSomething();" },
{ code: "var foo = 42;", options: ["ConditionalExpression"] },
{ code: "foo += 42;", options: ["VariableDeclaration", "FunctionExpression"] },
{ code: "foo;", options: ["Identifier[name=\"bar\"]"] },
{ code: "() => 5", options: ["ArrowFunctionExpression > BlockStatement"], parserOptions: { ecmaVersion: 6 } },
{ code: "({ foo: 1, bar: 2 })", options: ["Property > Literal.key"] },
{ code: "A: for (;;) break;", options: ["BreakStatement[label]"] },
{ code: "function foo(bar, baz) {}", options: ["FunctionDeclaration[params.length>2]"] }
{ code: "function foo(bar, baz) {}", options: ["FunctionDeclaration[params.length>2]"] },

// object format
{ code: "var foo = 42;", options: [{ selector: "ConditionalExpression" }] },
{ code: "({ foo: 1, bar: 2 })", options: [{ selector: "Property > Literal.key" }] },
{
code: "({ foo: 1, bar: 2 })",
options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom error message." }]
}
],
invalid: [

// string format
{
code: "var foo = 41;",
options: ["VariableDeclaration"],
Expand Down Expand Up @@ -82,6 +94,30 @@ ruleTester.run("no-restricted-syntax", rule, {
code: "function foo(bar, baz, qux) {}",
options: ["FunctionDeclaration[params.length>2]"],
errors: [{ message: "Using 'FunctionDeclaration[params.length>2]' is not allowed.", type: "FunctionDeclaration" }]
},

// object format
{
code: "var foo = 41;",
options: [{ selector: "VariableDeclaration" }],
errors: [{ message: "Using 'VariableDeclaration' is not allowed.", type: "VariableDeclaration" }]
},
{
code: "function foo(bar, baz, qux) {}",
options: [{ selector: "FunctionDeclaration[params.length>2]" }],
errors: [{ message: "Using 'FunctionDeclaration[params.length>2]' is not allowed.", type: "FunctionDeclaration" }]
},
{
code: "function foo(bar, baz, qux) {}",
options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom error message." }],
errors: [{ message: "custom error message.", type: "FunctionDeclaration" }]
},

// with object format, the custom message may contain the string '{{selector}}'
{
code: "function foo(bar, baz, qux) {}",
options: [{ selector: "FunctionDeclaration[params.length>2]", message: "custom message with {{selector}}" }],
errors: [{ message: "custom message with {{selector}}", type: "FunctionDeclaration" }]
}
]
});

0 comments on commit 91baed4

Please sign in to comment.