diff --git a/.travis.yml b/.travis.yml index 22918d3647..13e4afec85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,24 @@ language: node_js node_js: + - 4 - 6 - - 7 + - 8 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/CHANGELOG.md b/CHANGELOG.md index 4e103387d5..6bb5752b6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,19 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel ## [Unreleased] +## [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] @@ -152,8 +158,7 @@ Yanked due to critical issue in eslint-module-utils with cache key resulting fro - 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 [ -ED] +## [1.10.1] - 2016-07-02 [YANKED] ### Added - Officially support ESLint 3.x. (peerDependencies updated to `2.x - 3.x`) @@ -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/appveyor.yml b/appveyor.yml index 57adb88741..406099f667 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 @@ -13,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/memo-parser/index.js b/memo-parser/index.js index d8296ac379..9fd74c33a9 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 a1ffae1cad..fa7d12973e 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" }, + "version": "0.2.0", + "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" + } } diff --git a/package.json b/package.json index f39f562585..4c270d71a0 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" @@ -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/resolvers/node/CHANGELOG.md b/resolvers/node/CHANGELOG.md index 78c6f77b1b..ab692d34b6 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 7cd304a405..cce7be4f2f 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 9795cc6863..7b8f9a662b 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 4d75578147..92bad18a85 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": { diff --git a/src/rules/no-named-default.js b/src/rules/no-named-default.js index 3185157f30..0625c1f1ea 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/files/foo-bar-resolver-no-version.js b/tests/files/foo-bar-resolver-no-version.js new file mode 100644 index 0000000000..89d4eb13e2 --- /dev/null +++ b/tests/files/foo-bar-resolver-no-version.js @@ -0,0 +1,14 @@ +var path = require('path') + +exports.resolveImport = function (modulePath, sourceFile, config) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { + return path.join(__dirname, 'bar.jsx') + } + else if (sourceFileName === 'exception.js') { + throw new Error('foo-bar-resolver-v1 resolveImport test exception') + } + else { + return undefined + } +} diff --git a/tests/files/foo-bar-resolver-v1.js b/tests/files/foo-bar-resolver-v1.js new file mode 100644 index 0000000000..8aafe7aa45 --- /dev/null +++ b/tests/files/foo-bar-resolver-v1.js @@ -0,0 +1,16 @@ +var path = require('path') + +exports.resolveImport = function (modulePath, sourceFile, config) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { + return path.join(__dirname, 'bar.jsx') + } + else if (sourceFileName === 'exception.js') { + 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 0000000000..9bb68171b7 --- /dev/null +++ b/tests/files/foo-bar-resolver-v2.js @@ -0,0 +1,16 @@ +var path = require('path') + +exports.resolve = function (modulePath, sourceFile, config) { + var sourceFileName = path.basename(sourceFile) + if (sourceFileName === 'foo.js') { + return { found: true, path: path.join(__dirname, 'bar.jsx') } + } + else if (sourceFileName === 'exception.js') { + 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 92421ba26c..0000000000 --- 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/files/ignore.invalid.extension b/tests/files/ignore.invalid.extension new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/src/core/getExports.js b/tests/src/core/getExports.js index 62513d4420..c3da17fe72 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/hash.js b/tests/src/core/hash.js new file mode 100644 index 0000000000..f8dd4b49ac --- /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",},],},}') + }) + }) + +}) diff --git a/tests/src/core/ignore.js b/tests/src/core/ignore.js new file mode 100644 index 0000000000..cc89f84543 --- /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/core/parse.js b/tests/src/core/parse.js index 2feea07ae1..9cc153ae3c 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 e8f255f345..bfff7935ca 100644 --- a/tests/src/core/resolve.js +++ b/tests/src/core/resolve.js @@ -7,24 +7,114 @@ 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) }) - 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 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 = [] + 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/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 () { - 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) diff --git a/tests/src/rules/default.js b/tests/src/rules/default.js index 5186e56ca4..027c5a93de 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 f1c40b4749..f027a5b3db 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 144ae54980..144969f5b0 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) { @@ -87,4 +88,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"', + }), + +]