From bfdf77a7e22cb9df80fcf9f8e38ce87fc5935526 Mon Sep 17 00:00:00 2001 From: Imad Elyafi Date: Wed, 21 Dec 2016 14:13:27 -0800 Subject: [PATCH 01/56] [New] Autofixer for newline-after-import Fixes #686 --- docs/rules/newline-after-import.md | 1 + src/rules/newline-after-import.js | 10 ++++++++- tests/src/rules/newline-after-import.js | 27 ++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/docs/rules/newline-after-import.md b/docs/rules/newline-after-import.md index a50a1e333..8c5d5760f 100644 --- a/docs/rules/newline-after-import.md +++ b/docs/rules/newline-after-import.md @@ -1,6 +1,7 @@ # newline-after-import Enforces having one or more empty lines after the last top-level import statement or require call. ++(fixable) The `--fix` option on the [command line] automatically fixes problems reported by this rule. ## Rule Details diff --git a/src/rules/newline-after-import.js b/src/rules/newline-after-import.js index 868904ba3..579fe43ac 100644 --- a/src/rules/newline-after-import.js +++ b/src/rules/newline-after-import.js @@ -57,6 +57,7 @@ module.exports = { 'additionalProperties': false, }, ], + fixable: 'whitespace', }, create: function (context) { let level = 0 @@ -68,7 +69,10 @@ module.exports = { } const options = context.options[0] || { count: 1 } - if (getLineDifference(node, nextNode) < options.count + 1) { + const lineDifference = getLineDifference(node, nextNode) + const EXPECTED_LINE_DIFFERENCE = options.count + 1 + + if (lineDifference < EXPECTED_LINE_DIFFERENCE) { let column = node.loc.start.column if (node.loc.start.line !== node.loc.end.line) { @@ -81,6 +85,10 @@ module.exports = { column, }, message: `Expected empty line after ${type} statement not followed by another ${type}.`, + fix: fixer => fixer.insertTextAfter( + node, + '\n'.repeat(EXPECTED_LINE_DIFFERENCE - lineDifference) + ), }) } } diff --git a/tests/src/rules/newline-after-import.js b/tests/src/rules/newline-after-import.js index 0d3120d61..aab38b21b 100644 --- a/tests/src/rules/newline-after-import.js +++ b/tests/src/rules/newline-after-import.js @@ -166,6 +166,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { invalid: [ { code: `import foo from 'foo';\nexport default function() {};`, + output: `import foo from 'foo';\n\nexport default function() {};`, errors: [ { line: 1, column: 1, @@ -175,6 +176,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `import foo from 'foo';\n\nexport default function() {};`, + output: `import foo from 'foo';\n\n\nexport default function() {};`, options: [{ 'count': 2 }], errors: [ { line: 1, @@ -183,8 +185,19 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { } ], parserOptions: { sourceType: 'module' }, }, + { + code: `var foo = require('foo-module');\nvar something = 123;`, + output: `var foo = require('foo-module');\n\nvar something = 123;`, + errors: [ { + line: 1, + column: 1, + message: REQUIRE_ERROR_MESSAGE, + } ], + parserOptions: { sourceType: 'module' }, + }, { code: `import foo from 'foo';\nexport default function() {};`, + output: `import foo from 'foo';\n\nexport default function() {};`, options: [{ 'count': 1 }], errors: [ { line: 1, @@ -195,6 +208,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var foo = require('foo-module');\nvar something = 123;`, + output: `var foo = require('foo-module');\n\nvar something = 123;`, errors: [ { line: 1, column: 1, @@ -204,6 +218,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `import foo from 'foo';\nvar a = 123;\n\nimport { bar } from './bar-lib';\nvar b=456;`, + output: `import foo from 'foo';\n\nvar a = 123;\n\nimport { bar } from './bar-lib';\n\nvar b=456;`, errors: [ { line: 1, @@ -219,6 +234,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var foo = require('foo-module');\nvar a = 123;\n\nvar bar = require('bar-lib');\nvar b=456;`, + output: `var foo = require('foo-module');\n\nvar a = 123;\n\nvar bar = require('bar-lib');\n\nvar b=456;`, errors: [ { line: 1, @@ -234,6 +250,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var foo = require('foo-module');\nvar a = 123;\n\nrequire('bar-lib');\nvar b=456;`, + output: `var foo = require('foo-module');\n\nvar a = 123;\n\nrequire('bar-lib');\n\nvar b=456;`, errors: [ { line: 1, @@ -249,6 +266,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var path = require('path');\nvar foo = require('foo');\nvar bar = 42;`, + output: `var path = require('path');\nvar foo = require('foo');\n\nvar bar = 42;`, errors: [ { line: 2, column: 1, @@ -257,6 +275,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var assign = Object.assign || require('object-assign');\nvar foo = require('foo');\nvar bar = 42;`, + output: `var assign = Object.assign || require('object-assign');\nvar foo = require('foo');\n\nvar bar = 42;`, errors: [ { line: 2, column: 1, @@ -265,6 +284,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `require('a');\nfoo(require('b'), require('c'), require('d'));\nrequire('d');\nvar foo = 'bar';`, + output: `require('a');\nfoo(require('b'), require('c'), require('d'));\nrequire('d');\n\nvar foo = 'bar';`, errors: [ { line: 3, @@ -275,6 +295,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `require('a');\nfoo(\nrequire('b'),\nrequire('c'),\nrequire('d')\n);\nvar foo = 'bar';`, + output: `require('a');\nfoo(\nrequire('b'),\nrequire('c'),\nrequire('d')\n);\n\nvar foo = 'bar';`, errors: [ { line: 6, @@ -285,6 +306,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `import path from 'path';\nimport foo from 'foo';\nvar bar = 42;`, + output: `import path from 'path';\nimport foo from 'foo';\n\nvar bar = 42;`, errors: [ { line: 2, column: 1, @@ -294,6 +316,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `import path from 'path';import foo from 'foo';var bar = 42;`, + output: `import path from 'path';import foo from 'foo';\n\nvar bar = 42;`, errors: [ { line: 1, column: 25, @@ -303,6 +326,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `import foo from 'foo';\n@SomeDecorator(foo)\nclass Foo {}`, + output: `import foo from 'foo';\n\n@SomeDecorator(foo)\nclass Foo {}`, errors: [ { line: 1, column: 1, @@ -313,6 +337,7 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { }, { code: `var foo = require('foo');\n@SomeDecorator(foo)\nclass Foo {}`, + output: `var foo = require('foo');\n\n@SomeDecorator(foo)\nclass Foo {}`, errors: [ { line: 1, column: 1, @@ -322,4 +347,4 @@ ruleTester.run('newline-after-import', require('rules/newline-after-import'), { parser: 'babel-eslint', }, ], -}) +}); From dedfb114b8138ac13e30799cb69f82b8267fdf05 Mon Sep 17 00:00:00 2001 From: kevin940726 Date: Sun, 5 Feb 2017 02:53:23 +0800 Subject: [PATCH 02/56] add allow glob for rule no-unassigned-import, fix #671 --- src/rules/no-unassigned-import.js | 32 +++++++++++++++-- tests/src/rules/no-unassigned-import.js | 47 +++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/rules/no-unassigned-import.js b/src/rules/no-unassigned-import.js index a5503f196..e7d5b1e3e 100644 --- a/src/rules/no-unassigned-import.js +++ b/src/rules/no-unassigned-import.js @@ -1,4 +1,6 @@ import isStaticRequire from '../core/staticRequire' +import path from 'path' +import minimatch from 'minimatch' function report(context, node) { context.report({ @@ -7,15 +9,40 @@ function report(context, node) { }) } +function testIsAllow(globs, filename, source) { + if (!Array.isArray(globs)) { + return false // default doens't allow any pattern + } + + let filePath + + if (source[0] !== '.' && source[0] !== '/') { // a node module + filePath = source + } else { + filePath = path.resolve(path.dirname(filename), source) // get source absolute path + } + + return globs.find(glob => ( + minimatch(filePath, glob) || + minimatch(filePath, path.join(process.cwd(), glob)) + )) !== undefined +} + function create(context) { + const options = context.options[0] || {} + const filename = context.getFilename() + const isAllow = source => testIsAllow(options.allow, filename, source) + return { ImportDeclaration(node) { - if (node.specifiers.length === 0) { + if (node.specifiers.length === 0 && !isAllow(node.source.value)) { report(context, node) } }, ExpressionStatement(node) { - if (node.expression.type === 'CallExpression' && isStaticRequire(node.expression)) { + if (node.expression.type === 'CallExpression' && + isStaticRequire(node.expression) && + !isAllow(node.expression.arguments[0].value)) { report(context, node.expression) } }, @@ -33,6 +60,7 @@ module.exports = { 'devDependencies': { 'type': ['boolean', 'array'] }, 'optionalDependencies': { 'type': ['boolean', 'array'] }, 'peerDependencies': { 'type': ['boolean', 'array'] }, + 'allow': { 'type': 'array' }, }, 'additionalProperties': false, }, diff --git a/tests/src/rules/no-unassigned-import.js b/tests/src/rules/no-unassigned-import.js index 86248d459..b21668fa1 100644 --- a/tests/src/rules/no-unassigned-import.js +++ b/tests/src/rules/no-unassigned-import.js @@ -29,6 +29,38 @@ ruleTester.run('no-unassigned-import', rule, { test({ code: 'require("lodash").foo'}), test({ code: 'require("lodash").foo()'}), test({ code: 'require("lodash")()'}), + test({ + code: 'import "app.css"', + options: [{ 'allow': ['**/*.css'] }], + }), + test({ + code: 'import "app.css";', + options: [{ 'allow': ['*.css'] }], + }), + test({ + code: 'import "./app.css"', + options: [{ 'allow': ['**/*.css'] }], + }), + test({ + code: 'import "foo/bar"', + options: [{ 'allow': ['foo/**'] }], + }), + test({ + code: 'import "foo/bar"', + options: [{ 'allow': ['foo/bar'] }], + }), + test({ + code: 'import "../dir/app.css"', + options: [{ 'allow': ['**/*.css'] }], + }), + test({ + code: 'import "../dir/app.js"', + options: [{ 'allow': ['**/dir/**'] }], + }), + test({ + code: 'require("./app.css")', + options: [{ 'allow': ['**/*.css'] }], + }), ], invalid: [ test({ @@ -39,5 +71,20 @@ ruleTester.run('no-unassigned-import', rule, { code: 'require("lodash")', errors: [error], }), + test({ + code: 'import "./app.css"', + options: [{ 'allow': ['**/*.js'] }], + errors: [error], + }), + test({ + code: 'import "./app.css"', + options: [{ 'allow': ['**/dir/**'] }], + errors: [error], + }), + test({ + code: 'require("./app.css")', + options: [{ 'allow': ['**/*.js'] }], + errors: [error], + }), ], }) From 7d41745437ffc87ed21d183f072946bff0023163 Mon Sep 17 00:00:00 2001 From: kevin940726 Date: Sun, 5 Feb 2017 15:10:50 +0800 Subject: [PATCH 03/56] write doc, add two more tests --- docs/rules/no-unassigned-import.md | 22 ++++++++++++++++++++++ tests/src/rules/no-unassigned-import.js | 20 ++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/docs/rules/no-unassigned-import.md b/docs/rules/no-unassigned-import.md index 1b25b0169..324962767 100644 --- a/docs/rules/no-unassigned-import.md +++ b/docs/rules/no-unassigned-import.md @@ -6,11 +6,24 @@ With both CommonJS' `require` and the ES6 modules' `import` syntax, it is possib This rule aims to remove modules with side-effects by reporting when a module is imported but not assigned. +### Options + +This rule supports the following option: + +`allow`: An Array of globs. The files that match any of these patterns would be ignored/allowed by the linter. This can be usefull for some build environment (e.g. css-loader in webpack). + +Note that the globs start from the where the linter is executed (usually project root), but not from each file that includes the source. Learn more in both the pass and fail examples below. + + ## Fail ```js import 'should' require('should') + +// In /src/app.js +import '../styles/app.css' +// {"allow": ["styles/*.css"]} ``` @@ -34,4 +47,13 @@ bar(require('foo')) require('foo').bar require('foo').bar() require('foo')() + +// With allow option set +import './style.css' // {"allow": ["**/*.css"]} +import 'babel-register' // {"allow": ["babel-register"]} + +// In /src/app.js +import './styles/app.css' +import '../scripts/register.js' +// {"allow": ["src/styles/**", "**/scripts/*.js"]} ``` diff --git a/tests/src/rules/no-unassigned-import.js b/tests/src/rules/no-unassigned-import.js index b21668fa1..92b276999 100644 --- a/tests/src/rules/no-unassigned-import.js +++ b/tests/src/rules/no-unassigned-import.js @@ -61,6 +61,20 @@ ruleTester.run('no-unassigned-import', rule, { code: 'require("./app.css")', options: [{ 'allow': ['**/*.css'] }], }), + test({ + code: 'import "babel-register"', + options: [{ 'allow': ['babel-register'] }], + }), + test({ + code: 'import "./styles/app.css"', + options: [{ 'allow': ['src/styles/**'] }], + filename: path.join(process.cwd(), 'src/app.js'), + }), + test({ + code: 'import "../scripts/register.js"', + options: [{ 'allow': ['src/styles/**', '**/scripts/*.js'] }], + filename: path.join(process.cwd(), 'src/app.js'), + }), ], invalid: [ test({ @@ -86,5 +100,11 @@ ruleTester.run('no-unassigned-import', rule, { options: [{ 'allow': ['**/*.js'] }], errors: [error], }), + test({ + code: 'import "./styles/app.css"', + options: [{ 'allow': ['styles/*.css'] }], + filename: path.join(process.cwd(), 'src/app.js'), + errors: [error], + }), ], }) From b4d75c80c5eba883b9e2314094e253a4e70a06f2 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 19 May 2017 16:26:36 -0700 Subject: [PATCH 04/56] eslint-module-utils: filePath in parserOptions Refs https://github.com/benmosher/eslint-plugin-import/issues/839 --- utils/parse.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/parse.js b/utils/parse.js index c93417a61..a38e9b81c 100644 --- a/utils/parse.js +++ b/utils/parse.js @@ -21,6 +21,10 @@ exports.default = function parse(path, content, context) { // always attach comments parserOptions.attachComment = true + + // provide the `filePath` like eslint itself does, in `parserOptions` + // https://github.com/eslint/eslint/blob/3ec436eeed0b0271e2ed0d0cb22e4246eb15f137/lib/linter.js#L637 + parserOptions.filePath = path // require the parser relative to the main module (i.e., ESLint) const parser = moduleRequire(parserPath) From 3544c0ff80f762167af4c9dafacda4fd9aa26173 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sat, 20 May 2017 01:11:14 -0700 Subject: [PATCH 05/56] eslint-module-utils: Add tests for parserOptions Refs https://github.com/benmosher/eslint-plugin-import/issues/839 --- CHANGELOG.md | 1 + package.json | 2 +- tests/src/core/parse.js | 19 ++++++++++++++++++- tests/src/core/parseStubParser.js | 4 ++++ tests/src/utils.js | 14 ++++++++++++++ utils/CHANGELOG.md | 8 ++++++-- utils/package.json | 2 +- utils/parse.js | 4 ++-- 8 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 tests/src/core/parseStubParser.js diff --git a/CHANGELOG.md b/CHANGELOG.md index e047404a0..827089ad9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-anonymous-default-export`] rule: report anonymous default exports ([#712], thanks [@duncanbeevers]). - Add new value to [`order`]'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) - Add `count` option to the [`newline-after-import`] rule to allow configuration of number of newlines expected ([#742], thanks [@ntdb]) +- Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) ### Changed - [`no-extraneous-dependencies`]: use `read-pkg-up` to simplify finding + loading `package.json` ([#680], thanks [@wtgtybhertgeghgtwtg]) diff --git a/package.json b/package.json index 0edaa58e0..c75c61b7f 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "debug": "^2.2.0", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.2.0", - "eslint-module-utils": "^2.0.0", + "eslint-module-utils": "^2.1.0", "has": "^1.0.1", "lodash.cond": "^4.3.0", "minimatch": "^3.0.3", diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index 0793a70c2..ab167b692 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -2,7 +2,7 @@ import * as fs from 'fs' import { expect } from 'chai' import parse from 'eslint-module-utils/parse' -import { getFilename } from '../utils' +import { getFilename, makeNaiveSpy } from '../utils' describe('parse(content, { settings, ecmaFeatures })', function () { const path = getFilename('jsx.js') @@ -21,4 +21,21 @@ describe('parse(content, { settings, ecmaFeatures })', function () { .not.to.throw(Error) }) + it('passes expected parserOptions to custom parser', function () { + const parseSpy = makeNaiveSpy() + const parserOptions = { ecmaFeatures: { jsx: true } } + require('./parseStubParser').parse = parseSpy + parse(path, content, { settings: {}, parserPath: require.resolve('./parseStubParser'), parserOptions: parserOptions }) + expect(parseSpy.callCount).to.equal(1) + expect(parseSpy.lastCallArguments[0]).to.equal(content) + expect(parseSpy.lastCallArguments[1]).to.be.an('object') + expect(parseSpy.lastCallArguments[1]).to.not.equal(parserOptions) + expect(parseSpy.lastCallArguments[1]) + .to.have.property('ecmaFeatures') + .that.is.eql(parserOptions.ecmaFeatures) + .and.is.not.equal(parserOptions.ecmaFeatures) + expect(parseSpy.lastCallArguments[1]).to.have.property('attachComment', true) + expect(parseSpy.lastCallArguments[1]).to.have.property('filePath', path) + }) + }) diff --git a/tests/src/core/parseStubParser.js b/tests/src/core/parseStubParser.js new file mode 100644 index 000000000..81daace43 --- /dev/null +++ b/tests/src/core/parseStubParser.js @@ -0,0 +1,4 @@ +// this stub must be in a separate file to require from parse via moduleRequire +module.exports = { + parse: function () {}, +} diff --git a/tests/src/utils.js b/tests/src/utils.js index 144ae5498..877855a94 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -28,6 +28,20 @@ export function getFilename(file) { return path.join(__dirname, '..', 'files', file || 'foo.js') } +/** + * naive implementation of a function spy + * for more robust spy, consider replacing with sinon or chai-spies + * @return {function} + */ +export function makeNaiveSpy() { + const spy = function () { + spy.callCount += 1 + spy.lastCallArguments = arguments + } + spy.callCount = 0 + return spy +} + /** * to be added as valid cases just to ensure no nullable fields are going * to crash at runtinme diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index e31196c69..e1522cbc5 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -3,9 +3,13 @@ All notable changes to this module will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). -## v2 - 2016-11-07 +## v2.1.0 - 2017-05-20 +### Added +- `parse` now additionally passes `filePath` to `parser` in `parserOptions` like `eslint` core does + +## v2.0.0 - 2016-11-07 ### Changed - `unambiguous` no longer exposes fast test regex ### Fixed -- `unambiguous.test()` regex is now properly in multiline mode \ No newline at end of file +- `unambiguous.test()` regex is now properly in multiline mode diff --git a/utils/package.json b/utils/package.json index 0f76e24d9..bc234b534 100644 --- a/utils/package.json +++ b/utils/package.json @@ -1,6 +1,6 @@ { "name": "eslint-module-utils", - "version": "2.0.0", + "version": "2.1.0", "description": "Core utilities to support eslint-plugin-import and other module-related plugins.", "engines": { "node": ">=4" diff --git a/utils/parse.js b/utils/parse.js index a38e9b81c..671dc86c0 100644 --- a/utils/parse.js +++ b/utils/parse.js @@ -21,9 +21,9 @@ exports.default = function parse(path, content, context) { // always attach comments parserOptions.attachComment = true - + // provide the `filePath` like eslint itself does, in `parserOptions` - // https://github.com/eslint/eslint/blob/3ec436eeed0b0271e2ed0d0cb22e4246eb15f137/lib/linter.js#L637 + // https://github.com/eslint/eslint/blob/3ec436ee/lib/linter.js#L637 parserOptions.filePath = path // require the parser relative to the main module (i.e., ESLint) From 7712ce132ec38e38e0c756695efd10df7c2c3eeb Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sat, 20 May 2017 02:10:25 -0700 Subject: [PATCH 06/56] eslint-module-utils: Reverted manual version bumps. Refs https://github.com/benmosher/eslint-plugin-import/issues/839 --- package.json | 2 +- utils/CHANGELOG.md | 2 +- utils/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c75c61b7f..0edaa58e0 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "debug": "^2.2.0", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.2.0", - "eslint-module-utils": "^2.1.0", + "eslint-module-utils": "^2.0.0", "has": "^1.0.1", "lodash.cond": "^4.3.0", "minimatch": "^3.0.3", diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index e1522cbc5..241398a41 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this module will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). -## v2.1.0 - 2017-05-20 +## [Unreleased] ### Added - `parse` now additionally passes `filePath` to `parser` in `parserOptions` like `eslint` core does diff --git a/utils/package.json b/utils/package.json index bc234b534..0f76e24d9 100644 --- a/utils/package.json +++ b/utils/package.json @@ -1,6 +1,6 @@ { "name": "eslint-module-utils", - "version": "2.1.0", + "version": "2.0.0", "description": "Core utilities to support eslint-plugin-import and other module-related plugins.", "engines": { "node": ">=4" From 3e8438e69c554eca91b293ebb8a2c0b88cd4fe87 Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Wed, 24 May 2017 18:37:27 +0300 Subject: [PATCH 07/56] Extract isAbsolutePath from importTypes helper importTypes helper performs resolve() - which does not look needed for the no-absolute-path rule. Additionally, the absolute condition only seems like it was used for no-absolute-path. Finally, all the tests continue to pass. --- src/core/importType.js | 5 ----- src/rules/no-absolute-path.js | 7 +++++-- tests/src/core/importType.js | 6 ------ 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index 869ca7496..6f37743f1 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -8,10 +8,6 @@ function constant(value) { return () => value } -function isAbsolute(name) { - return name.indexOf('/') === 0 -} - export function isBuiltIn(name, settings) { const extras = (settings && settings['import/core-modules']) || [] return builtinModules.indexOf(name) !== -1 || extras.indexOf(name) > -1 @@ -50,7 +46,6 @@ function isRelativeToSibling(name) { } const typeTest = cond([ - [isAbsolute, constant('absolute')], [isBuiltIn, constant('builtin')], [isExternalModule, constant('external')], [isScoped, constant('external')], diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index 33da932fd..217bd4f32 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -1,12 +1,15 @@ -import importType from '../core/importType' import isStaticRequire from '../core/staticRequire' function reportIfMissing(context, node, name) { - if (importType(name, context) === 'absolute') { + if (isAbsolute(name)) { context.report(node, 'Do not import modules using an absolute path') } } +function isAbsolute(name) { + return name.indexOf('/') === 0 +} + module.exports = { meta: { docs: {}, diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 5b63910af..9e552e60b 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -8,12 +8,6 @@ import { testContext } from '../utils' describe('importType(name)', function () { const context = testContext() - it("should return 'absolute' for paths starting with a /", function() { - expect(importType('/', context)).to.equal('absolute') - expect(importType('/path', context)).to.equal('absolute') - expect(importType('/some/path', context)).to.equal('absolute') - }) - it("should return 'builtin' for node.js modules", function() { expect(importType('fs', context)).to.equal('builtin') expect(importType('path', context)).to.equal('builtin') From 5aa2fe0712b9cc927bea2263a00e1a0dfab03bdb Mon Sep 17 00:00:00 2001 From: Joachim Seminck Date: Wed, 24 May 2017 18:39:13 +0300 Subject: [PATCH 08/56] Rename funtion reportIfMissing to reportIfAbsolute The old name seems wrong. Probably copied from no-extraneuous-dependencies --- src/rules/no-absolute-path.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index 217bd4f32..8503be0d5 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -1,6 +1,6 @@ import isStaticRequire from '../core/staticRequire' -function reportIfMissing(context, node, name) { +function reportIfAbsolute(context, node, name) { if (isAbsolute(name)) { context.report(node, 'Do not import modules using an absolute path') } @@ -18,11 +18,11 @@ module.exports = { create: function (context) { return { ImportDeclaration: function handleImports(node) { - reportIfMissing(context, node, node.source.value) + reportIfAbsolute(context, node, node.source.value) }, CallExpression: function handleRequires(node) { if (isStaticRequire(node)) { - reportIfMissing(context, node, node.arguments[0].value) + reportIfAbsolute(context, node, node.arguments[0].value) } }, } From d0007f269c82e648e724dde509245082eaed10f5 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 26 May 2017 14:33:41 -0700 Subject: [PATCH 09/56] Add sinon, replace eslint-module-utils test spy with sinon.spy --- package.json | 1 + tests/src/core/parse.js | 19 ++++++++++--------- tests/src/utils.js | 14 -------------- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index 0edaa58e0..60b53c3cd 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "nyc": "^8.3.0", "redux": "^3.0.4", "rimraf": "2.5.2", + "sinon": "^2.3.2", "typescript": "^2.0.3", "typescript-eslint-parser": "^2.1.0" }, diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index ab167b692..41c0d9a8c 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -1,8 +1,9 @@ import * as fs from 'fs' import { expect } from 'chai' +import sinon from 'sinon' import parse from 'eslint-module-utils/parse' -import { getFilename, makeNaiveSpy } from '../utils' +import { getFilename } from '../utils' describe('parse(content, { settings, ecmaFeatures })', function () { const path = getFilename('jsx.js') @@ -22,20 +23,20 @@ describe('parse(content, { settings, ecmaFeatures })', function () { }) it('passes expected parserOptions to custom parser', function () { - const parseSpy = makeNaiveSpy() + const parseSpy = sinon.spy() const parserOptions = { ecmaFeatures: { jsx: true } } require('./parseStubParser').parse = parseSpy parse(path, content, { settings: {}, parserPath: require.resolve('./parseStubParser'), parserOptions: parserOptions }) - expect(parseSpy.callCount).to.equal(1) - expect(parseSpy.lastCallArguments[0]).to.equal(content) - expect(parseSpy.lastCallArguments[1]).to.be.an('object') - expect(parseSpy.lastCallArguments[1]).to.not.equal(parserOptions) - expect(parseSpy.lastCallArguments[1]) + expect(parseSpy.callCount, 'parse to be called once').to.equal(1) + expect(parseSpy.args[0][0], 'parse to get content as its first argument').to.equal(content) + expect(parseSpy.args[0][1], 'parse to get an object as its second argument').to.be.an('object') + expect(parseSpy.args[0][1], 'parse to clone the parserOptions object').to.not.equal(parserOptions) + expect(parseSpy.args[0][1], 'parse to get ecmaFeatures in parserOptions which is a clone of ecmaFeatures passed in') .to.have.property('ecmaFeatures') .that.is.eql(parserOptions.ecmaFeatures) .and.is.not.equal(parserOptions.ecmaFeatures) - expect(parseSpy.lastCallArguments[1]).to.have.property('attachComment', true) - expect(parseSpy.lastCallArguments[1]).to.have.property('filePath', path) + expect(parseSpy.args[0][1], 'parse to get parserOptions.attachComment equal to true').to.have.property('attachComment', true) + expect(parseSpy.args[0][1], 'parse to get parserOptions.filePath equal to the full path of the source file').to.have.property('filePath', path) }) }) diff --git a/tests/src/utils.js b/tests/src/utils.js index 877855a94..144ae5498 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -28,20 +28,6 @@ export function getFilename(file) { return path.join(__dirname, '..', 'files', file || 'foo.js') } -/** - * naive implementation of a function spy - * for more robust spy, consider replacing with sinon or chai-spies - * @return {function} - */ -export function makeNaiveSpy() { - const spy = function () { - spy.callCount += 1 - spy.lastCallArguments = arguments - } - spy.callCount = 0 - return spy -} - /** * to be added as valid cases just to ensure no nullable fields are going * to crash at runtinme From 7ac5e8f24fe23c726e350168faa9d64380c0f26c Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 26 May 2017 14:35:47 -0700 Subject: [PATCH 10/56] Fix CHANGELOG merge error --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e1f135f8..246b82083 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,6 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - [`no-anonymous-default-export`] rule: report anonymous default exports ([#712], thanks [@duncanbeevers]). - Add new value to [`order`]'s `newlines-between` option to allow newlines inside import groups ([#627], [#628], thanks [@giodamelio]) - Add `count` option to the [`newline-after-import`] rule to allow configuration of number of newlines expected ([#742], thanks [@ntdb]) -- Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) ### Changed - [`no-extraneous-dependencies`]: use `read-pkg-up` to simplify finding + loading `package.json` ([#680], thanks [@wtgtybhertgeghgtwtg]) From d397b9b7ff6a2cc0c800cfeea3ad28427f9b05ec Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 26 May 2017 15:01:03 -0700 Subject: [PATCH 11/56] eslint-module-utils: Add more tests for parse (coverage 100%) --- tests/src/core/parse.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index 41c0d9a8c..55a37f34c 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -27,16 +27,32 @@ describe('parse(content, { settings, ecmaFeatures })', function () { const parserOptions = { ecmaFeatures: { jsx: true } } require('./parseStubParser').parse = parseSpy parse(path, content, { settings: {}, parserPath: require.resolve('./parseStubParser'), parserOptions: parserOptions }) - expect(parseSpy.callCount, 'parse to be called once').to.equal(1) - expect(parseSpy.args[0][0], 'parse to get content as its first argument').to.equal(content) - expect(parseSpy.args[0][1], 'parse to get an object as its second argument').to.be.an('object') - expect(parseSpy.args[0][1], 'parse to clone the parserOptions object').to.not.equal(parserOptions) - expect(parseSpy.args[0][1], 'parse to get ecmaFeatures in parserOptions which is a clone of ecmaFeatures passed in') + expect(parseSpy.callCount, 'custom parser to be called once').to.equal(1) + expect(parseSpy.args[0][0], 'custom parser to get content as its first argument').to.equal(content) + expect(parseSpy.args[0][1], 'custom parser to get an object as its second argument').to.be.an('object') + expect(parseSpy.args[0][1], 'custom parser to clone the parserOptions object').to.not.equal(parserOptions) + expect(parseSpy.args[0][1], 'custom parser to get ecmaFeatures in parserOptions which is a clone of ecmaFeatures passed in') .to.have.property('ecmaFeatures') .that.is.eql(parserOptions.ecmaFeatures) .and.is.not.equal(parserOptions.ecmaFeatures) - expect(parseSpy.args[0][1], 'parse to get parserOptions.attachComment equal to true').to.have.property('attachComment', true) - expect(parseSpy.args[0][1], 'parse to get parserOptions.filePath equal to the full path of the source file').to.have.property('filePath', path) + expect(parseSpy.args[0][1], 'custom parser to get parserOptions.attachComment equal to true').to.have.property('attachComment', true) + expect(parseSpy.args[0][1], 'custom parser to get parserOptions.filePath equal to the full path of the source file').to.have.property('filePath', path) + }) + + it('should throw on context == null', function () { + expect(parse.bind(null, path, content, null)).to.throw(Error) + }) + + it('should throw on unable to resolve parserPath', function () { + expect(parse.bind(null, path, content, { settings: {}, parserPath: null })).to.throw(Error) + }) + + it('should take the alternate parser specified in settings', function () { + const parseSpy = sinon.spy() + const parserOptions = { ecmaFeatures: { jsx: true } } + require('./parseStubParser').parse = parseSpy + expect(parse.bind(null, path, content, { settings: { 'import/parsers': { [require.resolve('./parseStubParser')]: [ '.js' ] } }, parserPath: null, parserOptions: parserOptions })).not.to.throw(Error) + expect(parseSpy.callCount, 'custom parser to be called once').to.equal(1) }) }) From 57327424f0a3fb3c37e7e8c8199f6f8558d8e837 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Mon, 29 May 2017 16:48:57 -0700 Subject: [PATCH 12/56] eslint-module-utils: In tests move require stub parser to the top. --- tests/src/core/parse.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index 55a37f34c..2feea07ae 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -7,6 +7,8 @@ import { getFilename } from '../utils' describe('parse(content, { settings, ecmaFeatures })', function () { const path = getFilename('jsx.js') + const parseStubParser = require('./parseStubParser') + const parseStubParserPath = require.resolve('./parseStubParser') let content before((done) => @@ -25,8 +27,8 @@ describe('parse(content, { settings, ecmaFeatures })', function () { it('passes expected parserOptions to custom parser', function () { const parseSpy = sinon.spy() const parserOptions = { ecmaFeatures: { jsx: true } } - require('./parseStubParser').parse = parseSpy - parse(path, content, { settings: {}, parserPath: require.resolve('./parseStubParser'), parserOptions: parserOptions }) + parseStubParser.parse = parseSpy + parse(path, content, { settings: {}, parserPath: parseStubParserPath, parserOptions: parserOptions }) expect(parseSpy.callCount, 'custom parser to be called once').to.equal(1) expect(parseSpy.args[0][0], 'custom parser to get content as its first argument').to.equal(content) expect(parseSpy.args[0][1], 'custom parser to get an object as its second argument').to.be.an('object') @@ -50,8 +52,8 @@ describe('parse(content, { settings, ecmaFeatures })', function () { it('should take the alternate parser specified in settings', function () { const parseSpy = sinon.spy() const parserOptions = { ecmaFeatures: { jsx: true } } - require('./parseStubParser').parse = parseSpy - expect(parse.bind(null, path, content, { settings: { 'import/parsers': { [require.resolve('./parseStubParser')]: [ '.js' ] } }, parserPath: null, parserOptions: parserOptions })).not.to.throw(Error) + parseStubParser.parse = parseSpy + expect(parse.bind(null, path, content, { settings: { 'import/parsers': { [parseStubParserPath]: [ '.js' ] } }, parserPath: null, parserOptions: parserOptions })).not.to.throw(Error) expect(parseSpy.callCount, 'custom parser to be called once').to.equal(1) }) From 95315e041f758ea925177736225ae2f931a25a8d Mon Sep 17 00:00:00 2001 From: kevin940726 Date: Sun, 5 Feb 2017 15:15:40 +0800 Subject: [PATCH 13/56] update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 246b82083..461303cdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] ### Added - Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) +- Add `allow` option to [`no-unassigned-import`] to allow for files that match the globs ([#671], [#737], thanks [@kevin940726]). ## [2.3.0] - 2017-05-18 ### Added @@ -390,6 +391,7 @@ for info on changes for earlier releases. [`no-anonymous-default-export`]: ./docs/rules/no-anonymous-default-export.md [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 +[#737]: https://github.com/benmosher/eslint-plugin-import/pull/737 [#712]: https://github.com/benmosher/eslint-plugin-import/pull/712 [#685]: https://github.com/benmosher/eslint-plugin-import/pull/685 [#680]: https://github.com/benmosher/eslint-plugin-import/pull/680 @@ -446,6 +448,7 @@ for info on changes for earlier releases. [#157]: https://github.com/benmosher/eslint-plugin-import/pull/157 [#314]: https://github.com/benmosher/eslint-plugin-import/pull/314 +[#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 [#653]: https://github.com/benmosher/eslint-plugin-import/issues/653 [#627]: https://github.com/benmosher/eslint-plugin-import/issues/627 @@ -583,3 +586,4 @@ for info on changes for earlier releases. [@giodamelio]: https://github.com/giodamelio [@ntdb]: https://github.com/ntdb [@ramasilveyra]: https://github.com/ramasilveyra +[@kevin940726]: https://github.com/kevin940726 From 8f9b403f36e511498bcea40b8d21f26a4bbb33ad Mon Sep 17 00:00:00 2001 From: kevin940726 Date: Sun, 5 Feb 2017 16:58:49 +0800 Subject: [PATCH 14/56] fix typos, enforce type of array of strings in allow option --- docs/rules/no-unassigned-import.md | 2 +- src/rules/no-unassigned-import.js | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/rules/no-unassigned-import.md b/docs/rules/no-unassigned-import.md index 324962767..85f9b7c3a 100644 --- a/docs/rules/no-unassigned-import.md +++ b/docs/rules/no-unassigned-import.md @@ -10,7 +10,7 @@ This rule aims to remove modules with side-effects by reporting when a module is This rule supports the following option: -`allow`: An Array of globs. The files that match any of these patterns would be ignored/allowed by the linter. This can be usefull for some build environment (e.g. css-loader in webpack). +`allow`: An Array of globs. The files that match any of these patterns would be ignored/allowed by the linter. This can be useful for some build environments (e.g. css-loader in webpack). Note that the globs start from the where the linter is executed (usually project root), but not from each file that includes the source. Learn more in both the pass and fail examples below. diff --git a/src/rules/no-unassigned-import.js b/src/rules/no-unassigned-import.js index e7d5b1e3e..2b1499b34 100644 --- a/src/rules/no-unassigned-import.js +++ b/src/rules/no-unassigned-import.js @@ -11,7 +11,7 @@ function report(context, node) { function testIsAllow(globs, filename, source) { if (!Array.isArray(globs)) { - return false // default doens't allow any pattern + return false // default doesn't allow any patterns } let filePath @@ -60,7 +60,12 @@ module.exports = { 'devDependencies': { 'type': ['boolean', 'array'] }, 'optionalDependencies': { 'type': ['boolean', 'array'] }, 'peerDependencies': { 'type': ['boolean', 'array'] }, - 'allow': { 'type': 'array' }, + 'allow': { + 'type': 'array', + 'items': { + 'type': 'string', + }, + }, }, 'additionalProperties': false, }, From 3e291690e41883cb67d13b5bbde1b32850494943 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 09:54:34 -0400 Subject: [PATCH 15/56] bump v2.4.0 --- CHANGELOG.md | 8 +++++++- package.json | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 461303cdd..90fc0fe98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] + + +## [2.4.0] - 2017-06-02 ### Added - Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) - Add `allow` option to [`no-unassigned-import`] to allow for files that match the globs ([#671], [#737], thanks [@kevin940726]). @@ -448,6 +451,7 @@ for info on changes for earlier releases. [#157]: https://github.com/benmosher/eslint-plugin-import/pull/157 [#314]: https://github.com/benmosher/eslint-plugin-import/pull/314 +[#839]: https://github.com/benmosher/eslint-plugin-import/issues/839 [#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 [#653]: https://github.com/benmosher/eslint-plugin-import/issues/653 @@ -506,7 +510,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.3.0...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...HEAD +[2.4.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.3.0...v2.4.0 [2.3.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.1.0...v2.2.0 [2.1.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.0.1...v2.1.0 @@ -586,4 +591,5 @@ for info on changes for earlier releases. [@giodamelio]: https://github.com/giodamelio [@ntdb]: https://github.com/ntdb [@ramasilveyra]: https://github.com/ramasilveyra +[@sompylasar]: https://github.com/sompylasar [@kevin940726]: https://github.com/kevin940726 diff --git a/package.json b/package.json index 60b53c3cd..c60e9b2ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.3.0", + "version": "2.4.0", "description": "Import with sanity.", "engines": { "node": ">=4" From a3728d705ed1547f91e487dd6f7326bf67c52e9e Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 09:57:28 -0400 Subject: [PATCH 16/56] bump eslint-module-utils to v2.1.0 --- package.json | 2 +- utils/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c60e9b2ad..2a74867fe 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "debug": "^2.2.0", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.2.0", - "eslint-module-utils": "^2.0.0", + "eslint-module-utils": "^2.1.0", "has": "^1.0.1", "lodash.cond": "^4.3.0", "minimatch": "^3.0.3", diff --git a/utils/package.json b/utils/package.json index 0f76e24d9..bc234b534 100644 --- a/utils/package.json +++ b/utils/package.json @@ -1,6 +1,6 @@ { "name": "eslint-module-utils", - "version": "2.0.0", + "version": "2.1.0", "description": "Core utilities to support eslint-plugin-import and other module-related plugins.", "engines": { "node": ">=4" From 44ca1588d3817f8142aba0bfd345871f8d563ded Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 10:03:05 -0400 Subject: [PATCH 17/56] update utils changelog --- utils/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index 241398a41..02ed3e462 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -3,7 +3,10 @@ All notable changes to this module will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). -## [Unreleased] +## Unreleased + + +## v2.1.0 - 2017-06-02 ### Added - `parse` now additionally passes `filePath` to `parser` in `parserOptions` like `eslint` core does From 36c0a0496097e551ff269820c8bba1087c4895e7 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 10:18:27 -0400 Subject: [PATCH 18/56] remove obsolete dad joke --- RELEASE.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/RELEASE.md b/RELEASE.md index fa14a18f5..e16a58993 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -26,8 +26,7 @@ ``` Generally, don't use `npm version` for this because it creates a tag, which I normally - wait until signoff from all contributors (`new Set(["@jfmengels"])`) and actually - `npm publish`-ing to snap the tag. + wait until signoff from contributors and actually `npm publish`-ing to snap the tag. 3. create pull request from `release-[x.y.z]` into `release` branch From dfbe0e7ea0312e1489d2f2279e29a0b69f0a6657 Mon Sep 17 00:00:00 2001 From: Haoliang Gao Date: Fri, 2 Jun 2017 22:44:10 +0800 Subject: [PATCH 19/56] Upgrade debug version of eslint-module-utils (#844) --- utils/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/package.json b/utils/package.json index bc234b534..665422ffe 100644 --- a/utils/package.json +++ b/utils/package.json @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/benmosher/eslint-plugin-import#readme", "dependencies": { - "debug": "2.2.0", + "debug": "^2.6.8", "pkg-dir": "^1.0.0" } } From 089f7f14b6165824e2b4c4c0f71b1482e9c84b9f Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 11:03:59 -0400 Subject: [PATCH 20/56] add yanking note to root change log --- CHANGELOG.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90fc0fe98..1fcb4faa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] -## [2.4.0] - 2017-06-02 +## [2.4.0] - 2017-06-02 [YANKED] + +Yanked due to critical issue in eslint-module-utils with cache key resulting from [#839]. + ### Added - Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) - Add `allow` option to [`no-unassigned-import`] to allow for files that match the globs ([#671], [#737], thanks [@kevin940726]). @@ -141,7 +144,8 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel - Something horrible happened during `npm prepublish` of 1.10.1. Several `rm -rf node_modules && npm i` and `gulp clean && npm prepublish`s later, it is rebuilt and republished as 1.10.2. Thanks [@rhettlivingston] for noticing and reporting! -## [1.10.1] - 2016-07-02 [YANKED] +## [1.10.1] - 2016-07-02 [ +ED] ### Added - Officially support ESLint 3.x. (peerDependencies updated to `2.x - 3.x`) From e3a32add069850647f73550bd9c088b46806f552 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 11:04:40 -0400 Subject: [PATCH 21/56] add yank note to utils change log --- utils/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index 02ed3e462..013c6998a 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -6,7 +6,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased -## v2.1.0 - 2017-06-02 +## v2.1.0 - 2017-06-02 [YANKED] + +Yanked due to critical issue with cache key resulting from #839. + ### Added - `parse` now additionally passes `filePath` to `parser` in `parserOptions` like `eslint` core does From 3c46d308ccb462a52554257c49c374045d1a6cf7 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 2 Jun 2017 11:05:41 -0400 Subject: [PATCH 22/56] rollback utils dependency to 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a74867fe..c60e9b2ad 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "debug": "^2.2.0", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.2.0", - "eslint-module-utils": "^2.1.0", + "eslint-module-utils": "^2.0.0", "has": "^1.0.1", "lodash.cond": "^4.3.0", "minimatch": "^3.0.3", From 17d2ee937d4aa98aeaae5a7dc4a83cf18f5432d9 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 14:52:14 -0700 Subject: [PATCH 23/56] eslint-module-utils: Add tests for hash utils --- tests/src/core/hash.js | 76 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 tests/src/core/hash.js diff --git a/tests/src/core/hash.js b/tests/src/core/hash.js new file mode 100644 index 000000000..f8dd4b49a --- /dev/null +++ b/tests/src/core/hash.js @@ -0,0 +1,76 @@ +import { expect } from 'chai' + +import hashify, { hashArray, hashObject } from 'eslint-module-utils/hash' + +const createHash = require('crypto').createHash + +function expectHash(actualHash, expectedString) { + const expectedHash = createHash('sha256') + expectedHash.update(expectedString) + expect(actualHash.digest('hex'), 'to be a hex digest of sha256 hash of string <' + expectedString + '>').to.equal(expectedHash.digest('hex')) +} + +describe('hash', function () { + describe('hashify', function () { + it('handles null', function () { + expectHash(hashify(null), 'null') + }) + + it('handles undefined', function () { + expectHash(hashify(undefined), 'undefined') + }) + + it('handles numbers', function () { + expectHash(hashify(123.456), '123.456') + }) + + it('handles strings', function () { + expectHash(hashify('a string'), '"a string"') + }) + + it('handles Array instances', function () { + expectHash(hashify([ 'a string' ]), '["a string",]') + }) + + it('handles empty Array instances', function () { + expectHash(hashify([]), '[]') + }) + + it('handles Object instances', function () { + expectHash(hashify({ foo: 123.456, 'a key': 'a value' }), '{"a key":"a value","foo":123.456,}') + }) + + it('handles nested Object instances', function () { + expectHash(hashify({ foo: 123.456, 'a key': 'a value', obj: { abc: { def: 'ghi' } } }), '{"a key":"a value","foo":123.456,"obj":{"abc":{"def":"ghi",},},}') + }) + + it('handles nested Object and Array instances', function () { + expectHash(hashify({ foo: 123.456, 'a key': 'a value', obj: { arr: [ { def: 'ghi' } ] } }), '{"a key":"a value","foo":123.456,"obj":{"arr":[{"def":"ghi",},],},}') + }) + }) + + describe('hashArray', function () { + it('handles Array instances', function () { + expectHash(hashArray([ 'a string' ]), '["a string",]') + }) + + it('handles empty Array instances', function () { + expectHash(hashArray([]), '[]') + }) + }) + + describe('hashObject', function () { + it('handles Object instances', function () { + expectHash(hashObject({ foo: 123.456, 'a key': 'a value' }), '{"a key":"a value","foo":123.456,}') + }) + + it('handles nested Object instances', function () { + expectHash(hashObject({ foo: 123.456, 'a key': 'a value', obj: { abc: { def: 'ghi' } } }), '{"a key":"a value","foo":123.456,"obj":{"abc":{"def":"ghi",},},}') + }) + + it('handles nested Object and Array instances', function () { + expectHash(hashObject({ foo: 123.456, 'a key': 'a value', obj: { arr: [ { def: 'ghi' } ] } }), '{"a key":"a value","foo":123.456,"obj":{"arr":[{"def":"ghi",},],},}') + }) + }) + +}) From a0012f8f9b17d6d6afd9ade7e608b3ad94b542e9 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 16:43:08 -0700 Subject: [PATCH 24/56] eslint-module-utils: Add tests for resolver versions --- tests/files/foo-bar-resolver-v1.js | 17 ++++++++++ tests/files/foo-bar-resolver-v2.js | 17 ++++++++++ tests/files/foo-bar-resolver.js | 7 ---- tests/src/core/resolve.js | 52 ++++++++++++++++++++++++------ 4 files changed, 77 insertions(+), 16 deletions(-) create mode 100644 tests/files/foo-bar-resolver-v1.js create mode 100644 tests/files/foo-bar-resolver-v2.js delete mode 100644 tests/files/foo-bar-resolver.js diff --git a/tests/files/foo-bar-resolver-v1.js b/tests/files/foo-bar-resolver-v1.js new file mode 100644 index 000000000..decde2e56 --- /dev/null +++ b/tests/files/foo-bar-resolver-v1.js @@ -0,0 +1,17 @@ +var path = require('path') + +exports.resolveImport = function (modulePath, sourceFile, config) { + var fooPathSuffix = '/files/foo.js' + var exceptionPathSuffix = '/files/exception.js' + if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + return path.join(__dirname, 'bar.jsx') + } + else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + throw new Error('foo-bar-resolver-v1 resolveImport test exception') + } + else { + return undefined + } +} + +exports.interfaceVersion = 1 diff --git a/tests/files/foo-bar-resolver-v2.js b/tests/files/foo-bar-resolver-v2.js new file mode 100644 index 000000000..adb764838 --- /dev/null +++ b/tests/files/foo-bar-resolver-v2.js @@ -0,0 +1,17 @@ +var path = require('path') + +exports.resolve = function (modulePath, sourceFile, config) { + var fooPathSuffix = '/files/foo.js' + var exceptionPathSuffix = '/files/exception.js' + if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + return { found: true, path: path.join(__dirname, 'bar.jsx') } + } + else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + throw new Error('foo-bar-resolver-v2 resolve test exception') + } + else { + return { found: false } + } +} + +exports.interfaceVersion = 2 diff --git a/tests/files/foo-bar-resolver.js b/tests/files/foo-bar-resolver.js deleted file mode 100644 index 92421ba26..000000000 --- a/tests/files/foo-bar-resolver.js +++ /dev/null @@ -1,7 +0,0 @@ -var path = require('path'); - -exports.resolve = function(source, file) { - return { found: true, path: path.join(__dirname, 'bar.jsx') }; -}; - -exports.interfaceVersion = 2; diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index e8f255f34..32eea3037 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -11,20 +11,54 @@ describe('resolve', function () { expect(resolve.bind(null, null, null)).to.throw(Error) }) - it('loads a custom resolver path', function () { - var file = resolve( '../files/foo' - , utils.testContext({ 'import/resolver': './foo-bar-resolver'}) - ) + it('resolves via a custom resolver with interface version 1', function () { + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v1'}) - expect(file).to.equal(utils.testFilePath('./bar.jsx')) + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + + expect(resolve( '../files/exception' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('exception.js') } }) + )).to.equal(undefined) + + expect(resolve( '../files/not-found' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('not-found.js') } }) + )).to.equal(undefined) + }) + + it('resolves via a custom resolver with interface version 2', function () { + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v2'}) + const testContextReports = [] + testContext.report = function (reportInfo) { + testContextReports.push(reportInfo) + } + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + + testContextReports.length = 0 + expect(resolve( '../files/exception' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('exception.js') } }) + )).to.equal(undefined) + expect(testContextReports[0]).to.be.an('object') + expect(testContextReports[0].message).to.equal('Resolve error: foo-bar-resolver-v2 resolve test exception') + expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }) + + testContextReports.length = 0 + expect(resolve( '../files/not-found' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('not-found.js') } }) + )).to.equal(undefined) + expect(testContextReports.length).to.equal(0) }) it('respects import/resolve extensions', function () { - var file = resolve( './jsx/MyCoolComponent' - , utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] }}) - ) + const testContext = utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] }}) - expect(file).to.equal(utils.testFilePath('./jsx/MyCoolComponent.jsx')) + expect(resolve( './jsx/MyCoolComponent' + , testContext + )).to.equal(utils.testFilePath('./jsx/MyCoolComponent.jsx')) }) const caseDescribe = (!CASE_SENSITIVE_FS ? describe : describe.skip) From f65c263f9e1f41baceefc0f55e179791e02d732d Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 16:45:20 -0700 Subject: [PATCH 25/56] eslint-module-utils: Unified test specs names to not use 'should' word --- tests/src/core/getExports.js | 12 ++++++------ tests/src/core/parse.js | 6 +++--- tests/src/core/resolve.js | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js index 62513d442..c3da17fe7 100644 --- a/tests/src/core/getExports.js +++ b/tests/src/core/getExports.js @@ -13,7 +13,7 @@ describe('ExportMap', function () { parserPath: 'babel-eslint', } - it('should handle ExportAllDeclaration', function () { + it('handles ExportAllDeclaration', function () { var imports expect(function () { imports = ExportMap.get('./export-all', fakeContext) @@ -24,12 +24,12 @@ describe('ExportMap', function () { }) - it('should return a cached copy on subsequent requests', function () { + it('returns a cached copy on subsequent requests', function () { expect(ExportMap.get('./named-exports', fakeContext)) .to.exist.and.equal(ExportMap.get('./named-exports', fakeContext)) }) - it('should not return a cached copy after modification', (done) => { + it('does not return a cached copy after modification', (done) => { const firstAccess = ExportMap.get('./mutator', fakeContext) expect(firstAccess).to.exist @@ -42,7 +42,7 @@ describe('ExportMap', function () { }) }) - it('should not return a cached copy with different settings', () => { + it('does not return a cached copy with different settings', () => { const firstAccess = ExportMap.get('./named-exports', fakeContext) expect(firstAccess).to.exist @@ -56,7 +56,7 @@ describe('ExportMap', function () { .not.to.equal(firstAccess) }) - it('should not throw for a missing file', function () { + it('does not throw for a missing file', function () { var imports expect(function () { imports = ExportMap.get('./does-not-exist', fakeContext) @@ -66,7 +66,7 @@ describe('ExportMap', function () { }) - it('should export explicit names for a missing file in exports', function () { + it('exports explicit names for a missing file in exports', function () { var imports expect(function () { imports = ExportMap.get('./exports-missing', fakeContext) diff --git a/tests/src/core/parse.js b/tests/src/core/parse.js index 2feea07ae..9cc153ae3 100644 --- a/tests/src/core/parse.js +++ b/tests/src/core/parse.js @@ -41,15 +41,15 @@ describe('parse(content, { settings, ecmaFeatures })', function () { expect(parseSpy.args[0][1], 'custom parser to get parserOptions.filePath equal to the full path of the source file').to.have.property('filePath', path) }) - it('should throw on context == null', function () { + it('throws on context == null', function () { expect(parse.bind(null, path, content, null)).to.throw(Error) }) - it('should throw on unable to resolve parserPath', function () { + it('throws on unable to resolve parserPath', function () { expect(parse.bind(null, path, content, { settings: {}, parserPath: null })).to.throw(Error) }) - it('should take the alternate parser specified in settings', function () { + it('takes the alternate parser specified in settings', function () { const parseSpy = sinon.spy() const parserOptions = { ecmaFeatures: { jsx: true } } parseStubParser.parse = parseSpy diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 32eea3037..b585e7218 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -7,7 +7,7 @@ import * as fs from 'fs' import * as utils from '../utils' describe('resolve', function () { - it('should throw on bad parameters.', function () { + it('throws on bad parameters', function () { expect(resolve.bind(null, null, null)).to.throw(Error) }) From 06695c49425fa0029deb69cbc94b0229f2bbe508 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 16:57:45 -0700 Subject: [PATCH 26/56] eslint-module-utils: Add test for when resolver version is not specified --- tests/files/foo-bar-resolver-no-version.js | 15 +++++++++++++++ tests/src/core/resolve.js | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/files/foo-bar-resolver-no-version.js diff --git a/tests/files/foo-bar-resolver-no-version.js b/tests/files/foo-bar-resolver-no-version.js new file mode 100644 index 000000000..6676133b0 --- /dev/null +++ b/tests/files/foo-bar-resolver-no-version.js @@ -0,0 +1,15 @@ +var path = require('path') + +exports.resolveImport = function (modulePath, sourceFile, config) { + var fooPathSuffix = '/files/foo.js' + var exceptionPathSuffix = '/files/exception.js' + if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + return path.join(__dirname, 'bar.jsx') + } + else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + throw new Error('foo-bar-resolver-v1 resolveImport test exception') + } + else { + return undefined + } +} diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index b585e7218..0ead05db0 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -27,6 +27,22 @@ describe('resolve', function () { )).to.equal(undefined) }) + it('resolves via a custom resolver with interface version 1 assumed if not specified', function () { + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-no-version'}) + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + + expect(resolve( '../files/exception' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('exception.js') } }) + )).to.equal(undefined) + + expect(resolve( '../files/not-found' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('not-found.js') } }) + )).to.equal(undefined) + }) + it('resolves via a custom resolver with interface version 2', function () { const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v2'}) const testContextReports = [] From 3b4cb478a4cb2101154cf53cef082857d3797dd0 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 17:13:16 -0700 Subject: [PATCH 27/56] eslint-module-utils: Add test for import/resolver config checks --- tests/src/core/resolve.js | 40 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 0ead05db0..916654474 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -69,6 +69,46 @@ describe('resolve', function () { expect(testContextReports.length).to.equal(0) }) + it('respects import/resolver as array of strings', function () { + const testContext = utils.testContext({ 'import/resolver': [ './foo-bar-resolver-v2', './foo-bar-resolver-v1' ] }) + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + }) + + it('respects import/resolver as object', function () { + const testContext = utils.testContext({ 'import/resolver': { './foo-bar-resolver-v2': {} } }) + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + }) + + it('respects import/resolver as array of objects', function () { + const testContext = utils.testContext({ 'import/resolver': [ { './foo-bar-resolver-v2': {} }, { './foo-bar-resolver-v1': {} } ] }) + + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(utils.testFilePath('./bar.jsx')) + }) + + it('reports invalid import/resolver config', function () { + const testContext = utils.testContext({ 'import/resolver': 123.456 }) + const testContextReports = [] + testContext.report = function (reportInfo) { + testContextReports.push(reportInfo) + } + + testContextReports.length = 0 + expect(resolve( '../files/foo' + , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) + )).to.equal(undefined) + expect(testContextReports[0]).to.be.an('object') + expect(testContextReports[0].message).to.equal('Resolve error: invalid resolver config') + expect(testContextReports[0].loc).to.eql({ line: 1, column: 0 }) + }) + it('respects import/resolve extensions', function () { const testContext = utils.testContext({ 'import/resolve': { 'extensions': ['.jsx'] }}) From 2bc4f7fc309bc311de2950742256f0ed4d6e70bf Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 17:36:31 -0700 Subject: [PATCH 28/56] eslint-module-utils: Add test for ignore --- tests/files/ignore.invalid.extension | 0 tests/src/core/ignore.js | 58 ++++++++++++++++++++++++++++ tests/src/utils.js | 8 +++- 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tests/files/ignore.invalid.extension create mode 100644 tests/src/core/ignore.js diff --git a/tests/files/ignore.invalid.extension b/tests/files/ignore.invalid.extension new file mode 100644 index 000000000..e69de29bb diff --git a/tests/src/core/ignore.js b/tests/src/core/ignore.js new file mode 100644 index 000000000..cc89f8454 --- /dev/null +++ b/tests/src/core/ignore.js @@ -0,0 +1,58 @@ +import { expect } from 'chai' + +import isIgnored, { hasValidExtension } from 'eslint-module-utils/ignore' + +import * as utils from '../utils' + +describe('ignore', function () { + describe('isIgnored', function () { + it('ignores paths with extensions other than .js', function () { + const testContext = utils.testContext({}) + + expect(isIgnored('../files/foo.js', testContext)).to.equal(false) + + expect(isIgnored('../files/bar.jsx', testContext)).to.equal(true) + + expect(isIgnored('../files/typescript.ts', testContext)).to.equal(true) + + expect(isIgnored('../files/ignore.invalid.extension', testContext)).to.equal(true) + }) + + it('ignores paths with invalid extensions when configured with import/extensions', function () { + const testContext = utils.testContext({ 'import/extensions': [ '.js', '.jsx', '.ts' ] }) + + expect(isIgnored('../files/foo.js', testContext)).to.equal(false) + + expect(isIgnored('../files/bar.jsx', testContext)).to.equal(false) + + expect(isIgnored('../files/typescript.ts', testContext)).to.equal(false) + + expect(isIgnored('../files/ignore.invalid.extension', testContext)).to.equal(true) + }) + }) + + describe('hasValidExtension', function () { + it('assumes only .js as valid by default', function () { + const testContext = utils.testContext({}) + + expect(hasValidExtension('../files/foo.js', testContext)).to.equal(true) + + expect(hasValidExtension('../files/foo.jsx', testContext)).to.equal(false) + + expect(hasValidExtension('../files/foo.css', testContext)).to.equal(false) + + expect(hasValidExtension('../files/foo.invalid.extension', testContext)).to.equal(false) + }) + + it('can be configured with import/extensions', function () { + const testContext = utils.testContext({ 'import/extensions': [ '.foo', '.bar' ] }) + + expect(hasValidExtension('../files/foo.foo', testContext)).to.equal(true) + + expect(hasValidExtension('../files/foo.bar', testContext)).to.equal(true) + + expect(hasValidExtension('../files/foo.js', testContext)).to.equal(false) + }) + }) + +}) diff --git a/tests/src/utils.js b/tests/src/utils.js index 144ae5498..7a13ed432 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -87,4 +87,10 @@ export const SYNTAX_CASES = [ test({ code: 'import * as a from "./commonjs-namespace/a"; a.b', }), - ] + + // ignore invalid extensions + test({ + code: 'import { foo } from "./ignore.invalid.extension"', + }), + +] From 314ead8d3dd626655b48e0a54c99f16c85178a2d Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 17:36:52 -0700 Subject: [PATCH 29/56] eslint-module-utils: Fix test coding style --- tests/src/core/resolve.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/src/core/resolve.js b/tests/src/core/resolve.js index 916654474..bfff7935c 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -12,7 +12,7 @@ describe('resolve', function () { }) it('resolves via a custom resolver with interface version 1', function () { - const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v1'}) + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v1' }) expect(resolve( '../files/foo' , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) @@ -28,7 +28,7 @@ describe('resolve', function () { }) it('resolves via a custom resolver with interface version 1 assumed if not specified', function () { - const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-no-version'}) + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-no-version' }) expect(resolve( '../files/foo' , Object.assign({}, testContext, { getFilename: function () { return utils.getFilename('foo.js') } }) @@ -44,7 +44,7 @@ describe('resolve', function () { }) it('resolves via a custom resolver with interface version 2', function () { - const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v2'}) + const testContext = utils.testContext({ 'import/resolver': './foo-bar-resolver-v2' }) const testContextReports = [] testContext.report = function (reportInfo) { testContextReports.push(reportInfo) From 0ad9659e611d18c48f732bc5f29eb2003eed3975 Mon Sep 17 00:00:00 2001 From: Ross Warren Date: Mon, 13 Feb 2017 11:00:41 +0000 Subject: [PATCH 30/56] support scoped modules containing hyphens --- CHANGELOG.md | 1 + src/core/importType.js | 2 +- tests/src/core/importType.js | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fcb4faa3..4c9a54888 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Yanked due to critical issue in eslint-module-utils with cache key resulting fro ### Fixed - attempt to fix crash in [`no-mutable-exports`]. ([#660]) - "default is a reserved keyword" in no-maned-default tests by locking down babylon to 6.15.0 (#756, thanks @gmathieu) +- support scoped modules containing non word characters ## [2.2.0] - 2016-11-07 diff --git a/src/core/importType.js b/src/core/importType.js index 869ca7496..79b8870b1 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -27,7 +27,7 @@ function isExternalModule(name, settings, path) { return externalModuleRegExp.test(name) && isExternalPath(path, name, settings) } -const scopedRegExp = /^@\w+\/\w+/ +const scopedRegExp = /^@[^\/]+\/[^\/]+/ function isScoped(name) { return scopedRegExp.test(name) } diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 5b63910af..dedf43d0d 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -31,6 +31,9 @@ describe('importType(name)', function () { it("should return 'external' for scopes packages", function() { expect(importType('@cycle/core', context)).to.equal('external') expect(importType('@cycle/dom', context)).to.equal('external') + expect(importType('@some-thing/something', context)).to.equal('external') + expect(importType('@some-thing/something/some-module', context)).to.equal('external') + expect(importType('@some-thing/something/some-directory/someModule.js', context)).to.equal('external') }) it("should return 'internal' for non-builtins resolved outside of node_modules", function () { From 117717f983094348fec9ad74b84685dbaaa50945 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Mon, 5 Jun 2017 10:30:01 -0700 Subject: [PATCH 31/56] eslint-module-utils: Fix resolver tests for Windows paths https://ci.appveyor.com/project/benmosher/eslint-plugin-import/build/2055/job/wsl6hrhpc2dt10cs --- tests/files/foo-bar-resolver-no-version.js | 7 +++---- tests/files/foo-bar-resolver-v1.js | 7 +++---- tests/files/foo-bar-resolver-v2.js | 7 +++---- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/tests/files/foo-bar-resolver-no-version.js b/tests/files/foo-bar-resolver-no-version.js index 6676133b0..89d4eb13e 100644 --- a/tests/files/foo-bar-resolver-no-version.js +++ b/tests/files/foo-bar-resolver-no-version.js @@ -1,12 +1,11 @@ var path = require('path') exports.resolveImport = function (modulePath, sourceFile, config) { - var fooPathSuffix = '/files/foo.js' - var exceptionPathSuffix = '/files/exception.js' - if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { return path.join(__dirname, 'bar.jsx') } - else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + else if (sourceFileName === 'exception.js') { throw new Error('foo-bar-resolver-v1 resolveImport test exception') } else { diff --git a/tests/files/foo-bar-resolver-v1.js b/tests/files/foo-bar-resolver-v1.js index decde2e56..8aafe7aa4 100644 --- a/tests/files/foo-bar-resolver-v1.js +++ b/tests/files/foo-bar-resolver-v1.js @@ -1,12 +1,11 @@ var path = require('path') exports.resolveImport = function (modulePath, sourceFile, config) { - var fooPathSuffix = '/files/foo.js' - var exceptionPathSuffix = '/files/exception.js' - if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { return path.join(__dirname, 'bar.jsx') } - else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + else if (sourceFileName === 'exception.js') { throw new Error('foo-bar-resolver-v1 resolveImport test exception') } else { diff --git a/tests/files/foo-bar-resolver-v2.js b/tests/files/foo-bar-resolver-v2.js index adb764838..9bb68171b 100644 --- a/tests/files/foo-bar-resolver-v2.js +++ b/tests/files/foo-bar-resolver-v2.js @@ -1,12 +1,11 @@ var path = require('path') exports.resolve = function (modulePath, sourceFile, config) { - var fooPathSuffix = '/files/foo.js' - var exceptionPathSuffix = '/files/exception.js' - if (sourceFile.indexOf(fooPathSuffix) === sourceFile.length - fooPathSuffix.length) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { return { found: true, path: path.join(__dirname, 'bar.jsx') } } - else if (sourceFile.indexOf(exceptionPathSuffix) === sourceFile.length - exceptionPathSuffix.length) { + else if (sourceFileName === 'exception.js') { throw new Error('foo-bar-resolver-v2 resolve test exception') } else { From 3268cb1ccde3812025066a2d9e1b59380213f36c Mon Sep 17 00:00:00 2001 From: Luke Page Date: Tue, 13 Jun 2017 18:55:24 +0200 Subject: [PATCH 32/56] Fix documentation of newline-after-import example --- docs/rules/newline-after-import.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/newline-after-import.md b/docs/rules/newline-after-import.md index 42e73f656..a50a1e333 100644 --- a/docs/rules/newline-after-import.md +++ b/docs/rules/newline-after-import.md @@ -76,7 +76,7 @@ const FOO = 'BAR' { ... "rules": { - "import/newline-after-import": [{ "count": 2 }] + "import/newline-after-import": ["error", { "count": 2 }] } } ``` From 406749522a6230eb988804c9be07654ec3ca72a6 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 16 Jun 2017 14:40:14 -0700 Subject: [PATCH 33/56] Only apps should have lockfiles. --- .gitignore | 5 +++++ .npmrc | 1 + 2 files changed, 6 insertions(+) create mode 100644 .npmrc diff --git a/.gitignore b/.gitignore index 24ceac8ff..0bf60608a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,8 @@ node_modules # generated output lib/ **/.nyc_output/ + +# Only apps should have lockfiles +yarn.lock +package-lock.json +npm-shrinkwrap.json diff --git a/.npmrc b/.npmrc new file mode 100644 index 000000000..43c97e719 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false From 3f9e4bf650339b4f2a4800f2d15cc3eb052a08ed Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Fri, 16 Jun 2017 17:13:17 -0700 Subject: [PATCH 34/56] [Tests] comment out failing (and probably invalid) test I suspect that this test is not actually valid syntax, and that babel is now throwing on it. If so, it should simply be removed. --- tests/src/rules/no-named-default.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/src/rules/no-named-default.js b/tests/src/rules/no-named-default.js index 8ca26f860..b7013fcc7 100644 --- a/tests/src/rules/no-named-default.js +++ b/tests/src/rules/no-named-default.js @@ -13,14 +13,14 @@ ruleTester.run('no-named-default', rule, { ], invalid: [ - test({ + /*test({ code: 'import { default } from "./bar";', errors: [{ message: 'Use default import syntax to import \'default\'.', type: 'Identifier', }], parser: 'babel-eslint', - }), + }),*/ test({ code: 'import { default as bar } from "./bar";', errors: [{ From dac23a180e6559011cd82a5834371848c86fd70a Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 06:23:41 -0400 Subject: [PATCH 35/56] eslint-module-utils: v2.1.1 (bumping to re-publish to npm) --- utils/CHANGELOG.md | 5 +++++ utils/package.json | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/utils/CHANGELOG.md b/utils/CHANGELOG.md index 013c6998a..cc9bc051b 100644 --- a/utils/CHANGELOG.md +++ b/utils/CHANGELOG.md @@ -6,6 +6,11 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## v2.1.1 - 2017-06-22 + +Re-releasing v2.1.0 after vetting (again) and unable to reproduce issue. + + ## v2.1.0 - 2017-06-02 [YANKED] Yanked due to critical issue with cache key resulting from #839. diff --git a/utils/package.json b/utils/package.json index 665422ffe..b961179db 100644 --- a/utils/package.json +++ b/utils/package.json @@ -1,6 +1,6 @@ { "name": "eslint-module-utils", - "version": "2.1.0", + "version": "2.1.1", "description": "Core utilities to support eslint-plugin-import and other module-related plugins.", "engines": { "node": ">=4" From 54687d1e488b053206d8af89c6211ade30e77a8a Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 06:27:58 -0400 Subject: [PATCH 36/56] resolvers/webpack: v0.8.2 --- resolvers/webpack/CHANGELOG.md | 3 +++ resolvers/webpack/package.json | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/resolvers/webpack/CHANGELOG.md b/resolvers/webpack/CHANGELOG.md index 6f1f5efef..9795cc686 100644 --- a/resolvers/webpack/CHANGELOG.md +++ b/resolvers/webpack/CHANGELOG.md @@ -5,6 +5,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## 0.8.2 - 2017-06-22 +### Changed +- `webpack` peer dep updated to >= 1.11 (works fine with webpack 3 AFAICT) ## 0.8.1 - 2017-01-19 ### Changed diff --git a/resolvers/webpack/package.json b/resolvers/webpack/package.json index 2f3e06930..bb77c4288 100644 --- a/resolvers/webpack/package.json +++ b/resolvers/webpack/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-webpack", - "version": "0.8.1", + "version": "0.8.2", "description": "Resolve paths to dependencies, given a webpack.config.js. Plugin for eslint-plugin-import.", "main": "index.js", "scripts": { @@ -43,7 +43,7 @@ }, "peerDependencies": { "eslint-plugin-import": ">=1.4.0", - "webpack": "^1.11.0 || ^2.1.0-beta || ^2.1.0 || ^2.2.0-rc" + "webpack": ">=1.11.0" }, "devDependencies": { "chai": "^3.4.1", From 94187a3c5c2ade9959086147daee27f634110ef1 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 06:56:32 -0400 Subject: [PATCH 37/56] bump `debug` version everywhere --- package.json | 2 +- resolvers/node/package.json | 2 +- resolvers/webpack/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c60e9b2ad..a8d04498a 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "dependencies": { "builtin-modules": "^1.1.1", "contains-path": "^0.1.0", - "debug": "^2.2.0", + "debug": "^2.6.8", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.2.0", "eslint-module-utils": "^2.0.0", diff --git a/resolvers/node/package.json b/resolvers/node/package.json index ddd1e5061..7cd304a40 100644 --- a/resolvers/node/package.json +++ b/resolvers/node/package.json @@ -25,7 +25,7 @@ }, "homepage": "https://github.com/benmosher/eslint-plugin-import", "dependencies": { - "debug": "^2.2.0", + "debug": "^2.6.8", "resolve": "^1.2.0" }, "devDependencies": { diff --git a/resolvers/webpack/package.json b/resolvers/webpack/package.json index bb77c4288..4d7557814 100644 --- a/resolvers/webpack/package.json +++ b/resolvers/webpack/package.json @@ -30,7 +30,7 @@ "homepage": "https://github.com/benmosher/eslint-plugin-import#readme", "dependencies": { "array-find": "^1.0.0", - "debug": "^2.2.0", + "debug": "^2.6.8", "enhanced-resolve": "~0.9.0", "find-root": "^0.1.1", "has": "^1.0.1", From c41ed065561d77d9c6bd3dfe622b58c6c6b2f7cd Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 06:57:05 -0400 Subject: [PATCH 38/56] bump to v2.5.0 --- CHANGELOG.md | 14 +++++++++++++- package.json | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fcb4faa3..4e103387d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] +## [2.5.0] - 2017-06-22 + +Re-releasing v[2.4.0] after discovering that the memory leak is isolated to the memo-parser, +which is more or less experimental anyway. + +### Added +- Autofixer for newline-after-import. [#686], [#696] (thanks [@eelyafi]) + ## [2.4.0] - 2017-06-02 [YANKED] Yanked due to critical issue in eslint-module-utils with cache key resulting from [#839]. @@ -400,6 +408,7 @@ for info on changes for earlier releases. [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 [#737]: https://github.com/benmosher/eslint-plugin-import/pull/737 [#712]: https://github.com/benmosher/eslint-plugin-import/pull/712 +[#696]: https://github.com/benmosher/eslint-plugin-import/pull/696 [#685]: https://github.com/benmosher/eslint-plugin-import/pull/685 [#680]: https://github.com/benmosher/eslint-plugin-import/pull/680 [#654]: https://github.com/benmosher/eslint-plugin-import/pull/654 @@ -456,6 +465,7 @@ for info on changes for earlier releases. [#314]: https://github.com/benmosher/eslint-plugin-import/pull/314 [#839]: https://github.com/benmosher/eslint-plugin-import/issues/839 +[#686]: https://github.com/benmosher/eslint-plugin-import/issues/686 [#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 [#660]: https://github.com/benmosher/eslint-plugin-import/issues/660 [#653]: https://github.com/benmosher/eslint-plugin-import/issues/653 @@ -514,7 +524,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.5.0...HEAD +[2.5.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.3.0...v2.4.0 [2.3.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.1.0...v2.2.0 @@ -597,3 +608,4 @@ for info on changes for earlier releases. [@ramasilveyra]: https://github.com/ramasilveyra [@sompylasar]: https://github.com/sompylasar [@kevin940726]: https://github.com/kevin940726 +[@eelyafi]: https://github.com/eelyafi diff --git a/package.json b/package.json index a8d04498a..f39f56258 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.4.0", + "version": "2.5.0", "description": "Import with sanity.", "engines": { "node": ">=4" From b1eeadeae237da407c88be8a989d33e472a8fde7 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 07:09:24 -0400 Subject: [PATCH 39/56] build on node v4, again (#855) * build on node v4 + linux, again * 7 => 8 * 7 => 8 + added 4 back --- .travis.yml | 3 ++- appveyor.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 22918d364..67643e74c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,8 @@ language: node_js node_js: + - 4 - 6 - - 7 + - 8 os: - linux diff --git a/appveyor.yml b/appveyor.yml index 57adb8874..0e86dc9e7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,8 +1,9 @@ # Test against this version of Node.js environment: matrix: - - nodejs_version: "7" + - nodejs_version: "8" - nodejs_version: "6" + - nodejs_version: "4" # platform: # - x86 From 0263be424e30777b23375ea92aaf925f7c979ff8 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 22 Jun 2017 08:02:12 -0400 Subject: [PATCH 40/56] memo-parser: require eslint >= 3.5.0 (need file path always) fixes #862, #863 --- memo-parser/index.js | 5 ++++- memo-parser/package.json | 9 +++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/memo-parser/index.js b/memo-parser/index.js index d8296ac37..9fd74c33a 100644 --- a/memo-parser/index.js +++ b/memo-parser/index.js @@ -17,9 +17,12 @@ const parserOptions = { } exports.parse = function parse(content, options) { - // them defaults yo options = Object.assign({}, options, parserOptions) + if (!options.filePath) { + throw new Error("no file path provided!") + } + const keyHash = crypto.createHash('sha256') keyHash.update(content) hashObject(options, keyHash) diff --git a/memo-parser/package.json b/memo-parser/package.json index a1ffae1ca..2577036ba 100644 --- a/memo-parser/package.json +++ b/memo-parser/package.json @@ -1,7 +1,9 @@ { "name": "memo-parser", "version": "0.1.0", - "engines": { "node": ">=4" }, + "engines": { + "node": ">=4" + }, "description": "Memoizing wrapper for any ESLint-compatible parser module.", "main": "index.js", "scripts": { @@ -21,5 +23,8 @@ "bugs": { "url": "https://github.com/benmosher/eslint-plugin-import/issues" }, - "homepage": "https://github.com/benmosher/eslint-plugin-import#readme" + "homepage": "https://github.com/benmosher/eslint-plugin-import#readme", + "peerDependencies": { + "eslint": ">=3.5.0" + } } From 7f055ec07fe84a2b3f3a4d622d2927167055230a Mon Sep 17 00:00:00 2001 From: Thomas Sileghem Date: Mon, 12 Jun 2017 14:30:56 +0100 Subject: [PATCH 41/56] chore(eslint): upgrade to eslint@4 --- .travis.yml | 10 +++++++++- appveyor.yml | 8 ++++---- package.json | 2 +- src/rules/no-named-default.js | 2 +- tests/src/rules/default.js | 8 ++++++-- tests/src/rules/named.js | 2 +- tests/src/utils.js | 7 ++++--- 7 files changed, 26 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 67643e74c..13e4afec8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,17 @@ os: - linux - osx +env: + - ESLINT_VERSION=2 + - ESLINT_VERSION=3 + - ESLINT_VERSION=4 + install: - - npm -g install npm@3 + - if [ ${TRAVIS_NODE_VERSION} == "4" ]; then + npm install -g npm@3; + fi - npm install + - npm install eslint@$ESLINT_VERSION --ignore-scripts || true # install all resolver deps - "for resolver in ./resolvers/*; do cd $resolver && npm install && cd ../..; done" diff --git a/appveyor.yml b/appveyor.yml index 0e86dc9e7..406099f66 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,11 +14,11 @@ install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version - # update npm (only needed for Node 0.10) - - npm -g install npm@3 - # - set PATH=%APPDATA%\npm;%PATH% - # install modules + - ps: >- + if ($env:nodejs_version -eq "4") { + npm install -g npm@3; + } - npm install # todo: learn how to do this for all .\resolvers\* on Windows diff --git a/package.json b/package.json index f39f56258..24f87d602 100644 --- a/package.json +++ b/package.json @@ -74,7 +74,7 @@ "typescript-eslint-parser": "^2.1.0" }, "peerDependencies": { - "eslint": "2.x - 3.x" + "eslint": "2.x - 4.x" }, "dependencies": { "builtin-modules": "^1.1.1", diff --git a/src/rules/no-named-default.js b/src/rules/no-named-default.js index 3185157f3..0625c1f1e 100644 --- a/src/rules/no-named-default.js +++ b/src/rules/no-named-default.js @@ -10,7 +10,7 @@ module.exports = { if (im.type === 'ImportSpecifier' && im.imported.name === 'default') { context.report({ node: im.local, - message: `Use default import syntax to import \'${im.local.name}\'.` }) + message: `Use default import syntax to import '${im.local.name}'.` }) } }) }, diff --git a/tests/src/rules/default.js b/tests/src/rules/default.js index 5186e56ca..027c5a93d 100644 --- a/tests/src/rules/default.js +++ b/tests/src/rules/default.js @@ -58,8 +58,12 @@ ruleTester.run('default', rule, { // #94: redux export of execution result, test({ code: 'import connectedApp from "./redux"' }), - test({ code: 'import App from "./jsx/App"' - , ecmaFeatures: { jsx: true, modules: true } }), + test({ + code: 'import App from "./jsx/App"', + parserOptions: { + ecmaFeatures: { jsx: true, modules: true }, + }, + }), // from no-errors test({ diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index f1c40b474..f027a5b3d 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -135,7 +135,7 @@ ruleTester.run('named', rule, { test({ code: 'import { a } from "./re-export-names"', - args: [2, 'es6-only'], + options: [2, 'es6-only'], errors: [error('a', './re-export-names')], }), diff --git a/tests/src/utils.js b/tests/src/utils.js index 7a13ed432..144969f5b 100644 --- a/tests/src/utils.js +++ b/tests/src/utils.js @@ -12,11 +12,12 @@ export const FILENAME = testFilePath('foo.js') export function test(t) { return Object.assign({ filename: FILENAME, - parserOptions: { + }, t, { + parserOptions: Object.assign({ sourceType: 'module', ecmaVersion: 6, - }, - }, t) + }, t.parserOptions), + }) } export function testContext(settings) { From 8101d39ea7fe94c1611b7183e5b171428f86f042 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Fri, 23 Jun 2017 06:13:59 -0400 Subject: [PATCH 42/56] bump to 2.6.0, node/0.3.1, webpack/0.8.3, memo-parser/0.2.0 --- CHANGELOG.md | 21 ++++++++++++++++----- memo-parser/package.json | 2 +- package.json | 2 +- resolvers/node/CHANGELOG.md | 4 ++++ resolvers/node/package.json | 2 +- resolvers/webpack/CHANGELOG.md | 4 ++++ resolvers/webpack/package.json | 2 +- 7 files changed, 28 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c561e723..6bb5752b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,21 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] -### Added -- Add `filePath` into `parserOptions` passed to `parser` ([#839], thanks [@sompylasar]) + + +## [2.6.0] - 2017-06-23 +### Changed +- update tests / peerDeps for ESLint 4.0 compatibility ([#871], thanks [@mastilver]) +- [`memo-parser`] updated to require `filePath` on parser options as it melts + down if it's not there, now that this plugin always provides it. (see [#863]) ## [2.5.0] - 2017-06-22 -Re-releasing v[2.4.0] after discovering that the memory leak is isolated to the memo-parser, +Re-releasing v[2.4.0] after discovering that the memory leak is isolated to the [`memo-parser`], which is more or less experimental anyway. ### Added -- Autofixer for newline-after-import. [#686], [#696] (thanks [@eelyafi]) +- Autofixer for newline-after-import. ([#686] + [#696], thanks [@eelyafi]) ## [2.4.0] - 2017-06-02 [YANKED] @@ -405,6 +410,9 @@ for info on changes for earlier releases. [`unambiguous`]: ./docs/rules/unambiguous.md [`no-anonymous-default-export`]: ./docs/rules/no-anonymous-default-export.md +[`memo-parser`]: ./memo-parser/README.md + +[#871]: https://github.com/benmosher/eslint-plugin-import/pull/871 [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 [#737]: https://github.com/benmosher/eslint-plugin-import/pull/737 [#712]: https://github.com/benmosher/eslint-plugin-import/pull/712 @@ -464,6 +472,7 @@ for info on changes for earlier releases. [#157]: https://github.com/benmosher/eslint-plugin-import/pull/157 [#314]: https://github.com/benmosher/eslint-plugin-import/pull/314 +[#863]: https://github.com/benmosher/eslint-plugin-import/issues/863 [#839]: https://github.com/benmosher/eslint-plugin-import/issues/839 [#686]: https://github.com/benmosher/eslint-plugin-import/issues/686 [#671]: https://github.com/benmosher/eslint-plugin-import/issues/671 @@ -524,7 +533,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.5.0...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.0...HEAD +[2.6.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.5.0...v2.6.0 [2.5.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.3.0...v2.4.0 [2.3.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.2.0...v2.3.0 @@ -609,3 +619,4 @@ for info on changes for earlier releases. [@sompylasar]: https://github.com/sompylasar [@kevin940726]: https://github.com/kevin940726 [@eelyafi]: https://github.com/eelyafi +[@mastilver]: https://github.com/mastilver diff --git a/memo-parser/package.json b/memo-parser/package.json index 2577036ba..fa7d12973 100644 --- a/memo-parser/package.json +++ b/memo-parser/package.json @@ -1,6 +1,6 @@ { "name": "memo-parser", - "version": "0.1.0", + "version": "0.2.0", "engines": { "node": ">=4" }, diff --git a/package.json b/package.json index 24f87d602..4c270d71a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.5.0", + "version": "2.6.0", "description": "Import with sanity.", "engines": { "node": ">=4" diff --git a/resolvers/node/CHANGELOG.md b/resolvers/node/CHANGELOG.md index 78c6f77b1..ab692d34b 100644 --- a/resolvers/node/CHANGELOG.md +++ b/resolvers/node/CHANGELOG.md @@ -6,6 +6,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## v0.3.1 - 2017-06-23 +### Changed +- bumped `debug` dep to match other packages + ## v0.3.0 - 2016-12-15 ### Changed - bumped `resolve` to fix issues with Node builtins (thanks [@SkeLLLa] and [@ljharb]) diff --git a/resolvers/node/package.json b/resolvers/node/package.json index 7cd304a40..cce7be4f2 100644 --- a/resolvers/node/package.json +++ b/resolvers/node/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-node", - "version": "0.3.0", + "version": "0.3.1", "description": "Node default behavior import resolution plugin for eslint-plugin-import.", "main": "index.js", "files": ["index.js"], diff --git a/resolvers/webpack/CHANGELOG.md b/resolvers/webpack/CHANGELOG.md index 9795cc686..7b8f9a662 100644 --- a/resolvers/webpack/CHANGELOG.md +++ b/resolvers/webpack/CHANGELOG.md @@ -5,6 +5,10 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## Unreleased +## 0.8.3 - 2017-06-23 +### Changed +- `debug` bumped to match others + ## 0.8.2 - 2017-06-22 ### Changed - `webpack` peer dep updated to >= 1.11 (works fine with webpack 3 AFAICT) diff --git a/resolvers/webpack/package.json b/resolvers/webpack/package.json index 4d7557814..92bad18a8 100644 --- a/resolvers/webpack/package.json +++ b/resolvers/webpack/package.json @@ -1,6 +1,6 @@ { "name": "eslint-import-resolver-webpack", - "version": "0.8.2", + "version": "0.8.3", "description": "Resolve paths to dependencies, given a webpack.config.js. Plugin for eslint-plugin-import.", "main": "index.js", "scripts": { From 9a064263867a7d266402de9ffccab3094d21bb12 Mon Sep 17 00:00:00 2001 From: futpib Date: Fri, 23 Jun 2017 18:51:32 +0300 Subject: [PATCH 43/56] Fix flow interface imports giving false-negative with `named` rule This fixes #708 without ignoring all type imports. --- src/ExportMap.js | 3 ++- tests/files/flowtypes.js | 4 ++++ tests/src/rules/named.js | 8 ++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/ExportMap.js b/src/ExportMap.js index 02b723837..e5e772914 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -155,7 +155,7 @@ export default class ExportMap { const d = dep() // CJS / ignored dependencies won't exist (#717) if (d == null) return - + d.forEach((v, n) => n !== 'default' && callback.call(thisArg, v, n, this)) }) @@ -406,6 +406,7 @@ ExportMap.parse = function (path, content, context) { case 'FunctionDeclaration': case 'ClassDeclaration': case 'TypeAlias': // flowtype with babel-eslint parser + case 'InterfaceDeclaration': m.namespace.set(n.declaration.id.name, captureDoc(docStyleParsers, n)) break case 'VariableDeclaration': diff --git a/tests/files/flowtypes.js b/tests/files/flowtypes.js index e4bbb0fd8..7ada3482b 100644 --- a/tests/files/flowtypes.js +++ b/tests/files/flowtypes.js @@ -6,3 +6,7 @@ export type MyType = { firstName: string, lastName: string }; + +export interface MyInterface {} + +export class MyClass {} diff --git a/tests/src/rules/named.js b/tests/src/rules/named.js index f027a5b3d..8cee0c731 100644 --- a/tests/src/rules/named.js +++ b/tests/src/rules/named.js @@ -72,6 +72,14 @@ ruleTester.run('named', rule, { code: 'import type { MyType } from "./flowtypes"', 'parser': 'babel-eslint', }), + test({ + code: 'import type { MyInterface } from "./flowtypes"', + 'parser': 'babel-eslint', + }), + test({ + code: 'import type { MyClass } from "./flowtypes"', + 'parser': 'babel-eslint', + }), // jsnext test({ From 56e60e4485f98b8d0374d1e71cb8911df5bc9e5a Mon Sep 17 00:00:00 2001 From: Ali Torki Date: Wed, 28 Jun 2017 19:36:47 +0430 Subject: [PATCH 44/56] Update no-extraneous-dependencies.md (#878) --- docs/rules/no-extraneous-dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/rules/no-extraneous-dependencies.md b/docs/rules/no-extraneous-dependencies.md index 1a18333f3..36aef8f9d 100644 --- a/docs/rules/no-extraneous-dependencies.md +++ b/docs/rules/no-extraneous-dependencies.md @@ -89,7 +89,7 @@ var foo = require('./foo'); import test from 'ava'; import find from 'lodash.find'; -import find from 'lodash.isarray'; +import isArray from 'lodash.isarray'; /* eslint import/no-extraneous-dependencies: ["error", {"peerDependencies": true}] */ import react from 'react'; From d9b712ac7fd1fddc391f7b234827925c160d956f Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 29 Jun 2017 06:58:38 -0400 Subject: [PATCH 45/56] =?UTF-8?q?bump=20to=20v2.6.1=20to=20bump=20dep=20on?= =?UTF-8?q?=20node=20resolver=20to=20latest=20=F0=9F=98=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 6 +++++- package.json | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb5752b6..337a8d3ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] +## [2.6.1] - 2017-06-29 +### Fixed +- update bundled node resolver dependency to latest version ## [2.6.0] - 2017-06-23 ### Changed @@ -533,7 +536,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.0...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.1...HEAD +[2.6.1]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.0...v2.6.1 [2.6.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.5.0...v2.6.0 [2.5.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...v2.5.0 [2.4.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.3.0...v2.4.0 diff --git a/package.json b/package.json index 4c270d71a..2ec09b9fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.6.0", + "version": "2.6.1", "description": "Import with sanity.", "engines": { "node": ">=4" @@ -81,7 +81,7 @@ "contains-path": "^0.1.0", "debug": "^2.6.8", "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.2.0", + "eslint-import-resolver-node": "^0.3.1", "eslint-module-utils": "^2.0.0", "has": "^1.0.1", "lodash.cond": "^4.3.0", From e4b88849a64f65c14692e732d298d69314bfd807 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 6 Jul 2017 06:32:13 -0400 Subject: [PATCH 46/56] PR note fixes --- src/core/importType.js | 5 +++++ src/rules/no-absolute-path.js | 5 +---- tests/src/core/importType.js | 6 ++++++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index 6f37743f1..23bc6350d 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -8,6 +8,10 @@ function constant(value) { return () => value } +export function isAbsolute(name) { + return name.indexOf('/') === 0 +} + export function isBuiltIn(name, settings) { const extras = (settings && settings['import/core-modules']) || [] return builtinModules.indexOf(name) !== -1 || extras.indexOf(name) > -1 @@ -46,6 +50,7 @@ function isRelativeToSibling(name) { } const typeTest = cond([ + [isAbsolute, constant('absolute')], [isBuiltIn, constant('builtin')], [isExternalModule, constant('external')], [isScoped, constant('external')], diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index 8503be0d5..e4cf18a63 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -1,3 +1,4 @@ +import { isAbsolute } from '../core/importType' import isStaticRequire from '../core/staticRequire' function reportIfAbsolute(context, node, name) { @@ -6,10 +7,6 @@ function reportIfAbsolute(context, node, name) { } } -function isAbsolute(name) { - return name.indexOf('/') === 0 -} - module.exports = { meta: { docs: {}, diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 9e552e60b..5b63910af 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -8,6 +8,12 @@ import { testContext } from '../utils' describe('importType(name)', function () { const context = testContext() + it("should return 'absolute' for paths starting with a /", function() { + expect(importType('/', context)).to.equal('absolute') + expect(importType('/path', context)).to.equal('absolute') + expect(importType('/some/path', context)).to.equal('absolute') + }) + it("should return 'builtin' for node.js modules", function() { expect(importType('fs', context)).to.equal('builtin') expect(importType('path', context)).to.equal('builtin') From f70d127b9d101a87d0d4160b62ffe16845e6e854 Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 6 Jul 2017 06:53:37 -0400 Subject: [PATCH 47/56] upgraded no-absolute-path to use `moduleVisitor` pattern to support all module systems --- docs/rules/no-absolute-path.md | 21 ++++++++++ src/rules/no-absolute-path.js | 25 +++++------- tests/src/rules/no-absolute-path.js | 61 ++++++++++++++++++----------- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/docs/rules/no-absolute-path.md b/docs/rules/no-absolute-path.md index 9a4be74f8..aa9cf142d 100644 --- a/docs/rules/no-absolute-path.md +++ b/docs/rules/no-absolute-path.md @@ -25,3 +25,24 @@ var _ = require('lodash'); var foo = require('foo'); var foo = require('./foo'); ``` + +### Options + +By default, only ES6 imports and CommonJS `require` calls will have this rule enforced. + +You may provide an options object providing true/false for any of + +- `esmodule`: defaults to `true` +- `commonjs`: defaults to `true` +- `amd`: defaults to `false` + +If `{ amd: true }` is provided, dependency paths for AMD-style `define` and `require` +calls will be resolved: + +```js +/*eslint import/no-absolute-path: [2, { commonjs: false, amd: true }]*/ +define(['/foo'], function (foo) { /*...*/ }) // reported +require(['/foo'], function (foo) { /*...*/ }) // reported + +const foo = require('/foo') // ignored because of explicit `commonjs: false` +``` diff --git a/src/rules/no-absolute-path.js b/src/rules/no-absolute-path.js index e4cf18a63..0f7b2bc48 100644 --- a/src/rules/no-absolute-path.js +++ b/src/rules/no-absolute-path.js @@ -1,27 +1,20 @@ import { isAbsolute } from '../core/importType' -import isStaticRequire from '../core/staticRequire' - -function reportIfAbsolute(context, node, name) { - if (isAbsolute(name)) { - context.report(node, 'Do not import modules using an absolute path') - } -} +import moduleVisitor, { makeOptionsSchema } from 'eslint-module-utils/moduleVisitor' module.exports = { meta: { docs: {}, + schema: [ makeOptionsSchema() ], }, create: function (context) { - return { - ImportDeclaration: function handleImports(node) { - reportIfAbsolute(context, node, node.source.value) - }, - CallExpression: function handleRequires(node) { - if (isStaticRequire(node)) { - reportIfAbsolute(context, node, node.arguments[0].value) - } - }, + function reportIfAbsolute(source) { + if (isAbsolute(source.value)) { + context.report(source, 'Do not import modules using an absolute path') + } } + + const options = Object.assign({ esmodule: true, commonjs: true }, context.options[0]) + return moduleVisitor(reportIfAbsolute, options) }, } diff --git a/tests/src/rules/no-absolute-path.js b/tests/src/rules/no-absolute-path.js index 88951672b..8689997b4 100644 --- a/tests/src/rules/no-absolute-path.js +++ b/tests/src/rules/no-absolute-path.js @@ -26,35 +26,29 @@ ruleTester.run('no-absolute-path', rule, { test({ code: 'var foo = require("foo")'}), test({ code: 'var foo = require("./")'}), test({ code: 'var foo = require("@scope/foo")'}), - test({ - code: 'import events from "events"', - options: [{ - allow: ['events'], - }], - }), + + test({ code: 'import events from "events"' }), + test({ code: 'import path from "path"' }), + test({ code: 'var events = require("events")' }), + test({ code: 'var path = require("path")' }), + test({ code: 'import path from "path";import events from "events"' }), + + // still works if only `amd: true` is provided test({ code: 'import path from "path"', - options: [{ - allow: ['path'], - }], - }), - test({ - code: 'var events = require("events")', - options: [{ - allow: ['events'], - }], + options: [{ amd: true }], }), + + // amd not enabled by default + test({ code: 'require(["/some/path"], function (f) { /* ... */ })' }), + test({ code: 'define(["/some/path"], function (f) { /* ... */ })' }), test({ - code: 'var path = require("path")', - options: [{ - allow: ['path'], - }], + code: 'require(["./some/path"], function (f) { /* ... */ })', + options: [{ amd: true }], }), test({ - code: 'import path from "path";import events from "events"', - options: [{ - allow: ['path', 'events'], - }], + code: 'define(["./some/path"], function (f) { /* ... */ })', + options: [{ amd: true }], }), ], invalid: [ @@ -70,6 +64,11 @@ ruleTester.run('no-absolute-path', rule, { code: 'import f from "/some/path"', errors: [error], }), + test({ + code: 'import f from "/some/path"', + options: [{ amd: true }], + errors: [error], + }), test({ code: 'var f = require("/foo")', errors: [error], @@ -82,5 +81,21 @@ ruleTester.run('no-absolute-path', rule, { code: 'var f = require("/some/path")', errors: [error], }), + test({ + code: 'var f = require("/some/path")', + options: [{ amd: true }], + errors: [error], + }), + // validate amd + test({ + code: 'require(["/some/path"], function (f) { /* ... */ })', + options: [{ amd: true }], + errors: [error], + }), + test({ + code: 'define(["/some/path"], function (f) { /* ... */ })', + options: [{ amd: true }], + errors: [error], + }), ], }) From ee5a986cfd3ed9d97857889655a969031f65f66d Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 6 Jul 2017 07:01:13 -0400 Subject: [PATCH 48/56] changelog note for #843 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 337a8d3ad..4dba6e5dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] +### Changed +- [`no-absolute-path`] picks up speed boost, optional AMD support ([#843], thansk [@jseminck]) ## [2.6.1] - 2017-06-29 ### Fixed @@ -415,6 +417,7 @@ for info on changes for earlier releases. [`memo-parser`]: ./memo-parser/README.md +[#843]: https://github.com/benmosher/eslint-plugin-import/pull/843 [#871]: https://github.com/benmosher/eslint-plugin-import/pull/871 [#742]: https://github.com/benmosher/eslint-plugin-import/pull/742 [#737]: https://github.com/benmosher/eslint-plugin-import/pull/737 @@ -624,3 +627,4 @@ for info on changes for earlier releases. [@kevin940726]: https://github.com/kevin940726 [@eelyafi]: https://github.com/eelyafi [@mastilver]: https://github.com/mastilver +[@jseminck]: https://github.com/jseminck From c9dd91d4fcfab3bb0f209a208e16077cb5843ceb Mon Sep 17 00:00:00 2001 From: Ben Mosher Date: Thu, 6 Jul 2017 07:05:02 -0400 Subject: [PATCH 49/56] bump to v2.7.0 --- CHANGELOG.md | 6 +++++- package.json | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dba6e5dd..64381788e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). This change log adheres to standards from [Keep a CHANGELOG](http://keepachangelog.com). ## [Unreleased] + + +## [2.7.0] - 2017-07-06 ### Changed - [`no-absolute-path`] picks up speed boost, optional AMD support ([#843], thansk [@jseminck]) @@ -539,7 +542,8 @@ for info on changes for earlier releases. [#119]: https://github.com/benmosher/eslint-plugin-import/issues/119 [#89]: https://github.com/benmosher/eslint-plugin-import/issues/89 -[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.1...HEAD +[Unreleased]: https://github.com/benmosher/eslint-plugin-import/compare/v2.7.0...HEAD +[2.7.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.1...v2.7.0 [2.6.1]: https://github.com/benmosher/eslint-plugin-import/compare/v2.6.0...v2.6.1 [2.6.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.5.0...v2.6.0 [2.5.0]: https://github.com/benmosher/eslint-plugin-import/compare/v2.4.0...v2.5.0 diff --git a/package.json b/package.json index 2ec09b9fe..925eec366 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eslint-plugin-import", - "version": "2.6.1", + "version": "2.7.0", "description": "Import with sanity.", "engines": { "node": ">=4" @@ -82,7 +82,7 @@ "debug": "^2.6.8", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.0.0", + "eslint-module-utils": "^2.1.1", "has": "^1.0.1", "lodash.cond": "^4.3.0", "minimatch": "^3.0.3", From dbc9ec735d9fd32ae69499c235f2a0deb106be94 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 14:47:01 -0600 Subject: [PATCH 50/56] bugfix: #886 --- src/core/importType.js | 3 ++- tests/src/core/importType.js | 7 ++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index 23bc6350d..c196ecd39 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -13,8 +13,9 @@ export function isAbsolute(name) { } export function isBuiltIn(name, settings) { + const baseModule = name.split('/')[0] const extras = (settings && settings['import/core-modules']) || [] - return builtinModules.indexOf(name) !== -1 || extras.indexOf(name) > -1 + return builtinModules.indexOf(baseModule) !== -1 || extras.indexOf(baseModule) > -1 } function isExternalPath(path, name, settings) { diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 5b63910af..e5e6f85ea 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe('importType(name)', function () { +describe.only('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { @@ -74,6 +74,11 @@ describe('importType(name)', function () { expect(importType('electron', electronContext)).to.equal('builtin') }) + it("should return 'builtin' for resources inside additional core modules", function() { + const electronContext = testContext({ 'import/core-modules': ['electron'] }) + expect(importType('electron/some/path/to/resource.json', electronContext)).to.equal('builtin') + }) + it("should return 'external' for module from 'node_modules' with default config", function() { expect(importType('builtin-modules', context)).to.equal('external') }) From 307ddeb587ce5abc382e9c827da045f0e5dcb292 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 14:49:52 -0600 Subject: [PATCH 51/56] cleanup: no exclusive tests --- tests/src/core/importType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index e5e6f85ea..20bdd676d 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe.only('importType(name)', function () { +describe('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { From ed65a7412a90f4e3cf475efaff7a8ea001d6adc1 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 15:47:24 -0600 Subject: [PATCH 52/56] logic: improve scoped module scoping --- src/core/importType.js | 13 +++++++++++-- tests/src/core/importType.js | 9 ++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/core/importType.js b/src/core/importType.js index c196ecd39..cc97de0d3 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -8,14 +8,23 @@ function constant(value) { return () => value } +function baseModule(name) { + if (isScoped(name)) { + const [scope, pkg] = name.split('/') + return `${scope}/${pkg}` + } + const [pkg] = name.split('/') + return pkg +} + export function isAbsolute(name) { return name.indexOf('/') === 0 } export function isBuiltIn(name, settings) { - const baseModule = name.split('/')[0] + const base = baseModule(name) const extras = (settings && settings['import/core-modules']) || [] - return builtinModules.indexOf(baseModule) !== -1 || extras.indexOf(baseModule) > -1 + return builtinModules.indexOf(base) !== -1 || extras.indexOf(base) > -1 } function isExternalPath(path, name, settings) { diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 20bdd676d..6f6c1ea73 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe('importType(name)', function () { +describe.only('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { @@ -69,14 +69,21 @@ describe('importType(name)', function () { it("should return 'builtin' for additional core modules", function() { // without extra config, should be marked external expect(importType('electron', context)).to.equal('external') + expect(importType('@org/foobar', context)).to.equal('external') const electronContext = testContext({ 'import/core-modules': ['electron'] }) expect(importType('electron', electronContext)).to.equal('builtin') + + const scopedContext = testContext({ 'import/core-modules': ['@org/foobar'] }) + expect(importType('@org/foobar', scopedContext)).to.equal('builtin') }) it("should return 'builtin' for resources inside additional core modules", function() { const electronContext = testContext({ 'import/core-modules': ['electron'] }) expect(importType('electron/some/path/to/resource.json', electronContext)).to.equal('builtin') + + const scopedContext = testContext({ 'import/core-modules': ['@org/foobar'] }) + expect(importType('@org/foobar/some/path/to/resource.json', scopedContext)).to.equal('builtin') }) it("should return 'external' for module from 'node_modules' with default config", function() { From 2f2dfb0a818f0c5cc6f5939627568636548bce97 Mon Sep 17 00:00:00 2001 From: Matt Lewis Date: Sun, 9 Jul 2017 15:48:12 -0600 Subject: [PATCH 53/56] cleanup: no exclusive tests --- tests/src/core/importType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/core/importType.js b/tests/src/core/importType.js index 6f6c1ea73..1a4816d1a 100644 --- a/tests/src/core/importType.js +++ b/tests/src/core/importType.js @@ -5,7 +5,7 @@ import importType from 'core/importType' import { testContext } from '../utils' -describe.only('importType(name)', function () { +describe('importType(name)', function () { const context = testContext() it("should return 'absolute' for paths starting with a /", function() { From ccd93942a0b9f59f1b698672ba167ece1aa9f5f1 Mon Sep 17 00:00:00 2001 From: "Anders D. Johnson" Date: Tue, 11 Jul 2017 12:22:28 -0500 Subject: [PATCH 54/56] docs(readme): add space (#888) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c8c3789aa..aec72d44a 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,7 @@ In the interest of supporting both of these, v0.11 introduces resolvers. Currently [Node] and [Webpack] resolution have been implemented, but the resolvers are just npm packages, so [third party packages are supported](https://github.com/benmosher/eslint-plugin-import/wiki/Resolvers) (and encouraged!). -You can reference resolvers in several ways(in order of precedence): +You can reference resolvers in several ways (in order of precedence): - as a conventional `eslint-import-resolver` name, like `eslint-import-resolver-foo`: From 72d13858e044569d6f194922e507578410601f28 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 25 Jul 2017 22:16:25 -0700 Subject: [PATCH 55/56] [Dev Deps] dev dep ranges should match peer dep ranges --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 925eec366..c62fbcfe7 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "chai": "^3.4.0", "coveralls": "^2.11.4", "cross-env": "^4.0.0", - "eslint": "3.x", + "eslint": "2.x - 4.x", "eslint-import-resolver-node": "file:./resolvers/node", "eslint-import-resolver-webpack": "file:./resolvers/webpack", "eslint-module-utils": "file:./utils", From dd281306089ba15394aeb2b85241509286442e34 Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Tue, 25 Jul 2017 22:16:49 -0700 Subject: [PATCH 56/56] [Fix] unescape unnecessarily escaped regex slashes --- src/core/importType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/importType.js b/src/core/importType.js index a9aef56a3..905b82613 100644 --- a/src/core/importType.js +++ b/src/core/importType.js @@ -27,7 +27,7 @@ function isExternalModule(name, settings, path) { return externalModuleRegExp.test(name) && isExternalPath(path, name, settings) } -const scopedRegExp = /^@[^\/]+\/[^\/]+/ +const scopedRegExp = /^@[^/]+\/[^/]+/ function isScoped(name) { return scopedRegExp.test(name) }