This commit is contained in:
jquense 2015-06-19 00:01:10 -04:00
parent 5b35722d63
commit c442efa7c5
13 changed files with 1190 additions and 0 deletions

1
eslint/babel-eslint-plugin/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

View File

@ -0,0 +1,7 @@
---
git:
depth: 1
language: node_js
node_js:
- '0.12'
- 'io.js'

View File

@ -0,0 +1,23 @@
Copyright (c) 2014-2015 Jason Quense <jason@quense.me>
Original work by respective rule authors; copywrites noted in files.
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,38 @@
# eslint-plugin-babel
An eslint plugin companion to babel-eslint. babel-eslint does a great job of adapting the eslint parser to valid babel code, it can't change built in rules to deal with the syntactic differences. eslint-plugin-babel reimplements problematic rules to not give false positives or negatives.
### Install
```sh
npm install eslint-plugin-babel -S
```
enable the plugin by adjusting your `.eslintrc` file to include the plugin:
```json
{
"plugins": [
"babel"
]
}
```
Finally enable all the rules you like to use (remember to disable the originals as well!).
```json
{
"rules": {
"babel/object-shorthand": 1,
"babel/generator-star": 1,
"babel/generator-star-spacing": 1,
}
}
```
### Rules
Each rule cooresponds to a core eslint rule, and has the same options.
- `babel/object-shorthand`: doesn't fail when using object spread (`...obj`)
- `babel/generator-star`: Handles async/await functions correctly
- `babel/generator-star-spacing`: Handles async/await functions correctly

View File

@ -0,0 +1,15 @@
var _parse = require('babel-core').parse;
module.exports = {
parse: function(code){
var ast = null
try {
ast = _parse(code, { locations: true, ranges: true }).body[0] //unwrap body
}
catch (err){
console.warn(err)
}
return ast
}
}

View File

@ -0,0 +1,8 @@
'use strict';
module.exports = {
rules: {
'object-shorthand': require('./rules/object-shorthand'),
'generator-star': require('./rules/object-shorthand')
}
};

View File

@ -0,0 +1,37 @@
{
"name": "eslint-plugin-babel",
"version": "1.0.0",
"description": "eslint rule plugin companion to babel-eslint",
"main": "index.js",
"scripts": {
"test": "mocha -R spec ./tests/*.js"
},
"repository": {
"type": "git",
"url": "git+https://github.com/babel/eslint-plugin-babel.git"
},
"keywords": [
"babel",
"eslint",
"eslintplugin",
"babel-eslint"
],
"author": "jquense @monasticpanic",
"license": "MIT",
"bugs": {
"url": "https://github.com/babel/eslint-plugin-babel/issues"
},
"homepage": "https://github.com/babel/eslint-plugin-babel#readme",
"devDependencies": {
"babel-eslint": "^3.1.17",
"eslint": "^0.23.0",
"eslint-tester": "^0.8.0",
"is-my-json-valid": "^2.12.0",
"mocha": "^2.2.5",
"mocha-phantomjs": "^3.5.3",
"phantomjs": "^1.9.17"
},
"dependencies": {
"babel-core": "^5.5.8"
}
}

View File

