@babel/eslint-plugin: Update rules/tests to use @babel/eslint-parser (#10977)

* Use @babel/eslint-parser for tests

* Update rules/tests

* Update docs

* add @babel/eslint-shared-fixtures to package.json

* remove bug fix

* convert RuleTester to ESM

* Update devDep versions
This commit is contained in:
Kai Cataldo 2020-01-11 14:42:21 -05:00 committed by Nicolò Ribaudo
parent 81c5f1f22d
commit d8e6219ad9
22 changed files with 101 additions and 3878 deletions

View File

@ -21,7 +21,7 @@
"main": "lib/index.js",
"peerDependencies": {
"@babel/core": ">=7.2.0",
"eslint": ">= 6.0.0"
"eslint": ">=6.0.0"
},
"dependencies": {
"eslint-scope": "5.0.0",
@ -29,22 +29,8 @@
"semver": "^6.3.0"
},
"devDependencies": {
"@babel/eslint-shared-fixtures": "*",
"@babel/core": "^7.2.0",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.2",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-private-methods": "^7.7.4",
"@babel/plugin-syntax-bigint": "^7.7.4",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
"@babel/plugin-syntax-export-namespace-from": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-syntax-numeric-separator": "^7.0.0",
"@babel/preset-env": "^7.1.5",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"dedent": "^0.7.0",
"eslint": "^6.0.1",
"espree": "^6.0.0"

View File

@ -1,5 +1,4 @@
import assert from "assert";
import path from "path";
import espree from "espree";
import escope from "eslint-scope";
import unpad from "dedent";
@ -7,7 +6,9 @@ import { parseForESLint } from "../src";
import assertImplementsAST from "./helpers/assert-implements-ast";
const babelOptions = {
configFile: path.resolve(__dirname, "./fixtures/config/babel.config.js"),
configFile: require.resolve(
"@babel/eslint-shared-fixtures/config/babel.config.js",
),
};
function parseAndAssertSame(code) {

View File

@ -23,9 +23,8 @@ function verifyAndAssertMessagesWithSpecificESLint(
sourceType,
requireConfigFile: false,
babelOptions: {
configFile: path.resolve(
__dirname,
"./fixtures/config/babel.config.js",
configFile: require.resolve(
"@babel/eslint-shared-fixtures/config/babel.config.js",
),
},
...overrideConfig?.parserOptions,
@ -1157,9 +1156,8 @@ describe("verify", () => {
parserOptions: {
sourceType,
babelOptions: {
configFile: path.resolve(
__dirname,
"./fixtures/config/babel.config.decorators-legacy.js",
configFile: require.resolve(
"@babel/eslint-shared-fixtures/config/babel.config.decorators-legacy.js",
),
},
},

View File

@ -1,7 +1,7 @@
# @babel/eslint-plugin
Companion rules for `@babel/eslint-parser`. `@babel/eslint-parser` does a great job at adapting `eslint`
for use with Babel, but it can't change the built in rules to support experimental features.
for use with Babel, but it can't change the built-in rules to support experimental features.
`@babel/eslint-plugin` re-implements problematic rules so they do not give false positives or negatives.
> Requires Node 10.9 or greater
@ -26,7 +26,6 @@ original ones as well!).
```json
{
"rules": {
"babel/camelcase": "error",
"babel/new-cap": "error",
"babel/no-invalid-this": "error",
"babel/no-unused-expressions": "error",
@ -37,13 +36,12 @@ original ones as well!).
```
### Rules
Each rule corresponds to a core `eslint` rule, and has the same options.
Each rule corresponds to a core `eslint` rule and has the same options.
🛠: means it's autofixable with `--fix`.
- `babel/camelcase: doesn't complain about optional chaining (`var foo = bar?.a_b;`)
- `babel/new-cap`: Ignores capitalized decorators (`@Decorator`)
- `babel/no-invalid-this`: doesn't fail when inside class properties (`class A { a = this.b; }`)
- `babel/no-unused-expressions`: doesn't fail when using `do` expressions or [optional chaining](https://github.com/tc39/proposal-optional-chaining) (`a?.b()`).
- `babel/object-curly-spacing`: doesn't complain about `export x from "mod";` or `export * as x from "mod";` (🛠)
- `babel/semi`: doesn't fail when using `for await (let something of {})`. Includes class properties (🛠)
- `babel/new-cap`: handles decorators (`@Decorator`)
- `babel/no-invalid-this`: handles class fields and private class methods (`class A { a = this.b; }`)
- `babel/no-unused-expressions`: handles `do` expressions
- `babel/object-curly-spacing`: handles `export * as x from "mod";` (🛠)
- `babel/semi`: Handles class properties (🛠)

View File

@ -27,14 +27,16 @@
},
"homepage": "https://github.com/babel/babel/tree/master/eslint/babel-eslint-plugin",
"peerDependencies": {
"eslint": ">=4.0.0"
"@babel/eslint-parser": "0.0.0",
"eslint": ">=6.0.0"
},
"dependencies": {
"eslint-rule-composer": "^0.3.0"
},
"devDependencies": {
"babel-eslint": "^8.2.2",
"eslint": "^4.19.1",
"@babel/eslint-shared-fixtures": "*",
"@babel/eslint-parser": "*",
"eslint": "^6.0.0",
"lodash.clonedeep": "^4.5.0"
}
}

View File

@ -1,5 +1,4 @@
import newCap from "./rules/new-cap";
import camelcase from "./rules/camelcase";
import noInvalidThis from "./rules/no-invalid-this";
import noUnusedExpressions from "./rules/no-unused-expressions";
import objectCurlySpacing from "./rules/object-curly-spacing";
@ -7,7 +6,6 @@ import semi from "./rules/semi";
module.exports = {
rules: {
camelcase,
"new-cap": newCap,
"no-invalid-this": noInvalidThis,
"no-unused-expressions": noUnusedExpressions,
@ -15,7 +13,6 @@ module.exports = {
semi,
},
rulesConfig: {
camelcase: "off",
"new-cap": "off",
"no-invalid-this": "off",
"no-unused-expressions": "off",

View File

@ -1,231 +0,0 @@
/**
* @fileoverview Rule to flag non-camelcased identifiers
* @author Nicholas C. Zakas
*/
"use strict";
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
export default {
meta: {
docs: {
description: "enforce camelcase naming convention",
category: "Stylistic Issues",
recommended: false,
url: "https://eslint.org/docs/rules/camelcase",
},
schema: [
{
type: "object",
properties: {
ignoreDestructuring: {
type: "boolean",
},
properties: {
enum: ["always", "never"],
},
},
additionalProperties: false,
},
],
messages: {
notCamelCase: "Identifier '{{name}}' is not in camel case.",
},
},
create(context) {
//--------------------------------------------------------------------------
// Helpers
//--------------------------------------------------------------------------
// contains reported nodes to avoid reporting twice on destructuring with shorthand notation
const reported = [];
const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]);
const MEMBER_EXPRESSIONS = ["MemberExpression", "OptionalMemberExpression"];
/**
* Checks if expression is supported member expression.
*
* @param {string} expression - An expression to check.
* @returns {boolean} `true` if the expression type is supported
*/
function isMemberExpression(expression) {
return MEMBER_EXPRESSIONS.indexOf(expression) >= 0;
}
/**
* Checks if a string contains an underscore and isn't all upper-case
* @param {string} name The string to check.
* @returns {boolean} if the string is underscored
* @private
*/
function isUnderscored(name) {
// if there's an underscore, it might be A_CONSTANT, which is okay
return name.indexOf("_") > -1 && name !== name.toUpperCase();
}
/**
* Checks if a parent of a node is an ObjectPattern.
* @param {ASTNode} node The node to check.
* @returns {boolean} if the node is inside an ObjectPattern
* @private
*/
function isInsideObjectPattern(node) {
let { parent } = node;
while (parent) {
if (parent.type === "ObjectPattern") {
return true;
}
parent = parent.parent;
}
return false;
}
/**
* Reports an AST node as a rule violation.
* @param {ASTNode} node The node to report.
* @returns {void}
* @private
*/
function report(node) {
if (reported.indexOf(node.parent) < 0) {
reported.push(node.parent);
context.report({
node,
messageId: "notCamelCase",
data: { name: node.name },
});
}
}
const options = context.options[0] || {};
let properties = options.properties || "";
const ignoreDestructuring = options.ignoreDestructuring || false;
if (properties !== "always" && properties !== "never") {
properties = "always";
}
return {
Identifier(node) {
/*
* Leading and trailing underscores are commonly used to flag
* private/protected identifiers, strip them
*/
const name = node.name.replace(/^_+|_+$/g, ""),
effectiveParent = isMemberExpression(node.parent.type)
? node.parent.parent
: node.parent;
// MemberExpressions get special rules
if (isMemberExpression(node.parent.type)) {
// "never" check properties
if (properties === "never") {
return;
}
// Always report underscored object names
if (
node.parent.object.type === "Identifier" &&
node.parent.object.name === node.name &&
isUnderscored(name)
) {
report(node);
// Report AssignmentExpressions only if they are the left side of the assignment
} else if (
effectiveParent.type === "AssignmentExpression" &&
isUnderscored(name) &&
(!isMemberExpression(effectiveParent.right.type) ||
(isMemberExpression(effectiveParent.left.type) &&
effectiveParent.left.property.name === node.name))
) {
report(node);
}
/*
* Properties have their own rules, and
* AssignmentPattern nodes can be treated like Properties:
* e.g.: const { no_camelcased = false } = bar;
*/
} else if (
node.parent.type === "Property" ||
node.parent.type === "AssignmentPattern"
) {
if (
node.parent.parent &&
node.parent.parent.type === "ObjectPattern"
) {
const assignmentKeyEqualsValue =
node.parent.key.name === node.parent.value.name;
// prevent checking righthand side of destructured object
if (node.parent.key === node && node.parent.value !== node) {
return;
}
const valueIsUnderscored =
node.parent.value.name && isUnderscored(name);
// ignore destructuring if the option is set, unless a new identifier is created
if (
valueIsUnderscored &&
!(assignmentKeyEqualsValue && ignoreDestructuring)
) {
report(node);
}
}
// "never" check properties or always ignore destructuring
if (
properties === "never" ||
(ignoreDestructuring && isInsideObjectPattern(node))
) {
return;
}
// don't check right hand side of AssignmentExpression to prevent duplicate warnings
if (
isUnderscored(name) &&
!ALLOWED_PARENT_TYPES.has(effectiveParent.type) &&
!(node.parent.right === node)
) {
report(node);
}
// Check if it's an import specifier
} else if (
[
"ImportSpecifier",
"ImportNamespaceSpecifier",
"ImportDefaultSpecifier",
].indexOf(node.parent.type) >= 0
) {
// Report only if the local imported identifier is underscored
if (
node.parent.local &&
node.parent.local.name === node.name &&
isUnderscored(name)
) {
report(node);
}
// Report anything that is underscored that isn't a CallExpression
} else if (
isUnderscored(name) &&
!ALLOWED_PARENT_TYPES.has(effectiveParent.type)
) {
report(node);
}
},
};
},
};

View File

@ -1,7 +1,7 @@
import ruleComposer from "eslint-rule-composer";
import eslint from "eslint";
const newCapRule = new eslint.Linter().getRules().get("new-cap");
const rule = new eslint.Linter().getRules().get("new-cap");
/**
* Returns whether a node is under a decorator or not.
@ -13,6 +13,6 @@ function isDecorator(node) {
}
export default ruleComposer.filterReports(
newCapRule,
rule,
problem => !isDecorator(problem.node),
);

View File

@ -21,6 +21,7 @@ function isFinalStatementInBlockStatement(node) {
* @param {ASTNode} node - any node
* @returns {boolean} whether the given node represents an unbroken chain of
* tail ExpressionStatements and IfStatements within a DoExpression
* https://github.com/tc39/proposal-do-expressions
*/
function isInDoStatement(node) {
if (!node) return false;
@ -46,7 +47,7 @@ function isInDoStatement(node) {
/**
* @param {ASTNode} node - any node
* @returns {boolean} whether the given node is an optional call expression,
* see https://github.com/tc39/proposal-optional-chaining
* https://github.com/tc39/proposal-optional-chaining
*/
function isOptionalCallExpression(node) {
return (

View File

@ -1,26 +1,20 @@
import ruleComposer from "eslint-rule-composer";
import eslint from "eslint";
const objectCurlySpacingRule = new eslint.Linter()
.getRules()
.get("object-curly-spacing");
const rule = new eslint.Linter().getRules().get("object-curly-spacing");
export default ruleComposer.filterReports(
objectCurlySpacingRule,
(problem, metadata) => {
const node = problem.node;
export default ruleComposer.filterReports(rule, problem => {
const node = problem.node;
// Allow `exportNamespaceFrom` and `exportDefaultFrom` syntax:
// export * as x from '...';
// export x from '...';
if (
node.type === "ExportNamedDeclaration" &&
node.specifiers.length > 0 &&
metadata.sourceCode.getTokenBefore(node.specifiers[0]).value === "export"
) {
return false;
}
// Allow exportDefaultFrom syntax:
// export x from '...';
if (
node.type === "ExportNamedDeclaration" &&
node.specifiers.length === 1 &&
node.specifiers[0].type === "ExportDefaultSpecifier"
) {
return false;
}
return true;
},
);
return true;
});

View File

@ -1,13 +1,15 @@
import ruleComposer from "eslint-rule-composer";
import eslint from "eslint";
const semiRule = new eslint.Linter().getRules().get("semi");
const OPT_OUT_PATTERN = /^[-[(/+`]/; // One of [(/+-`
const isSemicolon = token => token.type === "Punctuator" && token.value === ";";
const rule = new eslint.Linter().getRules().get("semi");
const isUnnecessarySemicolon = (context, lastToken) => {
function isSemicolon(token) {
return token.type === "Punctuator" && token.value === ";";
}
function isUnnecessarySemicolon(context, lastToken) {
if (!isSemicolon(lastToken)) {
return false;
}
@ -27,9 +29,9 @@ const isUnnecessarySemicolon = (context, lastToken) => {
const isDivider = nextToken.value === "}" || nextToken.value === ";";
return (lastTokenLine !== nextTokenLine && !isOptOutToken) || isDivider;
};
}
const isOneLinerBlock = (context, node) => {
function isOneLinerBlock(context, node) {
const nextToken = context.getSourceCode().getTokenAfter(node);
if (!nextToken || nextToken.value !== "}") {
@ -43,9 +45,9 @@ const isOneLinerBlock = (context, node) => {
parent.type === "BlockStatement" &&
parent.loc.start.line === parent.loc.end.line
);
};
}
const report = (context, node, missing) => {
function report(context, node, missing) {
const lastToken = context.getSourceCode().getLastToken(node);
let message,
@ -72,15 +74,14 @@ const report = (context, node, missing) => {
message,
fix,
});
};
}
const semiRuleWithClassProperty = ruleComposer.joinReports([
semiRule,
export default ruleComposer.joinReports([
rule,
context => ({
ClassProperty(node) {
const options = context.options[1];
const exceptOneLine = options && options.omitLastInOneLineBlock === true;
const sourceCode = context.getSourceCode();
const lastToken = sourceCode.getLastToken(node);
@ -102,21 +103,3 @@ const semiRuleWithClassProperty = ruleComposer.joinReports([
},
}),
]);
export default ruleComposer.filterReports(
semiRuleWithClassProperty,
problem => {
const node = problem.node;
// Handle async iterator:
// for await (let something of {})
if (
node.type === "VariableDeclaration" &&
node.parent.type === "ForAwaitStatement"
) {
return false;
}
return true;
},
);

View File

@ -1,7 +1,14 @@
var RuleTester = require("eslint").RuleTester;
import { RuleTester } from "eslint";
RuleTester.setDefaultConfig({
parser: 'babel-eslint'
parser: require.resolve("@babel/eslint-parser"),
parserOptions: {
babelOptions: {
configFile: require.resolve(
"@babel/eslint-shared-fixtures/config/babel.config.js",
),
},
},
});
module.exports = RuleTester;
export default RuleTester;

View File

@ -1,570 +0,0 @@
/**
* @fileoverview Tests for camelcase rule.
* @author Nicholas C. Zakas
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
import rule from "../../src/rules/camelcase";
import RuleTester from "../helpers/RuleTester";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const ruleTester = new RuleTester();
ruleTester.run("camelcase", rule, {
valid: [
// Original test cases.
'firstName = "Nicholas"',
'FIRST_NAME = "Nicholas"',
'__myPrivateVariable = "Patrick"',
'myPrivateVariable_ = "Patrick"',
"function doSomething(){}",
"do_something()",
"new do_something",
"new do_something()",
"foo.do_something()",
"var foo = bar.baz_boom;",
"var foo = bar.baz_boom.something;",
"foo.boom_pow.qux = bar.baz_boom.something;",
"if (bar.baz_boom) {}",
"var obj = { key: foo.bar_baz };",
"var arr = [foo.bar_baz];",
"[foo.bar_baz]",
"var arr = [foo.bar_baz.qux];",
"[foo.bar_baz.nesting]",
"if (foo.bar_baz === boom.bam_pow) { [foo.baz_boom] }",
{
code: "var o = {key: 1}",
options: [{ properties: "always" }],
},
{
code: "var o = {_leading: 1}",
options: [{ properties: "always" }],
},
{
code: "var o = {trailing_: 1}",
options: [{ properties: "always" }],
},
{
code: "var o = {bar_baz: 1}",
options: [{ properties: "never" }],
},
{
code: "var o = {_leading: 1}",
options: [{ properties: "never" }],
},
{
code: "var o = {trailing_: 1}",
options: [{ properties: "never" }],
},
{
code: "obj.a_b = 2;",
options: [{ properties: "never" }],
},
{
code: "obj._a = 2;",
options: [{ properties: "always" }],
},
{
code: "obj.a_ = 2;",
options: [{ properties: "always" }],
},
{
code: "obj._a = 2;",
options: [{ properties: "never" }],
},
{
code: "obj.a_ = 2;",
options: [{ properties: "never" }],
},
{
code: "var obj = {\n a_a: 1 \n};\n obj.a_b = 2;",
options: [{ properties: "never" }],
},
{
code: "obj.foo_bar = function(){};",
options: [{ properties: "never" }],
},
{
code: "var { category_id } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 },
},
{
code: "var { category_id: category_id } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 },
},
{
code: "var { category_id = 1 } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 },
},
{
code: "var { category_id: category } = query;",
parserOptions: { ecmaVersion: 6 },
},
{
code: "var { _leading } = query;",
parserOptions: { ecmaVersion: 6 },
},
{
code: "var { trailing_ } = query;",
parserOptions: { ecmaVersion: 6 },
},
{
code: 'import { camelCased } from "external module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: 'import { _leading } from "external module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: 'import { trailing_ } from "external module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: 'import { no_camelcased as camelCased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: 'import { no_camelcased as _leading } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: 'import { no_camelcased as trailing_ } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code:
'import { no_camelcased as camelCased, anoterCamelCased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
},
{
code: "function foo({ no_camelcased: camelCased }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ no_camelcased: _leading }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ no_camelcased: trailing_ }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ camelCased = 'default value' }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ _leading = 'default value' }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ trailing_ = 'default value' }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ camelCased }) {};",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ _leading }) {}",
parserOptions: { ecmaVersion: 6 },
},
{
code: "function foo({ trailing_ }) {}",
parserOptions: { ecmaVersion: 6 },
},
// Babel-specific test cases
{
code: "var foo = bar?.a_b;",
options: [{ properties: "never" }],
},
],
invalid: [
{
code: 'first_name = "Nicholas"',
errors: [
{
messageId: "notCamelCase",
data: { name: "first_name" },
type: "Identifier",
},
],
},
{
code: '__private_first_name = "Patrick"',
errors: [
{
messageId: "notCamelCase",
data: { name: "__private_first_name" },
type: "Identifier",
},
],
},
{
code: "function foo_bar(){}",
errors: [
{
messageId: "notCamelCase",
data: { name: "foo_bar" },
type: "Identifier",
},
],
},
{
code: "obj.foo_bar = function(){};",
errors: [
{
messageId: "notCamelCase",
data: { name: "foo_bar" },
type: "Identifier",
},
],
},
{
code: "bar_baz.foo = function(){};",
errors: [
{
messageId: "notCamelCase",
data: { name: "bar_baz" },
type: "Identifier",
},
],
},
{
code: "[foo_bar.baz]",
errors: [
{
messageId: "notCamelCase",
data: { name: "foo_bar" },
type: "Identifier",
},
],
},
{
code: "if (foo.bar_baz === boom.bam_pow) { [foo_bar.baz] }",
errors: [
{
messageId: "notCamelCase",
data: { name: "foo_bar" },
type: "Identifier",
},
],
},
{
code: "foo.bar_baz = boom.bam_pow",
errors: [
{
messageId: "notCamelCase",
data: { name: "bar_baz" },
type: "Identifier",
},
],
},
{
code: "var foo = { bar_baz: boom.bam_pow }",
errors: [
{
messageId: "notCamelCase",
data: { name: "bar_baz" },
type: "Identifier",
},
],
},
{
code: "foo.qux.boom_pow = { bar: boom.bam_pow }",
errors: [
{
messageId: "notCamelCase",
data: { name: "boom_pow" },
type: "Identifier",
},
],
},
{
code: "var o = {bar_baz: 1}",
options: [{ properties: "always" }],
errors: [
{
messageId: "notCamelCase",
data: { name: "bar_baz" },
type: "Identifier",
},
],
},
{
code: "obj.a_b = 2;",
options: [{ properties: "always" }],
errors: [
{
messageId: "notCamelCase",
data: { name: "a_b" },
type: "Identifier",
},
],
},
{
code: "var { category_id: category_alias } = query;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_alias" },
type: "Identifier",
},
],
},
{
code: "var { category_id: category_alias } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_alias" },
type: "Identifier",
},
],
},
{
code: "var { category_id: categoryId, ...other_props } = query;",
options: [{ ignoreDestructuring: true }],
parserOptions: { ecmaVersion: 2018 },
errors: [
{
messageId: "notCamelCase",
data: { name: "other_props" },
type: "Identifier",
},
],
},
{
code: "var { category_id } = query;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_id" },
type: "Identifier",
},
],
},
{
code: "var { category_id: category_id } = query;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
messageId: "notCamelCase",
data: { name: "category_id" },
type: "Identifier",
},
],
},
{
code: "var { category_id = 1 } = query;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'category_id' is not in camel case.",
type: "Identifier",
},
],
},
{
code: 'import no_camelcased from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code: 'import * as no_camelcased from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code: 'import { no_camelcased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code:
'import { no_camelcased as no_camel_cased } from "external module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camel_cased" },
type: "Identifier",
},
],
},
{
code: 'import { camelCased as no_camel_cased } from "external module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camel_cased" },
type: "Identifier",
},
],
},
{
code: 'import { camelCased, no_camelcased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code:
'import { no_camelcased as camelCased, another_no_camelcased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "another_no_camelcased" },
type: "Identifier",
},
],
},
{
code: 'import camelCased, { no_camelcased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code:
'import no_camelcased, { another_no_camelcased as camelCased } from "external-module";',
parserOptions: { ecmaVersion: 6, sourceType: "module" },
errors: [
{
messageId: "notCamelCase",
data: { name: "no_camelcased" },
type: "Identifier",
},
],
},
{
code: "function foo({ no_camelcased }) {};",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "function foo({ no_camelcased = 'default value' }) {};",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
],
},
{
code:
"const no_camelcased = 0; function foo({ camelcased_value = no_camelcased}) {}",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
{
message: "Identifier 'camelcased_value' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "const { bar: no_camelcased } = foo;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "function foo({ value_1: my_default }) {}",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'my_default' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "function foo({ isCamelcased: no_camelcased }) {};",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "var { foo: bar_baz = 1 } = quz;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'bar_baz' is not in camel case.",
type: "Identifier",
},
],
},
{
code: "const { no_camelcased = false } = bar;",
parserOptions: { ecmaVersion: 6 },
errors: [
{
message: "Identifier 'no_camelcased' is not in camel case.",
type: "Identifier",
},
],
},
],
});

View File

@ -1,300 +1,12 @@
/**
* @fileoverview Tests for new-cap rule.
* @author Nicholas C. Zakas
*/
import rule from "../../src/rules/new-cap";
import RuleTester from "../helpers/RuleTester";
const ruleTester = new RuleTester();
ruleTester.run("babel/new-cap", rule, {
ruleTester.run("@babel/new-cap", rule, {
valid: [
// Original test cases.
"var x = new Constructor();",
"var x = new a.b.Constructor();",
"var x = new a.b['Constructor']();",
"var x = new a.b[Constructor]();",
"var x = new a.b[constructor]();",
"var x = new function(){};",
"var x = new _;",
"var x = new $;",
"var x = new Σ;",
"var x = new _x;",
"var x = new $x;",
"var x = new this;",
"var x = Array(42)",
"var x = Boolean(42)",
"var x = Date(42)",
"var x = Date.UTC(2000, 0)",
"var x = Error('error')",
"var x = Function('return 0')",
"var x = Number(42)",
"var x = Object(null)",
"var x = RegExp(42)",
"var x = String(42)",
"var x = Symbol('symbol')",
"var x = _();",
"var x = $();",
{ code: "var x = Foo(42)", options: [{ capIsNew: false }] },
{ code: "var x = bar.Foo(42)", options: [{ capIsNew: false }] },
{ code: "var x = Foo.bar(42)", options: [{ capIsNew: false }] },
"var x = bar[Foo](42)",
{ code: "var x = bar['Foo'](42)", options: [{ capIsNew: false }] },
"var x = Foo.bar(42)",
{ code: "var x = new foo(42)", options: [{ newIsCap: false }] },
"var o = { 1: function() {} }; o[1]();",
"var o = { 1: function() {} }; new o[1]();",
{
code: "var x = Foo(42);",
options: [{ capIsNew: true, capIsNewExceptions: ["Foo"] }],
},
{
code: "var x = Foo(42);",
options: [{ capIsNewExceptionPattern: "^Foo" }],
},
{
code: "var x = new foo(42);",
options: [{ newIsCap: true, newIsCapExceptions: ["foo"] }],
},
{
code: "var x = new foo(42);",
options: [{ newIsCapExceptionPattern: "^foo" }],
},
{ code: "var x = Object(42);", options: [{ capIsNewExceptions: ["Foo"] }] },
{
code: "var x = Foo.Bar(42);",
options: [{ capIsNewExceptions: ["Bar"] }],
},
{
code: "var x = Foo.Bar(42);",
options: [{ capIsNewExceptions: ["Foo.Bar"] }],
},
{
code: "var x = Foo.Bar(42);",
options: [{ capIsNewExceptionPattern: "^Foo\\.." }],
},
{
code: "var x = new foo.bar(42);",
options: [{ newIsCapExceptions: ["bar"] }],
},
{
code: "var x = new foo.bar(42);",
options: [{ newIsCapExceptions: ["foo.bar"] }],
},
{
code: "var x = new foo.bar(42);",
options: [{ newIsCapExceptionPattern: "^foo\\.." }],
},
{ code: "var x = new foo.bar(42);", options: [{ properties: false }] },
{ code: "var x = Foo.bar(42);", options: [{ properties: false }] },
{
code: "var x = foo.Bar(42);",
options: [{ capIsNew: false, properties: false }],
},
// Babel-specific test cases.
{ code: "@MyDecorator(123) class MyClass{}", parser: "babel-eslint" },
],
invalid: [
{
code: "var x = new c();",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
},
],
},
{
code: "var x = new φ;",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
},
],
},
{
code: "var x = new a.b.c;",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
},
],
},
{
code: "var x = new a.b['c'];",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
},
],
},
{
code: "var b = Foo();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
},
],
},
{
code: "var b = a.Foo();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
},
],
},
{
code: "var b = a['Foo']();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
},
],
},
{
code: "var b = a.Date.UTC();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
},
],
},
{
code: "var b = UTC();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
},
],
},
{
code: "var a = B.C();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
line: 1,
column: 11,
},
],
},
{
code: "var a = B\n.C();",
errors: [
{
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
type: "CallExpression",
line: 2,
column: 2,
},
],
},
{
code: "var a = new B.c();",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
line: 1,
column: 15,
},
],
},
{
code: "var a = new B.\nc();",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
line: 2,
column: 1,
},
],
},
{
code: "var a = new c();",
errors: [
{
message:
"A constructor name should not start with a lowercase letter.",
type: "NewExpression",
line: 1,
column: 13,
},
],
},
{
code: "var x = Foo.Bar(42);",
options: [{ capIsNewExceptions: ["Foo"] }],
errors: [
{
type: "CallExpression",
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
},
],
},
{
code: "var x = Bar.Foo(42);",
options: [{ capIsNewExceptionPattern: "^Foo\\.." }],
errors: [
{
type: "CallExpression",
message:
"A function with a name starting with an uppercase letter should only be used as a constructor.",
},
],
},
{
code: "var x = new foo.bar(42);",
options: [{ newIsCapExceptions: ["foo"] }],
errors: [
{
type: "NewExpression",
message:
"A constructor name should not start with a lowercase letter.",
},
],
},
{
code: "var x = new bar.foo(42);",
options: [{ newIsCapExceptionPattern: "^foo\\.." }],
errors: [
{
type: "NewExpression",
message:
"A constructor name should not start with a lowercase letter.",
},
],
code: "@MyDecorator(123) class MyClass{}",
},
],
invalid: [],
});

