diff --git a/lib/index.js b/lib/index.js index 13c31bc..c666898 100644 --- a/lib/index.js +++ b/lib/index.js @@ -6,9 +6,12 @@ const defaultsDeep = require('lodash.defaultsdeep'); const md5Hex = require('md5-hex'); const stringify = require('json-stable-stringify'); const path = require('path'); +const concat = require('broccoli-concat'); const isString = require('./is-string'); const getResultSeverity = require('./get-result-severity'); +const testGenerators = require('./test-generators'); +const testGeneratorNames = Object.keys(testGenerators); function resolveInputDirectory(inputNode) { if (typeof inputNode === 'string') { @@ -68,9 +71,10 @@ function EslintValidationFilter(inputNode, options) { this.eslintrc = resolveInputDirectory(inputNode); if (isString(this.internalOptions.testGenerator)) { - const testGenerators = require('./test-generators'); - this.testGenerator = testGenerators[this.internalOptions.testGenerator]; + if (this.internalOptions.group && this.testGenerator) { + this.testGenerator = this.testGenerator.testOnly; + } if (!this.testGenerator) { throw new Error(`Could not find '${this.internalOptions.testGenerator}' test generator.`); } @@ -191,5 +195,29 @@ EslintValidationFilter.prototype.postProcess = function postProcess(results /* , * @experimental */ EslintValidationFilter.create = function(inputNode, options) { - return new EslintValidationFilter(inputNode, options); + options = options || {}; + + if (!options.group) { + return new EslintValidationFilter(inputNode, options); + } + + if (typeof options.testGenerator !== 'string' || testGeneratorNames.indexOf(options.testGenerator) === -1) { + throw new Error(`The "group" options can only be used with a "testGenerator" option of: ${testGeneratorNames}`); + } + + let testGenerator = testGenerators[options.testGenerator]; + + let header = testGenerator.header(options.group); + let footer = testGenerator.footer(); + + let eslint = new EslintValidationFilter(inputNode, options); + + return concat(eslint, { + outputFile: `/${options.group}.lint-test.js`, + header, + inputFiles: ['**/*.lint-test.js'], + footer, + sourceMapConfig: { enabled: false }, + allowNone: true, + }); }; diff --git a/package.json b/package.json index fbbf223..da87e25 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ }, "homepage": "https://github.com/ember-cli/broccoli-lint-eslint", "dependencies": { + "broccoli-concat": "^3.2.2", "broccoli-persistent-filter": "^1.2.0", "eslint": "^3.0.0", "js-string-escape": "^1.0.1", diff --git a/test/eslint-test.js b/test/eslint-test.js index 715b74f..d869a88 100644 --- a/test/eslint-test.js +++ b/test/eslint-test.js @@ -208,6 +208,67 @@ describe('broccoli-lint-eslint', function() { })); }); + describe('group', function() { + it('qunit: generates a single QUnit module', co.wrap(function *() { + input.write({ + '.eslintrc.js': `module.exports = { rules: { 'no-console': 'error', 'no-unused-vars': 'warn' } };\n`, + 'a.js': `console.log('foo');\n`, + 'b.js': `var foo = 5;\n`, + }); + + output = createBuilder(eslint.create(input.path(), { console, testGenerator: 'qunit', group: 'app' })); + + yield output.build(); + + let result = output.read(); + expect(Object.keys(result)).to.deep.equal(['app.lint-test.js']); + expect(result['app.lint-test.js'].trim()).to.equal([ + `QUnit.module('ESLint | app');`, + ``, + `QUnit.test('a.js', function(assert) {`, + ` assert.expect(1);`, + ` assert.ok(false, 'a.js should pass ESLint\\n\\n1:1 - Unexpected console statement. (no-console)');`, + `});`, + ``, + `QUnit.test('b.js', function(assert) {`, + ` assert.expect(1);`, + ` assert.ok(true, 'b.js should pass ESLint\\n\\n1:5 - \\'foo\\' is assigned a value but never used. (no-unused-vars)');`, + `});`, + ].join('\n')); + })); + + it('mocha: generates a single Mocha test suite', co.wrap(function *() { + input.write({ + '.eslintrc.js': `module.exports = { rules: { 'no-console': 'error', 'no-unused-vars': 'warn' } };\n`, + 'a.js': `console.log('foo');\n`, + 'b.js': `var foo = 5;\n`, + }); + + output = createBuilder(eslint.create(input.path(), { console, testGenerator: 'mocha', group: 'app' })); + + yield output.build(); + + let result = output.read(); + expect(Object.keys(result)).to.deep.equal(['app.lint-test.js']); + expect(result['app.lint-test.js'].trim()).to.equal([ + `describe('ESLint | app', function() {`, + ``, + ` it('a.js', function() {`, + ` // ESLint failed`, + ` var error = new chai.AssertionError('a.js should pass ESLint\\n\\n1:1 - Unexpected console statement. (no-console)');`, + ` error.stack = undefined;`, + ` throw error;`, + ` });`, + ``, + ` it('b.js', function() {`, + ` // ESLint passed`, + ` });`, + ``, + `});`, + ].join('\n')); + })); + }); + describe('throwOnError', function() { it('throw an error for the first encountered error', co.wrap(function *() { input.write({