@ -0,0 +1,92 @@
/**
* @fileoverview Rule to check the spacing around the * in generator functions.
* @author Jamund Ferguson
* @copyright 2015 Brandon Mills. All rights reserved.
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/
"use strict";
module.exports = function(context) {
var mode = {
before: { before: true, after: false },
after: { before: false, after: true },
both: { before: true, after: true },
neither: { before: false, after: false }
}[context.options[0] || "before"];
function isAsyncGenerator(node){
return context.getFirstToken(node, 2).value === '*'
}
/**
* Checks the spacing between two tokens before or after the star token.
* @param {string} side Either "before" or "after".
* @param {Token} leftToken `function` keyword token if side is "before", or
* star token if side is "after".
* @param {Token} rightToken Star token if side is "before", or identifier
* token if side is "after".
* @returns {void}
*/
function checkSpacing(side, leftToken, rightToken) {
if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) {
context.report(
leftToken.value === "*" ? leftToken : rightToken,
"{{type}} space {{side}} *.",
{
type: mode[side] ? "Missing" : "Unexpected",
side: side
}
);
}
}
/**
* Enforces the spacing around the star if node is a generator function.
* @param {ASTNode} node A function expression or declaration node.
* @returns {void}
*/
function checkFunction(node) {
var first = context.getFirstToken(node)
, isMethod = node.parent.method || node.parent.type === "MethodDefinition"
, isAsync = first.value === 'async';
var prevToken, starToken, nextToken;
if ( !node.generator || (isAsync && !isAsyncGenerator(node))) {
return;
}
if (isMethod) {
starToken = context.getTokenBefore(node, 1);
} else {
starToken = context.getFirstToken(node, isAsync ? 2 : 1);
}
// Only check before when preceded by `function` keyword
prevToken = context.getTokenBefore(starToken);
if (prevToken.value === "function" || prevToken.value === "static") {
checkSpacing("before", prevToken, starToken);
}
// Only check after when followed by an identifier
nextToken = context.getTokenAfter(starToken);
if (nextToken.type === "Identifier") {
checkSpacing("after", starToken, nextToken);
}
}
return {
"FunctionDeclaration": checkFunction,
"FunctionExpression": checkFunction
};
};
module.exports.schema = [
{
"enum": ["before", "after", "both", "neither"]
}
];

View File

@ -0,0 +1,84 @@
/**
* @fileoverview Rule to check for the position of the * in your generator functions
* @author Jamund Ferguson
* @copyright 2014 Jamund Ferguson. All rights reserved.
*/
"use strict";
var parse = require('../helpers').parse
module.exports = function(context) {
var position = context.options[0] || "end";
function isAsyncGenerator(node){
return context.getFirstToken(node, 2).value === '*'
}
/**
* Check the position of the star compared to the expected position.
* @param {ASTNode} node - the entire function node
* @returns {void}
*/
function checkStarPosition(node) {
var first = context.getFirstToken(node)
, isAsync = first.value === 'async'
, starToken;
if (!node.generator || (isAsync && !isAsyncGenerator(node))) {
return;
}
// Blocked, pending decision to fix or work around in eslint/espree#36
if (context.getAncestors().pop().method) {
return;
}
starToken = context.getFirstToken(node, isAsync ? 2 : 1);
//console.log(declaration, starToken)
// check for function *name() {}
if (position === "end") {
if (starToken.range[1] !== context.getTokenAfter(starToken).range[0]) {
// * starts where the next identifier begins
context.report(node, "Expected a space before *.");
}
}
// check for function* name() {}
if (position === "start") {
// * begins where the previous identifier ends
if (starToken.range[0] !== context.getTokenBefore(starToken).range[1]) {
context.report(node, "Expected no space before *.");
}
}
// check for function * name() {}
if (position === "middle") {
// must be a space before and afer the *
if (starToken.range[0] <= context.getTokenBefore(starToken).range[1] ||
starToken.range[1] >= context.getTokenAfter(starToken).range[0]) {
context.report(node, "Expected spaces around *.");
}
}
}
return {
"FunctionDeclaration": checkStarPosition,
"FunctionExpression": checkStarPosition
};
};
module.exports.schema = [
{
"enum": ["start", "middle", "end"]
}
];

View File

