Skip to content

Commit

Permalink
Fix: Use error templates even when reading from stdin (fixes #7213) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
not-an-aardvark authored and ilyavolodin committed Sep 28, 2016
1 parent 66adac1 commit 85b8714
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 9 deletions.
5 changes: 3 additions & 2 deletions Makefile.js
Expand Up @@ -87,7 +87,8 @@ const NODE = "node ", // intentional extra space
*/
function getTestFilePatterns() {
const testLibPath = "tests/lib/",
testTemplatesPath = "tests/templates/";
testTemplatesPath = "tests/templates/",
testBinPath = "tests/bin/";

return ls(testLibPath).filter(function(pathToCheck) {
return test("-d", testLibPath + pathToCheck);
Expand All @@ -96,7 +97,7 @@ function getTestFilePatterns() {
initialValue.push(testLibPath + currentValues + "/**/*.js");
}
return initialValue;
}, [testLibPath + "rules/**/*.js", testLibPath + "*.js", testTemplatesPath + "*.js"]).join(" ");
}, [testLibPath + "rules/**/*.js", testLibPath + "*.js", testTemplatesPath + "*.js", testBinPath + "**/*.js"]).join(" ");
}

/**
Expand Down
8 changes: 1 addition & 7 deletions bin/eslint.js
Expand Up @@ -56,13 +56,7 @@ process.on("uncaughtException", function(err) {

if (useStdIn) {
process.stdin.pipe(concat({ encoding: "string" }, function(text) {
try {
process.exitCode = cli.execute(process.argv, text);
} catch (ex) {
console.error(ex.message);
console.error(ex.stack);
process.exitCode = 1;
}
process.exitCode = cli.execute(process.argv, text);
}));
} else if (init) {
const configInit = require("../lib/config/config-initializer");
Expand Down
2 changes: 2 additions & 0 deletions tests/bin/.eslintrc.yml
@@ -0,0 +1,2 @@
env:
mocha: true
112 changes: 112 additions & 0 deletions tests/bin/eslint.js
@@ -0,0 +1,112 @@
/**
* @fileoverview Tests for the eslint.js executable.
* @author Teddy Katz
*/

"use strict";

const childProcess = require("child_process");
const assert = require("chai").assert;
const EXECUTABLE_PATH = require("path").resolve(`${__dirname}/../../bin/eslint.js`);

/**
* Asserts that the exit code of a given child process will equal the given value.
* @param {ChildProcess} exitingProcess The child process
* @param {number} expectedExitCode The expected exit code of the child process
* @returns {Promise} A Promise that fufills if the exit code ends up matching, and rejects otherwise.
*/
function assertExitCode(exitingProcess, expectedExitCode) {
return new Promise((resolve, reject) => {
exitingProcess.once("exit", exitCode => {
if (exitCode === expectedExitCode) {
resolve();
} else {
reject(new Error(`Expected an exit code of ${expectedExitCode} but got ${exitCode}.`));
}
});
});
}

/**
* Returns a Promise for the stdout of a process.
* @param {ChildProcess} runningProcess The child process
* @returns {Promise<string>} A Promise that fulfills with all of the stdout output produced by the process when it exits.
*/
function getStdout(runningProcess) {
let stdout = "";

runningProcess.stdout.on("data", data => {
stdout += data;
});

return new Promise(resolve => {
runningProcess.once("exit", () => resolve(stdout));
});
}

describe("bin/eslint.js", () => {
const forkedProcesses = new Set();

/**
* Forks the process to run an instance of ESLint.
* @param {string[]} [args] An array of arguments
* @param {Object} [options] An object containing options for the resulting child process
* @returns {ChildProcess} The resulting child process
*/
function runESLint(args, options) {
const newProcess = childProcess.fork(EXECUTABLE_PATH, args, Object.assign({silent: true}, options));

forkedProcesses.add(newProcess);
return newProcess;
}

describe("reading from stdin", () => {
it("has exit code 0 if no linting errors are reported", () => {
const child = runESLint(["--stdin", "--no-eslintrc"]);

child.stdin.write("var foo = bar;\n");
child.stdin.end();
return assertExitCode(child, 0);
});

it("has exit code 1 if a syntax error is thrown", () => {
const child = runESLint(["--stdin", "--no-eslintrc"]);

child.stdin.write("This is not valid JS syntax.\n");
child.stdin.end();
return assertExitCode(child, 1);
});

it("has exit code 1 if a linting error occurs", () => {
const child = runESLint(["--stdin", "--no-eslintrc", "--rule", "semi:2"]);

child.stdin.write("var foo = bar // <-- no semicolon\n");
child.stdin.end();
return assertExitCode(child, 1);
});

it("gives a detailed error message if no config file is found", () => {
const child = runESLint(["--stdin"], {cwd: "/"}); // Assumes the root directory has no .eslintrc file

const exitCodePromise = assertExitCode(child, 1);
const stdoutPromise = getStdout(child).then(stdout => {
assert.match(stdout, /ESLint couldn't find a configuration file/);
});

child.stdin.write("var foo = bar\n");
child.stdin.end();

return Promise.all([exitCodePromise, stdoutPromise]);
});

});

afterEach(() => {

// Clean up all the processes after every test.
forkedProcesses.forEach(child => child.kill());
forkedProcesses.clear();
});

// TODO (not-an-aardvark): Add tests for non-stdin functionality
});

0 comments on commit 85b8714

Please sign in to comment.