284 lines
7.8 KiB
JavaScript
284 lines
7.8 KiB
JavaScript
var fs = require('fs');
|
|
var path = require('path');
|
|
var util = require('util');
|
|
var mkpath = require('mkpath');
|
|
var Logger = require('../util/logger.js');
|
|
var colors = Logger.colors;
|
|
var format = util.format;
|
|
var Utils = require('../util/utils.js');
|
|
var Q = require('q');
|
|
|
|
var Reporter = module.exports = function(globalResults, testResults, globalStartTime, options) {
|
|
this.globalResults = globalResults;
|
|
this.testResults = testResults;
|
|
this.globalStartTime = globalStartTime;
|
|
this.options = options;
|
|
this.reporter = options.reporter || 'junit';
|
|
};
|
|
|
|
var printf = function() {
|
|
console.log(format.apply(null, arguments));
|
|
};
|
|
|
|
/**
|
|
* @static
|
|
* @param err
|
|
* @param testname
|
|
* @param time
|
|
* @return {string}
|
|
*/
|
|
Reporter.getTestOutput = function (err, testname, time) {
|
|
var symbol;
|
|
if (Utils.isErrorObject(err)) {
|
|
symbol = Logger.colors.red(Utils.symbols.fail);
|
|
testname = Logger.colors.red(testname);
|
|
} else {
|
|
symbol = Logger.colors.green(Utils.symbols.ok);
|
|
}
|
|
|
|
var args = [
|
|
'%s %s', symbol, testname
|
|
];
|
|
|
|
if (time > 20) {
|
|
args[0] += ' %s';
|
|
args.push(Logger.colors.yellow(Utils.format('(%s)', Utils.formatElapsedTime(time))));
|
|
}
|
|
|
|
return Utils.format.apply(null, args);
|
|
};
|
|
|
|
Reporter.printAssertions = function(test) {
|
|
test.assertions.forEach(function(a) {
|
|
if (a.failure !== false) {
|
|
var message = a.stackTrace.split('\n');
|
|
message.unshift(a.fullMsg);
|
|
Utils.showStackTrace(message.join('\n'));
|
|
}
|
|
});
|
|
|
|
if (test.stackTrace) {
|
|
Utils.showStackTrace(test.stackTrace);
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.get = function() {
|
|
var fileName = __dirname + '/reporters/' + this.reporter + '.js';
|
|
|
|
if (fs.existsSync(fileName)) {
|
|
return require(fileName);
|
|
}
|
|
|
|
fileName = path.resolve(this.reporter);
|
|
|
|
if (fs.existsSync(fileName)) {
|
|
var reporter = require(fileName);
|
|
if (typeof reporter.write == 'function') {
|
|
return reporter;
|
|
}
|
|
throw new Error('The reporter module must have a public `write` method defined.');
|
|
}
|
|
|
|
throw new Error('The reporter file name cannot be resolved. Using path: ' + fileName);
|
|
};
|
|
|
|
/**
|
|
* @param {object} globals
|
|
* @returns {function}
|
|
*/
|
|
Reporter.prototype.globalReporter = function(globals) {
|
|
var reporterFn = Utils.checkFunction('reporter', globals) || function() {};
|
|
return Utils.makeFnAsync(2, reporterFn, globals);
|
|
};
|
|
|
|
Reporter.prototype.isDisabled = function() {
|
|
return this.options.output_folder === false;
|
|
};
|
|
|
|
Reporter.prototype.createFolder = function(cb) {
|
|
if (this.isDisabled()) {
|
|
cb(null);
|
|
} else {
|
|
mkpath(this.options.output_folder, cb);
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.save = function() {
|
|
var self = this;
|
|
var deferred = Q.defer();
|
|
this.createFolder(function(err) {
|
|
if (self.isDisabled()) {
|
|
deferred.resolve();
|
|
} else {
|
|
if (err) {
|
|
deferred.reject(err);
|
|
return;
|
|
}
|
|
|
|
var reporter = self.get();
|
|
|
|
reporter.write(self.globalResults, self.options, function(err) {
|
|
if (err) {
|
|
console.log(colors.yellow(format('Warning: Failed to save report file to folder: %s', self.options.output_folder)));
|
|
console.log(err.stack);
|
|
}
|
|
deferred.resolve(err);
|
|
});
|
|
}
|
|
});
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
Reporter.prototype.printTotalResults = function() {
|
|
var elapsedTime = new Date().getTime() - this.globalStartTime;
|
|
process.stdout.write('\n');
|
|
|
|
if (this.testsFailed()) {
|
|
var countMessage = this.getTestsFailedMessage();
|
|
|
|
console.log(colors.light_red(' _________________________________________________'));
|
|
console.log(
|
|
format('\n %s', colors.light_red('TEST FAILURE:')),
|
|
countMessage,
|
|
format('(%s)', Utils.formatElapsedTime(elapsedTime))
|
|
);
|
|
|
|
|
|
this.printFailureSummary();
|
|
console.log('');
|
|
} else {
|
|
if (!this.shouldShowSummary()) {
|
|
return;
|
|
}
|
|
|
|
var message = this.getTestsPassedMessage();
|
|
printf('%s (%s)', message, Utils.formatElapsedTime(elapsedTime));
|
|
}
|
|
};
|
|
|
|
Reporter.prototype.testsFailed = function() {
|
|
return Object.keys(this.globalResults.modules).some(function(moduleKey) {
|
|
return this.globalResults.modules[moduleKey].failures > 0 || this.globalResults.modules[moduleKey].errors > 0;
|
|
}.bind(this));
|
|
};
|
|
|
|
Reporter.prototype.shouldShowSummary = function() {
|
|
var modules = Object.keys(this.globalResults.modules);
|
|
if (modules.length > 1) {
|
|
return true;
|
|
}
|
|
|
|
if (modules.length <= 0) {
|
|
return false;
|
|
}
|
|
|
|
return Object.keys(this.globalResults.modules[modules[0]].completed).length > 1;
|
|
};
|
|
|
|
Reporter.prototype.hasAssertionCount = function() {
|
|
return Object.keys(this.globalResults.modules).length > 0 &&
|
|
(this.globalResults.failed > 0 || this.globalResults.passed > 0);
|
|
};
|
|
|
|
Reporter.prototype.getTestsPassedMessage = function() {
|
|
var hasCount = this.hasAssertionCount();
|
|
var message;
|
|
var count;
|
|
|
|
if (hasCount) {
|
|
count = this.globalResults.passed;
|
|
message = colors.green(format('OK. %s %s passed.', count, (count > 1 ? ' total assertions' : ' assertion')));
|
|
} else {
|
|
count = this.getTotalTestsCount();
|
|
message = format('%s tests passed.', colors.green('OK. ' + count));
|
|
}
|
|
|
|
return message;
|
|
};
|
|
|
|
Reporter.prototype.getTotalTestsCount = function() {
|
|
|
|
var module;
|
|
|
|
return Object.keys(this.globalResults.modules).reduce(function(count, moduleKey) {
|
|
module = this.globalResults.modules[moduleKey];
|
|
return count + module.tests - module.skipped.length;
|
|
}.bind(this), 0);
|
|
};
|
|
|
|
Reporter.prototype.getTestsFailedMessage = function() {
|
|
var hasCount = this.hasAssertionCount();
|
|
if (!hasCount && this.testResults.errmessages === 0) {
|
|
return '';
|
|
}
|
|
var errorsMsg = '';
|
|
var failedMsg = 'assertions';
|
|
var passedMsg = format('%s passed', colors.green(this.globalResults.passed));
|
|
|
|
if (!this.options.start_session) {
|
|
failedMsg = 'tests';
|
|
var passedCount = Math.max(0, this.getTotalTestsCount() - this.globalResults.failed);
|
|
passedMsg = format('%s passed', colors.green(passedCount));
|
|
}
|
|
|
|
var skipped = '';
|
|
if (this.testResults.skipped) {
|
|
skipped = format(' and %s skipped', colors.cyan(this.testResults.skipped));
|
|
}
|
|
|
|
if (this.globalResults.errors) {
|
|
var suffix = this.globalResults.errors > 1 ? 's' : '';
|
|
errorsMsg += format('%s error%s during execution, ', colors.red(this.globalResults.errors), suffix);
|
|
}
|
|
|
|
return format('%s %s %s failed, %s%s.', errorsMsg, colors.red(this.globalResults.failed), failedMsg, passedMsg, skipped);
|
|
};
|
|
|
|
Reporter.prototype.printFailureSummary = function() {
|
|
Object.keys(this.globalResults.modules).forEach(function(moduleKey) {
|
|
var testSuite = this.globalResults.modules[moduleKey];
|
|
if (testSuite.failures > 0 || testSuite.errors > 0) {
|
|
|
|
console.log('\n' + colors.red(format(' %s %s', Utils.symbols.fail, moduleKey)));
|
|
|
|
Object.keys(testSuite.completed).forEach(function(testcase) {
|
|
var test = testSuite.completed[testcase];
|
|
if (test.failed > 0 || test.errors > 0) {
|
|
printf('\n - %s %s', testcase, colors.yellow('(' + Utils.formatElapsedTime(test.timeMs) + ')'));
|
|
|
|
if (test.assertions.length > 0 && this.options.start_session) {
|
|
Reporter.printAssertions(test);
|
|
} else if (test.stackTrace) {
|
|
Utils.showStackTrace(test.stackTrace);
|
|
}
|
|
}
|
|
}.bind(this));
|
|
|
|
if (Array.isArray(testSuite.errmessages)) {
|
|
testSuite.errmessages.forEach(function(err) {
|
|
console.log('');
|
|
Utils.showStackTrace(err);
|
|
console.log('');
|
|
});
|
|
}
|
|
|
|
|
|
if (testSuite.skipped.length > 0) {
|
|
console.log(colors.cyan(' SKIPPED:'));
|
|
testSuite.skipped.forEach(function(testcase) {
|
|
printf(' - %s', testcase);
|
|
});
|
|
}
|
|
}
|
|
}.bind(this));
|
|
|
|
if (Array.isArray(this.globalResults.errmessages)) {
|
|
this.globalResults.errmessages.forEach(function(err) {
|
|
console.log('');
|
|
Utils.showStackTrace(err);
|
|
console.log('');
|
|
}.bind(this));
|
|
}
|
|
};
|