@ -0,0 +1,73 @@
/**
* @fileoverview Rule to enforce concise object methods and properties.
* @author Jamund Ferguson
* @copyright 2015 Jamund Ferguson. All rights reserved.
*/
'use strict';
var OPTIONS = {
always: 'always',
never: 'never',
methods: 'methods',
properties: 'properties'
};
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
module.exports = function(context) {
var APPLY = context.options[0] || OPTIONS.always;
var APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always;
var APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always;
var APPLY_NEVER = APPLY === OPTIONS.never;
return {
Property: function(node) {
var isConciseProperty = node.method || node.shorthand
, isSpreadProperty = !!this.getSource(node).match(/^\.\.\./)
, type;
// if we're 'never' and concise we should warn now
if (APPLY_NEVER && isConciseProperty) {
type = node.method ? 'method' : 'property';
context.report(node, 'Expected longform ' + type + ' syntax.');
}
// at this point if we're concise or if we're 'never' we can leave
if (APPLY_NEVER || isConciseProperty) {
return;
}
if (node.kind === 'get' || node.kind === 'set') {
return;
}
if (isSpreadProperty) {
return;
}
if (node.value.type === 'FunctionExpression' && node.value.id == null && APPLY_TO_METHODS) {
// {x: function(){}} should be written as {x() {}}
context.report(node, 'Expected method shorthand.');
}
else if (node.value.type === 'Identifier' && node.key.name === node.value.name && APPLY_TO_PROPS) {
// {x: x} should be written as {x}
context.report(node, 'Expected property shorthand.');
}
else if (node.value.type === 'Identifier' && node.key.type === 'Literal' && node.key.value === node.value.name && APPLY_TO_PROPS) {
// {'x': x} should be written as {x}
context.report(node, 'Expected property shorthand.');
}
}
};
};
module.exports.schema = [
{
'enum': ['always', 'methods', 'properties', 'never']
}
];

View File

