From b4d75c80c5eba883b9e2314094e253a4e70a06f2 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 19 May 2017 16:26:36 -0700 Subject: [PATCH 01/15] 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 02/15] 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 03/15] 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 d0007f269c82e648e724dde509245082eaed10f5 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 26 May 2017 14:33:41 -0700 Subject: [PATCH 04/15] 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 05/15] 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 06/15] 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 07/15] 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 17d2ee937d4aa98aeaae5a7dc4a83cf18f5432d9 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Sun, 4 Jun 2017 14:52:14 -0700 Subject: [PATCH 08/15] 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 09/15] 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 10/15] 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 11/15] 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 12/15] 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 13/15] 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 14/15] 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 117717f983094348fec9ad74b84685dbaaa50945 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Mon, 5 Jun 2017 10:30:01 -0700 Subject: [PATCH 15/15] 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 {