From c1b5c2b4843b986cc2c4e96f1b75d1e463162d24 Mon Sep 17 00:00:00 2001 From: James Owen Date: Sun, 14 Apr 2019 13:47:33 +0200 Subject: [PATCH] [[FIX]] Use relative paths with `--filename` when recieving from stdin When linting stdin with the `--filename` option set, config overrides that were relative to the current directory had no effect. This fixes that issue, but existing workarounds will still work. This is ensured by adding versions of the existing overrides tests that pass their data in using stdin. Fixes 2536 (Extra comment at the bottom) --- src/cli.js | 13 ++++- tests/cli.js | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+), 2 deletions(-) diff --git a/src/cli.js b/src/cli.js index 7933ca67cd..4a74903437 100644 --- a/src/cli.js +++ b/src/cli.js @@ -611,15 +611,24 @@ var exports = { } var filename; + var lintStdinFile; // There is an if(filename) check in the lint() function called below. // passing a filename of undefined is the same as calling the function // without a filename. If there is no opts.filename, filename remains // undefined and lint() is effectively called with 4 parameters. if (opts.filename) { - filename = path.resolve(opts.filename); + filename = opts.filename; + var ignores = !opts.ignores ? loadIgnores({ cwd: opts.cwd }) : + opts.ignores.map(function(target) { + return path.resolve(target); + }); + lintStdinFile = (opts.useStdin && !isIgnored(filename, ignores)); + } else { + lintStdinFile = opts.useStdin; } - if (opts.useStdin && opts.ignores.indexOf(filename) === -1) { + + if (lintStdinFile) { cli.withStdin(function(code) { var config = opts.config; diff --git a/tests/cli.js b/tests/cli.js index 931e7caab3..f7e5871725 100644 --- a/tests/cli.js +++ b/tests/cli.js @@ -1472,6 +1472,146 @@ exports.useStdin = { test.equal(cli.exit.args[1][0], 0, "The input is not linted because the specified file name is ignored."); + test.done(); + }, + + // Overrides should work when the passed stdin filename is in the current directoy + testOverridesFromStdin: function (test) { + var dir = __dirname + "/../examples/"; + var rep = require("../examples/reporter.js"); + var config = { + "asi": true, + "overrides": { + "bar.js": { + "asi": false + } + } + }; + + this.sinon.stub(process, "cwd").returns(dir); + this.sinon.stub(rep, "reporter"); + this.sinon.stub(shjs, "cat") + .withArgs(sinon.match(/config\.json$/)) + .returns(JSON.stringify(config)); + + this.sinon.stub(shjs, "test") + .withArgs("-e", sinon.match(/config\.json$/)).returns(true); + + cli.exit.withArgs(0).returns(true) + .withArgs(1).throws("ProcessExit"); + + // Test successful file + cli.interpret([ + "node", "jshint", "--filename", "foo.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + this.stdin.reset(true); + test.ok(rep.reporter.args[0][0].length === 0); + + // Test overriden, failed file + cli.interpret([ + "node", "jshint", "--filename", "bar.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + test.ok(rep.reporter.args[1][0].length > 0, "Error was expected but not thrown"); + test.equal(rep.reporter.args[1][0][0].error.code, "W033"); + + test.done(); + }, + + // Override behaviour for implicit relative paths (without a leading ./) should be the same + // for stdin as for file + testOverridesMatchesImplicitRelativePathsFromStdin: function (test) { + var dir = __dirname + "/../examples/"; + var rep = require("../examples/reporter.js"); + var config = { + "asi": true, + "overrides": { + "src/bar.js": { + "asi": false + } + } + }; + + this.sinon.stub(process, "cwd").returns(dir); + this.sinon.stub(rep, "reporter"); + this.sinon.stub(shjs, "cat") + .withArgs(sinon.match(/config\.json$/)) + .returns(JSON.stringify(config)); + + this.sinon.stub(shjs, "test") + .withArgs("-e", sinon.match(/config\.json$/)).returns(true); + + cli.exit.withArgs(0).returns(true) + .withArgs(1).throws("ProcessExit"); + + // Test successful file + cli.interpret([ + "node", "jshint", "--filename", "src/foo.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + this.stdin.reset(true); + test.ok(rep.reporter.args[0][0].length === 0); + + // Test overriden, failed file + cli.interpret([ + "node", "jshint", "--filename", "src/bar.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + test.ok(rep.reporter.args[1][0].length > 0, "Error was expected but not thrown"); + test.equal(rep.reporter.args[1][0][0].error.code, "W033"); + + test.done(); + }, + + // Override behaviour for explicit relative paths (with a leading ./) should be the same + // for stdin as for file + testOverridesMatchesExplicitRelativePathsFromStdin: function (test) { + var dir = __dirname + "/../examples/"; + var rep = require("../examples/reporter.js"); + var config = { + "asi": true, + "overrides": { + "src/bar.js": { + "asi": false + } + } + }; + + this.sinon.stub(process, "cwd").returns(dir); + this.sinon.stub(rep, "reporter"); + this.sinon.stub(shjs, "cat") + .withArgs(sinon.match(/config\.json$/)) + .returns(JSON.stringify(config)); + + this.sinon.stub(shjs, "test") + .withArgs("-e", sinon.match(/config\.json$/)).returns(true); + + cli.exit.withArgs(0).returns(true) + .withArgs(1).throws("ProcessExit"); + + // Test successful file + cli.interpret([ + "node", "jshint", "--filename", "./src/foo.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + this.stdin.reset(true); + test.ok(rep.reporter.args[0][0].length === 0); + + // Test overriden, failed file + cli.interpret([ + "node", "jshint", "--filename", "./src/bar.js", "--config", "config.json", "--reporter", "reporter.js", "-" + ]); + this.stdin.send("a()"); + this.stdin.end(); + test.ok(rep.reporter.args[1][0].length > 0, "Error was expected but not thrown"); + test.equal(rep.reporter.args[1][0][0].error.code, "W033"); + test.done(); } };