Skip to content

Commit

Permalink
Accept non-string inputTrees
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Iaconis committed Mar 29, 2016
1 parent 5017db2 commit 3905375
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 30 deletions.
41 changes: 34 additions & 7 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const Filter = require('broccoli-filter');
const CLIEngine = require('eslint').CLIEngine;
const path = require('path');

/**
* Calculates the severity of a eslint.linter.verify result
Expand Down Expand Up @@ -57,27 +58,52 @@ function filterAllIgnoredFileMessages(result) {
return resultOutput;
}

function resolveInputDirectory(inputNode) {
if (typeof inputNode === 'string') {
return inputNode;
}

// eslint-disable-next-line no-underscore-dangle
const nodeInfo = inputNode.__broccoliGetInfo__();

if (nodeInfo.nodeType === 'source') {
return nodeInfo.sourceDirectory;
}

if (nodeInfo.inputNodes.length > 1) {
// eslint-disable-next-line max-len
throw new Error('EslintValidationFilter can only handle one:* broccoli nodes, but part of the given input pipeline is a many:* node. (broccoli-merge-trees is an example of a many:* node) Please perform many:* operations after linting.');
}

return resolveInputDirectory(nodeInfo.inputNodes[0]);
}

/**
* Uses the content of each file in a given tree and runs eslint validation on it.
* @param {Object} inputTree Tree from broccoli.makeTree
* @param {Object} inputNode Tree from broccoli.makeTree
* @param {{config: String, rulesdir: String, format: String}} options Filter options
* @returns {EslintValidationFilter} Filter obconfig @constructor
*/
function EslintValidationFilter(inputTree, options) {
function EslintValidationFilter(inputNode, options) {
if (!(this instanceof EslintValidationFilter)) {
return new EslintValidationFilter(inputTree, options);
return new EslintValidationFilter(inputNode, options);
}
this.options = options || {};
this.eslintOptions = options.options || {};
// call base class constructor
Filter.call(this, inputTree);
Filter.call(this, inputNode);

// set formatter
this.formatter = require(this.options.format || 'eslint/lib/formatters/stylish'); // eslint-disable-line global-require
if (typeof this.options.format === 'function') {
this.formatter = this.options.format;
} else {
// eslint-disable-next-line global-require
this.formatter = require(this.options.format || 'eslint/lib/formatters/stylish');
}

this.cli = new CLIEngine(this.eslintOptions);

this.eslintrc = inputTree;
this.eslintrc = resolveInputDirectory(inputNode);

this.testGenerator = options.testGenerator;
if (this.testGenerator) {
Expand All @@ -95,7 +121,8 @@ EslintValidationFilter.prototype.processString = function processString(content,
'use strict'; // eslint-disable-line strict

// verify file content
const output = this.cli.executeOnText(content, this.eslintrc + '/' + relativePath);
const configPath = path.join(this.eslintrc, path.basename(relativePath));
const output = this.cli.executeOnText(content, configPath);
const filteredOutput = filterAllIgnoredFileMessages(output);

// if verification has result
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@
"broccoli": "^0.16.9",
"broccoli-cli": "^1.0.0",
"broccoli-merge-trees": "^1.1.1",
"broccoli-source": "^1.1.0",
"broccoli-stew": "^1.2.0",
"chai": "^3.5.0",
"eslint-config-nightmare-mode": "^2.3.0",
"mocha": "^2.2.4",
Expand Down
19 changes: 7 additions & 12 deletions test/helpers/run-eslint.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ const eslint = require('../../index');
module.exports = function runEslint(path, _options) {
const options = _options || {};
const buildLog = [];
const consoleLog = console.log;

// stub console.log so we can get the formatter's output
console.log = function appendToBuildLog(...args) {
const text = args.join(' ');

buildLog.push(text);
};

// default options
options.format = options.format || 'eslint/lib/formatters/compact';
// eslint-disable-next-line global-require, newline-after-var
const formatter = require(options.format || 'eslint/lib/formatters/compact');
options.format = function spyFormatter(results) {
buildLog.push(formatter(results));
// prevent console spew
return '';
};
options.options = options.options || {};
options.options.ignore = options.options.ignore || false;

Expand All @@ -26,9 +24,6 @@ module.exports = function runEslint(path, _options) {

promise.finally(function builderCleanup() {
builder.cleanup();

// restore the original console.log
console.log = consoleLog;
});

return promise;
Expand Down
40 changes: 29 additions & 11 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
/* eslint-disable no-unused-expressions */
const fs = require('fs');
const expect = require('chai').expect;
const stew = require('broccoli-stew');
const mv = stew.mv;
const UnwatchedDir = require('broccoli-source').UnwatchedDir;
const MergeTrees = require('broccoli-merge-trees');
const runEslint = require('./helpers/run-eslint');
const FIXTURES = 'test/fixture';
const CAMELCASE = '(camelcase)';
Expand All @@ -9,18 +14,22 @@ const DOUBLEQUOTE = 'Strings must use doublequote.';
const FILEPATH = 'fixture/1.js';

describe('EslintValidationFilter', function describeEslintValidationFilter() {
it('should report errors', function shouldReportErrors() {
// lint test fixtures
const promise = runEslint(FIXTURES);
function shouldReportErrors(inputTree) {
return function _shouldReportErrors() {
// lint test fixtures
const promise = runEslint(inputTree);

return promise.then(function assertLinting({buildLog}) {
expect(buildLog, 'Used eslint validation').to.have.string(CAMELCASE);
expect(buildLog, 'Shows filepath').to.have.string(FILEPATH);
expect(buildLog, 'Used relative config - console not allowed').to.have.string(CONSOLE);
expect(buildLog, 'Used relative config - single quotes').to.not.have.string(DOUBLEQUOTE);
expect(buildLog, 'No custom rules defined').to.not.have.string(CUSTOM_RULES);
});
});
return promise.then(function assertLinting({buildLog}) {
expect(buildLog, 'Used eslint validation').to.have.string(CAMELCASE);
expect(buildLog, 'Shows filepath').to.have.string(FILEPATH);
expect(buildLog, 'Used relative config - console not allowed').to.have.string(CONSOLE);
expect(buildLog, 'Used relative config - single quotes').to.not.have.string(DOUBLEQUOTE);
expect(buildLog, 'No custom rules defined').to.not.have.string(CUSTOM_RULES);
});
};
}

it('should report errors', shouldReportErrors(FIXTURES));

it('should accept rule paths', function shouldAcceptRulePaths() {
// lint test fixtures using a custom rule
Expand Down Expand Up @@ -62,4 +71,13 @@ describe('EslintValidationFilter', function describeEslintValidationFilter() {
expect(content, 'Used the testGenerator').to.equal('test-content');
});
});

// specify test fixtures via a broccoli node
it('should accept a node as the input', shouldReportErrors(mv(new UnwatchedDir(FIXTURES), 'foobar/fixture')));

it('should not accept a many:* node as the input', function shouldNotAcceptManyStarNode() {
expect(() => {
runEslint(new MergeTrees([FIXTURES, 'lib']));
}, 'Should throw descriptive error').to.throw('many:*');
});
});

0 comments on commit 3905375

Please sign in to comment.