diff --git a/.gitignore b/.gitignore index da23d0d..f96bd9c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,11 @@ build/Release # Deployed apps should consider commenting this line out: # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git node_modules + + +# Webstorm IDE metadata directory +.idea + +# test report files +test/report/*.xml* +test/report/*.log \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 4d7e181..55ea8fa 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,15 +1,17 @@ "use strict"; var gulp = require('gulp'), - mochaStream = require('./lib').mochaStream, - SpawnMocha = require('./lib').SpawnMocha, - _ = require('lodash'), - through = require('through'), - Q = require('q'), - runSequence = Q.denodeify(require('run-sequence')), - assert = require('assert'), - File = require('vinyl'), - from = require('from'); + mochaStream = require('./lib').mochaStream, + SpawnMocha = require('./lib').SpawnMocha, + _ = require('lodash'), + through = require('through'), + Q = require('q'), + runSequence = Q.denodeify(require('run-sequence')), + assert = require('assert'), + File = require('vinyl'), + from = require('from'), + path = require('path'), + glob = require('glob'); function customMocha(opts) { opts = opts || {}; @@ -129,6 +131,60 @@ gulp.task('test-live-output-with-prepend', function() { .pipe(mocha); }); +gulp.task('test-mocha-opts-override', function (cb) { + function mochaIteration(opts, overrides, files, cb) { + opts = opts || {}; + var spawnMocha = new SpawnMocha(opts); + overrides.forEach(function (override) { + spawnMocha.add(files, override); + }); + var errors = []; + spawnMocha.on('error', function (err) { + console.error(err.toString()); + errors.push(err); + }).on('end', function () { + if (errors.length > 0) { + console.error('ERROR SUMMARY: '); + _(errors).each(function (err) { + console.error(err); + console.error(err.stack); + }).value(); + return cb(new Error('some tests failed')); + } + cb(null); + }); + } + + function setEnv(envs) { + var env = process.env; + env = _.clone(env); + env = _.merge(env, envs, {JUNIT_REPORT_PATH: path.resolve(__dirname, 'test/report/report.xml')}); + return env; + } + + var opts = { + concurrency: 3, + flags: {R: 'mocha-jenkins-reporter'} + }; + var overrides = [{ + env: setEnv({NODE_ENV: 'groupa'}), + flags: {grep: "@groupA@"} + }, { + env: setEnv({NODE_ENV: 'groupb'}), + flags: {grep: "@groupB@"} + }, { + env: setEnv({NODE_ENV: 'groupc'}), + flags: {grep: "@groupC@"} + }]; + + glob('test/group/*-specs.js', function (err, files) { + if (err) { + return cb(err); + } + console.log('files', files); + mochaIteration(opts, overrides, files, cb); + }); +}); gulp.task('test', function() { return runSequence( @@ -137,6 +193,7 @@ gulp.task('test', function() { 'test-live-output', 'test-live-output-with-prepend', 'test-live-output-with-file', - 'test-with-file' + 'test-with-file', + 'test-mocha-opts-override' ); }); diff --git a/lib/index.js b/lib/index.js index cfca208..8bfbd2d 100644 --- a/lib/index.js +++ b/lib/index.js @@ -2,22 +2,22 @@ // Module Requirements var _ = require('lodash'), - proc = require('child_process'), - join = require('path').join, - async = require('async'), - util = require('util'), - EventEmitter = require('events').EventEmitter, - streamBuffers = require("stream-buffers"), - through = require('through'), - split = require('split'), - fs = require('fs'); + proc = require('child_process'), + join = require('path').join, + async = require('async'), + util = require('util'), + EventEmitter = require('events').EventEmitter, + streamBuffers = require("stream-buffers"), + through = require('through'), + split = require('split'), + fs = require('fs'); require('colors'); function newStreamBuffer() { var stream = new streamBuffers.WritableStreamBuffer({ - initialSize: (25 * 1024), - incrementAmount: (10 * 1024) + initialSize: (25 * 1024), + incrementAmount: (10 * 1024) }); return stream; } @@ -30,15 +30,16 @@ var SpawnMocha = function (opts) { }); var queue = async.queue(function (task, done) { // Setup + var overrideOpts = _.merge(_.clone(opts), task.overrideOpts); var bin = _.isFunction(opts.bin) ? opts.bin() : opts.bin || - join(__dirname, '..', 'node_modules', '.bin', 'mocha'); - var env = _.isFunction(opts.env) ? opts.env() : opts.env || process.env; + join(__dirname, '..', 'node_modules', '.bin', 'mocha'); + var env = _.isFunction(overrideOpts.env) ? overrideOpts.env() : overrideOpts.env || process.env; env = _.clone(env); // Generate arguments var args = []; - _(opts.flags).each(function (val, key) { - if(_.isFunction(val)) val = val(); + _(overrideOpts.flags).each(function (val, key) { + if (_.isFunction(val)) val = val(); args.push((key.length > 1 ? '--' : '-') + key); if (_.isString(val) || _.isNumber(val)) { args.push(val); @@ -47,27 +48,26 @@ var SpawnMocha = function (opts) { var stdout = newStreamBuffer(); var stderr = newStreamBuffer(); - var fsStream = opts.fileOutput ? - fs.createWriteStream(opts.fileOutput, { flags: 'a', encoding: 'utf8' }) : null; + var fsStream = overrideOpts.fileOutput ? + fs.createWriteStream(overrideOpts.fileOutput, {flags: 'a', encoding: 'utf8'}) : null; // Split xunit test report in several files if required - if(env.JUNIT_REPORT_PATH) { - env.JUNIT_REPORT_PATH = env.JUNIT_REPORT_PATH + '.' + task.taskNum; + if (env.JUNIT_REPORT_PATH) { + env.JUNIT_REPORT_PATH = env.JUNIT_REPORT_PATH.replace(/xml$/, task.taskNum + '.xml'); } - // Execute Mocha var child = proc.spawn(bin, args.concat(task.files), {env: env}); if (opts.liveOutput) { child.stdout.pipe(split()) .on('data', function (line) { - console.log((opts.liveOutputPrepend || '') + line); + console.log((overrideOpts.liveOutputPrepend || '') + line); }); child.stderr.pipe(split()) .on('data', function (line) { - console.error((opts.liveOutputPrepend || '') + line); + console.error((overrideOpts.liveOutputPrepend || '') + line); }); - if(fsStream) { + if (fsStream) { child.stdout.pipe(fsStream); child.stderr.pipe(fsStream); } @@ -77,25 +77,27 @@ var SpawnMocha = function (opts) { } // When done... - child.on('close', function(errCode) { - if(stdout.size()) { + child.on('close', function (errCode) { + if (stdout.size()) { var contentOut = stdout.getContentsAsString("utf8"); console.log(contentOut); - if(fsStream) { + if (fsStream) { fsStream.write(contentOut + '\n', 'utf8'); } } - if(stderr.size()) { + if (stderr.size()) { var contentErr = stdout.getContentsAsString("utf8"); console.error(contentErr); - if(fsStream) { + if (fsStream) { fsStream.write(contentErr + '\n', 'utf8'); } } - if(fsStream) { fsStream.close(); } + if (fsStream) { + fsStream.close(); + } var err = null; - if(errCode && opts.errorSummary) { + if (errCode && opts.errorSummary) { err = new Error('Error for files: ' + task.files.join(', ')); err.files = task.files; err.stderr = stderr.size() ? stderr.getContentsAsString("utf8") : ''; @@ -105,25 +107,26 @@ var SpawnMocha = function (opts) { }); }, opts.concurrency || 1); - queue.drain = function() { + queue.drain = function () { _this.emit('end'); }; var taskNum = 0; - this.add = function(files) { - taskNum ++; + this.add = function (files, overrideOpts) { + taskNum++; if (!_.isArray(files)) { files = [files]; } - var task = {taskNum: taskNum, files: files}; - queue.push(task, function(err) { - if(err){ + var task = {taskNum: taskNum, files: files, overrideOpts: overrideOpts || {}}; + queue.push(task, function (err) { + if (err) { _this.emit('error', err, files); } }); }; }; + util.inherits(SpawnMocha, EventEmitter); var mochaStream = function mocha(opts) { diff --git a/package.json b/package.json index 7716d77..f969368 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,9 @@ "devDependencies": { "fixture-stdout": "^0.2.1", "from": "^0.1.3", + "glob": "^5.0.5", "gulp": "^3.8.8", + "mocha-jenkins-reporter": "^0.1.8", "q": "^1.1.2", "run-sequence": "^1.0.1", "vinyl": "^0.4.3" diff --git a/test/group/a-group-specs.js b/test/group/a-group-specs.js new file mode 100644 index 0000000..d51495a --- /dev/null +++ b/test/group/a-group-specs.js @@ -0,0 +1,27 @@ +"use strict"; +/* global describe, it */ + +describe('@suiteA@groupA@', function() { + this.timeout(3000); + it('should work, NODE_ENV: ' + process.env.NODE_ENV, function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteA@groupB@', function() { + this.timeout(3000); + it('should work, NODE_ENV: ' + process.env.NODE_ENV, function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteA@groupC@', function() { + this.timeout(3000); + it('should work, NODE_ENV: ' + process.env.NODE_ENV, function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); \ No newline at end of file diff --git a/test/group/b-group-specs.js b/test/group/b-group-specs.js new file mode 100644 index 0000000..f36a6d6 --- /dev/null +++ b/test/group/b-group-specs.js @@ -0,0 +1,27 @@ +"use strict"; +/* global describe, it */ + +describe('@suiteB@groupA@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteB@groupB@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteB@groupC@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); \ No newline at end of file diff --git a/test/group/c-group-specs.js b/test/group/c-group-specs.js new file mode 100644 index 0000000..1db2525 --- /dev/null +++ b/test/group/c-group-specs.js @@ -0,0 +1,27 @@ +"use strict"; +/* global describe, it */ + +describe('@suiteC@groupA@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteC@groupB@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); +describe('@suiteC@groupC@', function() { + this.timeout(3000); + it('should work', function(done) { + setTimeout(function() { + done(); + }, 2000); + }); +}); \ No newline at end of file diff --git a/test/report/reports.md b/test/report/reports.md new file mode 100644 index 0000000..ab465b4 --- /dev/null +++ b/test/report/reports.md @@ -0,0 +1,2 @@ +# reports +This directory for .log, .xml, etc reports \ No newline at end of file