View File

@ -1,20 +1,7 @@
/**
* @fileoverview Tests for no-invalid-this rule.
* @author Toru Nagashima
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
import cloneDeep from "lodash.clonedeep";
import rule from "../../src/rules/no-invalid-this";
import RuleTester from "../helpers/RuleTester";
//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------
/**
* A constant value for non strict mode environment.
* @returns {void}
@ -96,558 +83,7 @@ const errors = [
];
const patterns = [
// Global.
{
code: "console.log(this); z(x => console.log(x, this));",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code: "console.log(this); z(x => console.log(x, this));",
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: { globalReturn: true },
},
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// IIFE.
{
code:
"(function() { console.log(this); z(x => console.log(x, this)); })();",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// Just functions.
{
code: "function foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
'function foo() { "use strict"; console.log(this); z(x => console.log(x, this)); }',
parserOptions: { ecmaVersion: 6 },
errors,
valid: [],
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"return function() { console.log(this); z(x => console.log(x, this)); };",
parserOptions: {
ecmaVersion: 6,
ecmaFeatures: { globalReturn: true },
},
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT], // modules cannot return on global.
},
{
code:
"var foo = (function() { console.log(this); z(x => console.log(x, this)); }).bar(obj);",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// Functions in methods.
{
code:
"var obj = {foo: function() { function foo() { console.log(this); z(x => console.log(x, this)); } foo(); }};",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"var obj = {foo() { function foo() { console.log(this); z(x => console.log(x, this)); } foo(); }};",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"var obj = {foo: function() { return function() { console.log(this); z(x => console.log(x, this)); }; }};",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
'var obj = {foo: function() { "use strict"; return function() { console.log(this); z(x => console.log(x, this)); }; }};',
parserOptions: { ecmaVersion: 6 },
errors,
valid: [],
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"obj.foo = function() { return function() { console.log(this); z(x => console.log(x, this)); }; };",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
'obj.foo = function() { "use strict"; return function() { console.log(this); z(x => console.log(x, this)); }; };',
parserOptions: { ecmaVersion: 6 },
errors,
valid: [],
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"class A { foo() { return function() { console.log(this); z(x => console.log(x, this)); }; } }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [],
invalid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
},
// Class Static methods.
{
code:
"class A {static foo() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Constructors.
{
code: "function Foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var Foo = function Foo() { console.log(this); z(x => console.log(x, this)); };",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"class A {constructor() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// On a property.
{
code:
"var obj = {foo: function() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var obj = {foo() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var obj = {foo: foo || function() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var obj = {foo: hasNative ? foo : function() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var obj = {foo: (function() { return function() { console.log(this); z(x => console.log(x, this)); }; })()};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
'Object.defineProperty(obj, "foo", {value: function() { console.log(this); z(x => console.log(x, this)); }})',
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"Object.defineProperties(obj, {foo: {value: function() { console.log(this); z(x => console.log(x, this)); }}})",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Assigns to a property.
{
code:
"obj.foo = function() { console.log(this); z(x => console.log(x, this)); };",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"obj.foo = foo || function() { console.log(this); z(x => console.log(x, this)); };",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"obj.foo = foo ? bar : function() { console.log(this); z(x => console.log(x, this)); };",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"obj.foo = (function() { return function() { console.log(this); z(x => console.log(x, this)); }; })();",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Class Instance Methods.
{
code:
"class A {foo() { console.log(this); z(x => console.log(x, this)); }};",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Bind/Call/Apply
{
code:
"var foo = function() { console.log(this); z(x => console.log(x, this)); }.bind(obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var foo = function() { console.log(this); z(x => console.log(x, this)); }.bind(null);",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"(function() { console.log(this); z(x => console.log(x, this)); }).call(obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"(function() { console.log(this); z(x => console.log(x, this)); }).call(undefined);",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"(function() { console.log(this); z(x => console.log(x, this)); }).apply(obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"(function() { console.log(this); z(x => console.log(x, this)); }).apply(void 0);",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"Reflect.apply(function() { console.log(this); z(x => console.log(x, this)); }, obj, []);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// Array methods.
{
code:
"Array.from([], function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.every(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.filter(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.find(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.findIndex(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.map(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo.some(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"Array.from([], function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.every(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.filter(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.find(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.findIndex(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.map(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.some(function() { console.log(this); z(x => console.log(x, this)); }, obj);",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"foo.forEach(function() { console.log(this); z(x => console.log(x, this)); }, null);",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// @this tag.
{
code:
"/** @this Obj */ function foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"/**\n * @returns {void}\n * @this Obj\n */\nfunction foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"/** @returns {void} */ function foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"/** @this Obj */ foo(function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"foo(/* @this Obj */ function() { console.log(this); z(x => console.log(x, this)); });",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// https://github.com/eslint/eslint/issues/3254
{
code: "function foo() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// https://github.com/eslint/eslint/issues/3287
{
code:
"function foo() { /** @this Obj*/ return function bar() { console.log(this); z(x => console.log(x, this)); }; }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
// https://github.com/eslint/eslint/issues/6824
{
code:
"var Ctor = function() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"var func = function() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"Ctor = function() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"func = function() { console.log(this); z(x => console.log(x, this)); }",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"function foo(Ctor = function() { console.log(this); z(x => console.log(x, this)); }) {}",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"function foo(func = function() { console.log(this); z(x => console.log(x, this)); }) {}",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
{
code:
"[obj.method = function() { console.log(this); z(x => console.log(x, this)); }] = a",
parserOptions: { ecmaVersion: 6 },
valid: [NORMAL, USE_STRICT, IMPLIED_STRICT, MODULES],
invalid: [],
},
{
code:
"[func = function() { console.log(this); z(x => console.log(x, this)); }] = a",
parserOptions: { ecmaVersion: 6 },
errors,
valid: [NORMAL],
invalid: [USE_STRICT, IMPLIED_STRICT, MODULES],
},
// babel/no-invalid-this
// Class Instance Properties.
// Class private fields
{
code: "class A {a = this.b;};",
parserOptions: { ecmaVersion: 6 },
@ -662,7 +98,7 @@ const patterns = [
invalid: [],
},
// Class Private Instance Properties.
// Class Private methods
{
code: "class A {#a = this.b;};",
parserOptions: { ecmaVersion: 6 },
@ -679,8 +115,7 @@ const patterns = [
];
const ruleTester = new RuleTester();
ruleTester.run("no-invalid-this", rule, {
ruleTester.run("@babel/no-invalid-this", rule, {
valid: extractPatterns(patterns, "valid"),
invalid: extractPatterns(patterns, "invalid"),
});

View File

@ -1,83 +1,9 @@
/**
* @fileoverview Tests for no-unused-expressions rule.
* @author Michael Ficarra
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
import rule from "../../src/rules/no-unused-expressions";
import RuleTester from "../helpers/RuleTester";
//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------
const ruleTester = new RuleTester();
ruleTester.run("no-unused-expressions", rule, {
ruleTester.run("@babel/no-unused-expressions", rule, {
valid: [
// Original test cases.
"function f(){}",
"a = b",
"new a",
"{}",
"f(); g()",
"i++",
"a()",
{ code: "a && a()", options: [{ allowShortCircuit: true }] },
{ code: "a() || (b = c)", options: [{ allowShortCircuit: true }] },
{ code: "a ? b() : c()", options: [{ allowTernary: true }] },
{
code: "a ? b() || (c = d) : e()",
options: [{ allowShortCircuit: true, allowTernary: true }],
},
"delete foo.bar",
"void new C",
'"use strict";',
'"directive one"; "directive two"; f();',
'function foo() {"use strict"; return true; }',
{
code: 'var foo = () => {"use strict"; return true; }',
parserOptions: { ecmaVersion: 6 },
},
'function foo() {"directive one"; "directive two"; f(); }',
'function foo() { var foo = "use strict"; return true; }',
{
code: "function* foo(){ yield 0; }",
parserOptions: { ecmaVersion: 6 },
},
{
code: "async function foo() { await 5; }",
parserOptions: { ecmaVersion: 8 },
},
{
code: "async function foo() { await foo.bar; }",
parserOptions: { ecmaVersion: 8 },
},
{
code: "async function foo() { bar && await baz; }",
options: [{ allowShortCircuit: true }],
parserOptions: { ecmaVersion: 8 },
},
{
code: "async function foo() { foo ? await bar : await baz; }",
options: [{ allowTernary: true }],
parserOptions: { ecmaVersion: 8 },
},
{
code: "tag`tagged template literal`",
options: [{ allowTaggedTemplates: true }],
parserOptions: { ecmaVersion: 6 },
},
{
code: "shouldNotBeAffectedByAllowTemplateTagsOption()",
options: [{ allowTaggedTemplates: true }],
parserOptions: { ecmaVersion: 6 },
},
// Babel-specific test cases.
"let a = do { if (foo) { foo.bar; } }",
"let a = do { foo; }",
"let a = do { let b = 2; foo; }",
@ -87,283 +13,6 @@ ruleTester.run("no-unused-expressions", rule, {
"foo.bar?.();",
],
invalid: [
{
code: "0",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "f(), 0",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "{0}",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "[]",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a && b();",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a() || false",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a || (b = c)",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a ? b() || (c = d) : e",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "`untagged template literal`",
parserOptions: { ecmaVersion: 6 },
errors: [
"Expected an assignment or function call and instead saw an expression.",
],
},
{
code: "tag`tagged template literal`",
parserOptions: { ecmaVersion: 6 },
errors: [
"Expected an assignment or function call and instead saw an expression.",
],
},
{
code: "a && b()",
options: [{ allowTernary: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a ? b() : c()",
options: [{ allowShortCircuit: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a || b",
options: [{ allowShortCircuit: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a() && b",
options: [{ allowShortCircuit: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a ? b : 0",
options: [{ allowTernary: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "a ? b : c()",
options: [{ allowTernary: true }],
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "foo.bar;",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "!a",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "+a",
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: '"directive one"; f(); "directive two";',
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: 'function foo() {"directive one"; f(); "directive two"; }',
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: 'if (0) { "not a directive"; f(); }',
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: 'function foo() { var foo = true; "use strict"; }',
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: 'var foo = () => { var foo = true; "use strict"; }',
parserOptions: { ecmaVersion: 6 },
errors: [
{
message:
"Expected an assignment or function call and instead saw an expression.",
type: "ExpressionStatement",
},
],
},
{
code: "`untagged template literal`",
options: [{ allowTaggedTemplates: true }],
parserOptions: { ecmaVersion: 6 },
errors: [
"Expected an assignment or function call and instead saw an expression.",
],
},
{
code: "`untagged template literal`",
options: [{ allowTaggedTemplates: false }],
parserOptions: { ecmaVersion: 6 },
errors: [
"Expected an assignment or function call and instead saw an expression.",
],
},
{
code: "tag`tagged template literal`",
options: [{ allowTaggedTemplates: false }],
parserOptions: { ecmaVersion: 6 },
errors: [
"Expected an assignment or function call and instead saw an expression.",
],
},
// Babel-specific test cases.
{
code: "let a = do { foo; let b = 2; }",
errors: [

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,3 @@
/* eslnit-disable */
/**
* @fileoverview Tests for semi rule.
* @author Nicholas C. Zakas
*/
//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------
import rule from "../../src/rules/semi";
import RuleTester from "../helpers/RuleTester";
@ -15,650 +5,19 @@ const ruleTester = new RuleTester();
ruleTester.run("semi", rule, {
valid: [
"var x = 5;",
"var x =5, y;",
"foo();",
"x = foo();",
'setTimeout(function() {foo = "bar"; });',
'setTimeout(function() {foo = "bar";});',
"for (var a in b){}",
"for (var i;;){}",
"if (true) {}\n;[global, extended].forEach(function(){});",
"throw new Error('foo');",
{ code: "throw new Error('foo')", options: ["never"] },
{ code: "var x = 5", options: ["never"] },
{ code: "var x =5, y", options: ["never"] },
{ code: "foo()", options: ["never"] },
{ code: "debugger", options: ["never"] },
{ code: "for (var a in b){}", options: ["never"] },
{ code: "for (var i;;){}", options: ["never"] },
{ code: "x = foo()", options: ["never"] },
{
code: "if (true) {}\n;[global, extended].forEach(function(){})",
options: ["never"],
},
{ code: "(function bar() {})\n;(function foo(){})", options: ["never"] },
{ code: ";/foo/.test('bar')", options: ["never"] },
{ code: ";+5", options: ["never"] },
{ code: ";-foo()", options: ["never"] },
{ code: "a++\nb++", options: ["never"] },
{ code: "a++; b++", options: ["never"] },
{
code: "for (let thing of {}) {\n console.log(thing);\n}",
parserOptions: { ecmaVersion: 6 },
},
{ code: "do{}while(true)", options: ["never"] },
{ code: "do{}while(true);", options: ["always"] },
{
code: "if (foo) { bar() }",
options: ["always", { omitLastInOneLineBlock: true }],
},
{
code: "if (foo) { bar(); baz() }",
options: ["always", { omitLastInOneLineBlock: true }],
},
// method definitions don't have a semicolon.
{ code: "class A { a() {} b() {} }", parserOptions: { ecmaVersion: 6 } },
{
code: "var A = class { a() {} b() {} };",
parserOptions: { ecmaVersion: 6 },
},
{
code: "import theDefault, { named1, named2 } from 'src/mylib';",
parserOptions: { sourceType: "module" },
},
{
code: "import theDefault, { named1, named2 } from 'src/mylib'",
options: ["never"],
parserOptions: { sourceType: "module" },
},
// exports, "always"
{ code: "export * from 'foo';", parserOptions: { sourceType: "module" } },
{
code: "export { foo } from 'foo';",
parserOptions: { sourceType: "module" },
},
{ code: "export { foo };", parserOptions: { sourceType: "module" } },
{ code: "export var foo;", parserOptions: { sourceType: "module" } },
{
code: "export function foo () { }",
parserOptions: { sourceType: "module" },
},
{
code: "export function* foo () { }",
parserOptions: { sourceType: "module" },
},
{ code: "export class Foo { }", parserOptions: { sourceType: "module" } },
{ code: "export let foo;", parserOptions: { sourceType: "module" } },
{ code: "export const FOO = 42;", parserOptions: { sourceType: "module" } },
{
code: "export default function() { }",
parserOptions: { sourceType: "module" },
},
{
code: "export default function* () { }",
parserOptions: { sourceType: "module" },
},
{
code: "export default class { }",
parserOptions: { sourceType: "module" },
},
{
code: "export default foo || bar;",
parserOptions: { sourceType: "module" },
},
{
code: "export default (foo) => foo.bar();",
parserOptions: { sourceType: "module" },
},
{
code: "export default foo = 42;",
parserOptions: { sourceType: "module" },
},
{
code: "export default foo += 42;",
parserOptions: { sourceType: "module" },
},
// exports, "never"
{
code: "export * from 'foo'",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export { foo } from 'foo'",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export { foo }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export var foo",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export function foo () { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export function* foo () { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export class Foo { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export let foo",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export const FOO = 42",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default function() { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default function* () { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default class { }",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default foo || bar",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default (foo) => foo.bar()",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default foo = 42",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{
code: "export default foo += 42",
options: ["never"],
parserOptions: { sourceType: "module" },
},
{ code: "++\nfoo;", options: ["always"] },
{ code: "var a = b;\n+ c", options: ["never"] },
// https://github.com/eslint/eslint/issues/7782
{ code: "var a = b;\n/foo/.test(c)", options: ["never"] },
{
code: "var a = b;\n`foo`",
options: ["never"],
parserOptions: { ecmaVersion: 6 },
},
// babel
"class Foo { bar = 'example'; }",
"class Foo { static bar = 'example'; }",
{
code:
"async function foo() { for await (let thing of {}) { console.log(thing); } }",
parserOptions: { ecmaVersion: 6 },
},
{
code: "class Foo { bar = () => {}; }",
options: ["always", { omitLastInOneLineBlock: true }],
},
// babel, "never"
// never
{ code: "class Foo { bar = 'example' }", options: ["never"] },
{ code: "class Foo { static bar = 'example' }", options: ["never"] },
{ code: "class Foo { bar = () => {} }", options: ["never"] },
],
invalid: [
{
code: "import * as utils from './utils'",
output: "import * as utils from './utils';",
parserOptions: { sourceType: "module" },
errors: [
{
message: "Missing semicolon.",
type: "ImportDeclaration",
column: 33,
},
],
},
{
code: "import { square, diag } from 'lib'",
output: "import { square, diag } from 'lib';",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
},
{
code: "import { default as foo } from 'lib'",
output: "import { default as foo } from 'lib';",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
},
{
code: "import 'src/mylib'",
output: "import 'src/mylib';",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
},
{
code: "import theDefault, { named1, named2 } from 'src/mylib'",
output: "import theDefault, { named1, named2 } from 'src/mylib';",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "ImportDeclaration" }],
},
{
code: "function foo() { return [] }",
output: "function foo() { return []; }",
errors: [{ message: "Missing semicolon.", type: "ReturnStatement" }],
},
{
code: "while(true) { break }",
output: "while(true) { break; }",
errors: [{ message: "Missing semicolon.", type: "BreakStatement" }],
},
{
code: "while(true) { continue }",
output: "while(true) { continue; }",
errors: [{ message: "Missing semicolon.", type: "ContinueStatement" }],
},
{
code: "let x = 5",
output: "let x = 5;",
parserOptions: { ecmaVersion: 6 },
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "var x = 5",
output: "var x = 5;",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "var x = 5, y",
output: "var x = 5, y;",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "debugger",
output: "debugger;",
errors: [{ message: "Missing semicolon.", type: "DebuggerStatement" }],
},
{
code: "foo()",
output: "foo();",
errors: [{ message: "Missing semicolon.", type: "ExpressionStatement" }],
},
{
code: "var x = 5, y",
output: "var x = 5, y;",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (var a in b) var i ",
output: "for (var a in b) var i; ",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (;;){var i}",
output: "for (;;){var i;}",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (;;) var i ",
output: "for (;;) var i; ",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (var j;;) {var i}",
output: "for (var j;;) {var i;}",
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "var foo = {\n bar: baz\n}",
output: "var foo = {\n bar: baz\n};",
errors: [
{ message: "Missing semicolon.", type: "VariableDeclaration", line: 3 },
],
},
{
code: "var foo\nvar bar;",
output: "var foo;\nvar bar;",
errors: [
{ message: "Missing semicolon.", type: "VariableDeclaration", line: 1 },
],
},
{
code: "throw new Error('foo')",
output: "throw new Error('foo');",
errors: [
{ message: "Missing semicolon.", type: "ThrowStatement", line: 1 },
],
},
{
code: "do{}while(true)",
output: "do{}while(true);",
errors: [
{ message: "Missing semicolon.", type: "DoWhileStatement", line: 1 },
],
},
{
code: "throw new Error('foo');",
output: "throw new Error('foo')",
options: ["never"],
errors: [
{ message: "Extra semicolon.", type: "ThrowStatement", column: 23 },
],
},
{
code: "function foo() { return []; }",
output: "function foo() { return [] }",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "ReturnStatement" }],
},
{
code: "while(true) { break; }",
output: "while(true) { break }",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "BreakStatement" }],
},
{
code: "while(true) { continue; }",
output: "while(true) { continue }",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "ContinueStatement" }],
},
{
code: "let x = 5;",
output: "let x = 5",
parserOptions: { ecmaVersion: 6 },
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "var x = 5;",
output: "var x = 5",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "var x = 5, y;",
output: "var x = 5, y",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "debugger;",
output: "debugger",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "DebuggerStatement" }],
},
{
code: "foo();",
output: "foo()",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "ExpressionStatement" }],
},
{
code: "var x = 5, y;",
output: "var x = 5, y",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (var a in b) var i; ",
output: "for (var a in b) var i ",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (;;){var i;}",
output: "for (;;){var i}",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (;;) var i; ",
output: "for (;;) var i ",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "for (var j;;) {var i;}",
output: "for (var j;;) {var i}",
options: ["never"],
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "var foo = {\n bar: baz\n};",
output: "var foo = {\n bar: baz\n}",
options: ["never"],
errors: [
{ message: "Extra semicolon.", type: "VariableDeclaration", line: 3 },
],
},
{
code: "import theDefault, { named1, named2 } from 'src/mylib';",
output: "import theDefault, { named1, named2 } from 'src/mylib'",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "ImportDeclaration" }],
},
{
code: "do{}while(true);",
output: "do{}while(true)",
options: ["never"],
errors: [
{ message: "Extra semicolon.", type: "DoWhileStatement", line: 1 },
],
},
{
code: "if (foo) { bar()\n }",
options: ["always", { omitLastInOneLineBlock: true }],
errors: [{ message: "Missing semicolon." }],
},
{
code: "if (foo) {\n bar() }",
options: ["always", { omitLastInOneLineBlock: true }],
errors: [{ message: "Missing semicolon." }],
},
{
code: "if (foo) {\n bar(); baz() }",
options: ["always", { omitLastInOneLineBlock: true }],
errors: [{ message: "Missing semicolon." }],
},
{
code: "if (foo) { bar(); }",
options: ["always", { omitLastInOneLineBlock: true }],
errors: [{ message: "Extra semicolon." }],
},
// exports, "always"
{
code: "export * from 'foo'",
output: "export * from 'foo';",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "ExportAllDeclaration" }],
},
{
code: "export { foo } from 'foo'",
output: "export { foo } from 'foo';",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportNamedDeclaration" },
],
},
{
code: "export { foo }",
output: "export { foo };",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportNamedDeclaration" },
],
},
{
code: "export var foo",
output: "export var foo;",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "export let foo",
output: "export let foo;",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "export const FOO = 42",
output: "export const FOO = 42;",
parserOptions: { sourceType: "module" },
errors: [{ message: "Missing semicolon.", type: "VariableDeclaration" }],
},
{
code: "export default foo || bar",
output: "export default foo || bar;",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default (foo) => foo.bar()",
output: "export default (foo) => foo.bar();",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default foo = 42",
output: "export default foo = 42;",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default foo += 42",
output: "export default foo += 42;",
parserOptions: { sourceType: "module" },
errors: [
{ message: "Missing semicolon.", type: "ExportDefaultDeclaration" },
],
},
// exports, "never"
{
code: "export * from 'foo';",
output: "export * from 'foo'",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "ExportAllDeclaration" }],
},
{
code: "export { foo } from 'foo';",
output: "export { foo } from 'foo'",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "ExportNamedDeclaration" }],
},
{
code: "export { foo };",
output: "export { foo }",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "ExportNamedDeclaration" }],
},
{
code: "export var foo;",
output: "export var foo",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "export let foo;",
output: "export let foo",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "export const FOO = 42;",
output: "export const FOO = 42",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [{ message: "Extra semicolon.", type: "VariableDeclaration" }],
},
{
code: "export default foo || bar;",
output: "export default foo || bar",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default (foo) => foo.bar();",
output: "export default (foo) => foo.bar()",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default foo = 42;",
output: "export default foo = 42",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "export default foo += 42;",
output: "export default foo += 42",
options: ["never"],
parserOptions: { sourceType: "module" },
errors: [
{ message: "Extra semicolon.", type: "ExportDefaultDeclaration" },
],
},
{
code: "a;\n++b",
output: "a\n++b",
options: ["never"],
errors: [{ message: "Extra semicolon." }],
},
// babel
{
code: "class Foo { bar = 'example' }",
errors: [{ message: "Missing semicolon." }],
@ -673,7 +32,7 @@ ruleTester.run("semi", rule, {
errors: [{ message: "Missing semicolon." }],
},
// babel, "never"
// "never"
{
code: "class Foo { bar = 'example'; }",
options: ["never"],

View File

@ -19,5 +19,6 @@ module.exports = {
["@babel/plugin-proposal-pipeline-operator", { proposal: "minimal" }],
"@babel/plugin-syntax-bigint",
"@babel/plugin-proposal-private-methods",
"@babel/plugin-proposal-do-expressions",
],
};

View File

@ -0,0 +1,25 @@
{
"name": "@babel/eslint-shared-fixtures",
"version": "0.0.0",
"description": "Shared fixtures for testing @babel/eslint-* packages",
"license": "MIT",
"private": true,
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-decorators": "^7.1.2",
"@babel/plugin-proposal-do-expressions": "^7.7.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-proposal-pipeline-operator": "^7.0.0",
"@babel/plugin-proposal-private-methods": "^7.7.4",
"@babel/plugin-syntax-bigint": "^7.7.4",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
"@babel/plugin-syntax-export-namespace-from": "^7.0.0",
"@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/plugin-syntax-numeric-separator": "^7.0.0",
"@babel/preset-env": "^7.1.5",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0"
}
}

View File

@ -46,6 +46,7 @@ module.exports = {
"<rootDir>/build/",
],
moduleNameMapper: {
"^@babel/([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/",
"^@babel/(?!eslint-)([a-zA-Z0-9_-]+)$": "<rootDir>/packages/babel-$1/",
"^@babel/eslint-([a-zA-Z0-9_-]+)$": "<rootDir>/eslint/babel-eslint-$1/",
},
};