From b4d75c80c5eba883b9e2314094e253a4e70a06f2 Mon Sep 17 00:00:00 2001 From: Ivan Babak Date: Fri, 19 May 2017 16:26:36 -0700 Subject: [PATCH 1/7] 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 c93417a61d..a38e9b81c0 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 2/7] 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 e047404a0f..827089ad98 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 0edaa58e03..c75c61b7f9 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 0793a70c25..ab167b692f 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 0000000000..81daace434 --- /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 144ae54980..877855a941 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 e31196c691..e1522cbc50 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 0f76e24d98..bc234b534e 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 a38e9b81c0..671dc86c0a 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 3/7] 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 c75c61b7f9..0edaa58e03 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 e1522cbc50..241398a416 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 bc234b534e..0f76e24d98 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 4/7] 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 0edaa58e03..60b53c3cdd 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 ab167b692f..41c0d9a8cf 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 877855a941..144ae54980 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 5/7] Fix CHANGELOG merge error --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e1f135f85..246b82083e 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 6/7] 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 41c0d9a8cf..55a37f34cd 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 7/7] 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 55a37f34cd..2feea07ae1 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) })