@ -0,0 +1,680 @@
/* eslint-disable */
var linter = require('eslint').linter
, ESLintTester = require('eslint-tester')
, eslintTester = new ESLintTester(linter);
var features = {
generators: true
};
function ok(code, args){
return { code: code, args: args, parser: 'babel-eslint', ecmaFeatures: features }
}
function err(code, errors, args){
var e = ok(code, args)
e.errors = errors
return e
}
var features = {
generators: true
};
function ok(code, args){
return { code: code, args: args, parser: 'babel-eslint', ecmaFeatures: features }
}
function err(code, errors, args){
var e = ok(code, args)
e.errors = errors
return e
}
eslintTester.addRuleTest('rules/generator-star-spacing', {
valid: [
ok('var test = async function(){}'),
ok('async function test(){}'),
ok('var test = async function *(){}'),
ok('async function *test(){}', [1, "before"]) ,
ok('async function* test(){}', [1, "after"]),
ok('async function * test(){}', [1, "both"]),
ok('async function*test(){}', [1, "neither"]),
{
code: "function foo(){}"
},
{
code: "function *foo(){}",
ecmaFeatures: { generators: true }
},
{
code: "function *foo(arg1, arg2){}",
ecmaFeatures: { generators: true }
},
{
code: "var foo = function *foo(){};",
ecmaFeatures: { generators: true }
},
{
code: "var foo = function *(){};",
ecmaFeatures: { generators: true }
},
{
code: "var foo = function * (){};",
ecmaFeatures: { generators: true }
},
{
code: "var foo = { *foo(){} };",
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "var foo = {*foo(){} };",
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "class Foo { *foo(){} }",
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo {*foo(){} }",
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { static *foo(){} }",
ecmaFeatures: { classes: true, generators: true }
},
// "before"
{
code: "function foo(){}",
args: [2, "before"]
},
{
code: "function *foo(){}",
args: [2, "before"],
ecmaFeatures: { generators: true }
},
{
code: "function *foo(arg1, arg2){}",
args: [2, "before"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function *foo(){};",
args: [2, "before"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function *(){};",
args: [2, "before"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function * (){};",
args: [2, "before"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = { *foo(){} };",
args: [2, "before"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "var foo = {*foo(){} };",
args: [2, "before"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "class Foo { *foo(){} }",
args: [2, "before"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo {*foo(){} }",
args: [2, "before"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { static *foo(){} }",
args: [2, "before"],
ecmaFeatures: { classes: true, generators: true }
},
// "after"
{
code: "function foo(){}",
args: [2, "after"]
},
{
code: "function* foo(){}",
args: [2, "after"],
ecmaFeatures: { generators: true }
},
{
code: "function* foo(arg1, arg2){}",
args: [2, "after"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function* foo(){};",
args: [2, "after"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function* (){};",
args: [2, "after"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function*(){};",
args: [2, "after"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = {* foo(){} };",
args: [2, "after"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "var foo = { * foo(){} };",
args: [2, "after"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "class Foo {* foo(){} }",
args: [2, "after"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { * foo(){} }",
args: [2, "after"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { static* foo(){} }",
args: [2, "after"],
ecmaFeatures: { classes: true, generators: true }
},
// "both"
{
code: "function foo(){}",
args: [2, "both"]
},
{
code: "function * foo(){}",
args: [2, "both"],
ecmaFeatures: { generators: true }
},
{
code: "function * foo(arg1, arg2){}",
args: [2, "both"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function * foo(){};",
args: [2, "both"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function * (){};",
args: [2, "both"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function *(){};",
args: [2, "both"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = { * foo(){} };",
args: [2, "both"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "var foo = {* foo(){} };",
args: [2, "both"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "class Foo { * foo(){} }",
args: [2, "both"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo {* foo(){} }",
args: [2, "both"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { static * foo(){} }",
args: [2, "both"],
ecmaFeatures: { classes: true, generators: true }
},
// "neither"
{
code: "function foo(){}",
args: [2, "neither"]
},
{
code: "function*foo(){}",
args: [2, "neither"],
ecmaFeatures: { generators: true }
},
{
code: "function*foo(arg1, arg2){}",
args: [2, "neither"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function*foo(){};",
args: [2, "neither"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function*(){};",
args: [2, "neither"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = function* (){};",
args: [2, "neither"],
ecmaFeatures: { generators: true }
},
{
code: "var foo = {*foo(){} };",
args: [2, "neither"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "var foo = { *foo(){} };",
args: [2, "neither"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true }
},
{
code: "class Foo {*foo(){} }",
args: [2, "neither"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { *foo(){} }",
args: [2, "neither"],
ecmaFeatures: { classes: true, generators: true }
},
{
code: "class Foo { static*foo(){} }",
args: [2, "neither"],
ecmaFeatures: { classes: true, generators: true }
}
],
invalid: [
// Default ("before")
err('async function*test(){}', [
{ message: 'Missing space before *.' },
]),
err('async function* test(){}', [
{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}
]),
{
code: "function*foo(){}",
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "function* foo(arg1, arg2){}",
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function*foo(){};",
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = function* (){};",
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = {* foo(){} };",
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo {* foo(){} }",
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { static* foo(){} }",
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
// "before"
{
code: "function*foo(){}",
args: [2, "before"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "function* foo(arg1, arg2){}",
args: [2, "before"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function*foo(){};",
args: [2, "before"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = function* (){};",
args: [2, "before"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = {* foo(){} };",
args: [2, "before"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo {* foo(){} }",
args: [2, "before"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
// "after"
{
code: "function*foo(){}",
args: [2, "after"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "function *foo(arg1, arg2){}",
args: [2, "after"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function *foo(){};",
args: [2, "after"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function *(){};",
args: [2, "after"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = { *foo(){} };",
args: [2, "after"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true },
errors: [{
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { *foo(){} }",
args: [2, "after"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { static *foo(){} }",
args: [2, "after"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
// "both"
{
code: "function*foo(){}",
args: [2, "both"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "function*foo(arg1, arg2){}",
args: [2, "both"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function*foo(){};",
args: [2, "both"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function*(){};",
args: [2, "both"],
ecmaFeatures: { generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = {*foo(){} };",
args: [2, "both"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true },
errors: [{
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo {*foo(){} }",
args: [2, "both"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Missing space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { static*foo(){} }",
args: [2, "both"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Missing space before *.",
type: "Punctuator"
}, {
message: "Missing space after *.",
type: "Punctuator"
}]
},
// "neither"
{
code: "function * foo(){}",
args: [2, "neither"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "function * foo(arg1, arg2){}",
args: [2, "neither"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function * foo(){};",
args: [2, "neither"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "var foo = function * (){};",
args: [2, "neither"],
ecmaFeatures: { generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}]
},
{
code: "var foo = { * foo(){} };",
args: [2, "neither"],
ecmaFeatures: { generators: true, objectLiteralShorthandMethods: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { * foo(){} }",
args: [2, "neither"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Unexpected space after *.",
type: "Punctuator"
}]
},
{
code: "class Foo { static * foo(){} }",
args: [2, "neither"],
ecmaFeatures: { classes: true, generators: true },
errors: [{
message: "Unexpected space before *.",
type: "Punctuator"
}, {
message: "Unexpected space after *.",
type: "Punctuator"
}]
}
]
});

View File

@ -0,0 +1,32 @@
/* eslint-disable */
var linter = require('eslint').linter
, ESLintTester = require('eslint-tester')
, eslintTester = new ESLintTester(linter);
var features = {
generators: true
};
function ok(code, args){
return { code: code, args: args, parser: 'babel-eslint', ecmaFeatures: features }
}
function err(code, errors, args){
var e = ok(code, args)
e.errors = errors
return e
}
eslintTester.addRuleTest('rules/generator-star', {
valid: [
ok('async function test(){}'),
ok('async function *test(){}', [1, "end"]) ,
ok('async function* test(){}', [1, "start"]),
ok('async function * test(){}', [1, "middle"])
],
invalid: [
err('async function* test(){}', [ { message: 'Expected a space before *.' }]),
err('async function *test(){}', [ { message: 'Expected no space before *.' }], [1, 'start'])
]
});

View File

@ -0,0 +1,100 @@
/* eslint-disable */
var linter = require('eslint').linter
, ESLintTester = require('eslint-tester')
, eslintTester = new ESLintTester(linter);
var features = {
objectLiteralShorthandMethods: true,
objectLiteralShorthandProperties: true,
arrowFunctions: true,
destructuring: true,
generators: true
};
function ok(code, args){
return { code: code, parser: 'babel-eslint', ecmaFeatures: features}
}
eslintTester.addRuleTest('rules/object-shorthand', {
valid: [
ok('let { ...spread } = obj'),
ok('let { ...spread } = obj', [2, 'never']),
//original test cases
{ code: "var x = {y() {}}", ecmaFeatures: features },
{ code: "var x = {y}", ecmaFeatures: features },
{ code: "var x = {a: b}", ecmaFeatures: features },
{ code: "var x = {a: 'a'}", ecmaFeatures: features },
{ code: "var x = {'a': 'a'}", ecmaFeatures: features },
{ code: "var x = {'a': b}", ecmaFeatures: features },
{ code: "var x = {y(x) {}}", ecmaFeatures: features },
{ code: "var {x,y,z} = x", ecmaFeatures: features },
{ code: "var {x: {y}} = z", ecmaFeatures: features },
{ code: "var x = {*x() {}}", ecmaFeatures: features },
{ code: "var x = {x: y}", ecmaFeatures: features },
{ code: "var x = {x: y, y: z}", ecmaFeatures: features},
{ code: "var x = {x: y, y: z, z: 'z'}", ecmaFeatures: features},
{ code: "var x = {x() {}, y: z, l(){}}", ecmaFeatures: features},
{ code: "var x = {x: y, y: z, a: b}", ecmaFeatures: features},
{ code: "var x = {x: y, y: z, 'a': b}", ecmaFeatures: features},
{ code: "var x = {x: y, y() {}, z: a}", ecmaFeatures: features},
{ code: "doSomething({x: y})", ecmaFeatures: features},
{ code: "doSomething({'x': y})", ecmaFeatures: features},
{ code: "doSomething({x: 'x'})", ecmaFeatures: features},
{ code: "doSomething({'x': 'x'})", ecmaFeatures: features},
{ code: "doSomething({y() {}})", ecmaFeatures: features},
{ code: "doSomething({x: y, y() {}})", ecmaFeatures: features},
{ code: "doSomething({y() {}, z: a})", ecmaFeatures: features},
{ code: "!{ a: function a(){} };", ecmaFeatures: features },
// arrows functions are still alright
{ code: "var x = {y: (x)=>x}", ecmaFeatures: features },
{ code: "doSomething({y: (x)=>x})", ecmaFeatures: features },
{ code: "var x = {y: (x)=>x, y: a}", ecmaFeatures: features },
{ code: "doSomething({x, y: (x)=>x})", ecmaFeatures: features },
// getters and setters are ok
{ code: "var x = {get y() {}}", ecmaFeatures: features },
{ code: "var x = {set y(z) {}}", ecmaFeatures: features },
{ code: "var x = {get y() {}, set y(z) {}}", ecmaFeatures: features },
{ code: "doSomething({get y() {}})", ecmaFeatures: features },
{ code: "doSomething({set y(z) {}})", ecmaFeatures: features },
{ code: "doSomething({get y() {}, set y(z) {}})", ecmaFeatures: features },
// options
{ code: "var x = {y() {}}", ecmaFeatures: features, args: [2, "methods"] },
{ code: "var x = {x, y() {}, a:b}", ecmaFeatures: features, args: [2, "methods"] },
{ code: "var x = {y}", ecmaFeatures: features, args: [2, "properties"] },
{ code: "var x = {y: {b}}", ecmaFeatures: features, args: [2, "properties"] },
{ code: "var x = {a: n, c: d, f: g}", ecmaFeatures: features, args: [2, "never"] },
{ code: "var x = {a: function(){}, b: {c: d}}", ecmaFeatures: features, args: [2, "never"] }
],
invalid: [
{ code: "var x = {x: x}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "var x = {'x': x}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "var x = {y: y, x: x}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected property shorthand.", type: "Property" }] },
{ code: "var x = {y: z, x: x, a: b}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "var x = {y: function() {}}", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }] },
{ code: "var x = {y: function*() {}}", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }] },
{ code: "var x = {x: y, y: z, a: a}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "var x = {x: y, y: z, a: function(){}, b() {}}", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }] },
{ code: "var x = {x: x, y: function() {}}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }, { message: "Expected method shorthand.", type: "Property" }]},
{ code: "doSomething({x: x})", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "doSomething({'x': x})", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "doSomething({a: 'a', 'x': x})", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }] },
{ code: "doSomething({y: function() {}})", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }] },
// options
{ code: "var x = {y: function() {}}", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }], args: [2, "methods"] },
{ code: "var x = {x, y() {}, z: function() {}}", ecmaFeatures: features, errors: [{ message: "Expected method shorthand.", type: "Property" }], args: [2, "methods"] },
{ code: "var x = {x: x}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }], args: [2, "properties"] },
{ code: "var x = {a, b, c(){}, x: x}", ecmaFeatures: features, errors: [{ message: "Expected property shorthand.", type: "Property" }], args: [2, "properties"] },
{ code: "var x = {y() {}}", ecmaFeatures: features, errors: [{ message: "Expected longform method syntax.", type: "Property" }], args: [2, "never"] },
{ code: "var x = {*y() {}}", ecmaFeatures: features, errors: [{ message: "Expected longform method syntax.", type: "Property" }], args: [2, "never"] },
{ code: "var x = {y}", ecmaFeatures: features, errors: [{ message: "Expected longform property syntax.", type: "Property" }], args: [2, "never"]},
{ code: "var x = {y, a: b, *x(){}}", ecmaFeatures: features, errors: [{ message: "Expected longform property syntax.", type: "Property" }, { message: "Expected longform method syntax.", type: "Property" }], args: [2, "never"]},
{ code: "var x = {y: {x}}", ecmaFeatures: features, errors: [{ message: "Expected longform property syntax.", type: "Property" }], args: [2, "never"]}
]
});