UNPKG

it

Version:

A testing framework for node

222 lines (191 loc) 7.83 kB
"use strict"; var _ = require("../extended"), style = _.style, format = _.format; _.declare({ instance: { numActions: 0, constructor: function () { this.errors = []; _.bindAll(this, ["startTests", "testError", "_testError", "printFinalSummary", "listenTest", "listenAction", "testRun", "testEnd", "testsDone", "actionError", "_actionError", "actionSuccess", "actionPending", "actionSkipped", "printDuplicateActions"]); _.bus.on("start", this.startTests); _.bus.on("error", this._testError); _.bus.on("done", this.testsDone); _.bus.on("test", this.listenTest); _.bus.on("printDuplicateActions", this.printDuplicateActions); }, listenTest: function listenTest(test) { test.on("test", this.listenTest); test.on("action", this.listenAction); test.on("run", this.testRun); test.on("error", this._testError); test.on("done", this.testEnd); }, listenAction: function listenAction(action) { this.numActions++; action.on("error", this._actionError); action.on("success", this.actionSuccess); action.on("pending", this.actionPending); action.on("skipped", this.actionSkipped); }, formatMs: function formatMs(ms) { return format("% 6ds", ms / 1000); }, startTests: function () { }, testRun: function printTitle() { }, actionSuccess: function printSuccess() { }, actionPending: function printPending() { }, actionSkipped: function printSkipped() { }, actionError: function actionError() { }, testError: function printError(test) { }, printDuplicateActions: function printDuplicateActions(duplicateActionErrors) { this._static.list(duplicateActionErrors); }, _actionError: function printError(action) { var error = action.get("summary").error; this.errors.push({error: error, test: action}); return this.actionError.apply(this, arguments); }, _testError: function _testError(test) { this.errors.push({error: test.error, test: test}); return this.testError.apply(this, arguments); }, processSummary: function processSummary(summary) { if (summary.hasOwnProperty("summaries")) { summary = summary.summaries; } var errCount = 0, successCount = 0, skippedCount = 0, pendingCount = 0, pendingActions = [], errors = {}, duration = 0; _(summary).forEach(function (sum) { duration += sum.duration; }); (function total(summary) { _(summary).forEach(function (sum, i) { if (sum.hasOwnProperty("summaries")) { total(sum.summaries); } else if (sum.status === "passed") { successCount++; } else if (sum.status === "pending") { pendingCount++; pendingActions.push(sum.parentFullName + ": " + sum.description); } else if (sum.status === "skipped") { skippedCount++; } else { errors[i] = sum.error; errCount++; } }); })(summary); return { totalCount: this.numActions, errCount: errCount, successCount: successCount, skippedCount: skippedCount, pendingCount: pendingCount, pendingActions: pendingActions, errors: errors, duration: duration }; }, testEnd: function () { }, testsDone: function (tests) { this.printFinalSummary(tests); }, returnCode: function returnCode(stats) { return this.errors.length || stats.errCount || stats.totalCount !== (stats.successCount + stats.skippedCount) ? 1 : 0; }, printFinalSummary: function (test) { this.testEnd.apply(this, arguments); console.log("\nSummary"); var stats = this.processSummary(test.summary || test.get("summary")); var totalCount = stats.totalCount, errCount = stats.errCount, successCount = stats.successCount, pendingCount = stats.pendingCount, skippedCount = stats.skippedCount, duration = stats.duration; console.log(format("Finished in %s", this.formatMs(duration))); var out = [ totalCount + " total", successCount + " passed", errCount + " failed", skippedCount + " skipped", pendingCount + " pending" ]; var color = 'green'; if (errCount > 0 || pendingCount > 0) { color = 'red'; } else if (skippedCount > 0) { color = 'cyan'; } console.log(style(out.join(", "), color)); this._static.list(this.errors); this._static.listPending(stats.pendingActions); return this.returnCode(stats); } }, "static": { reporters: {}, registerType: function (type) { type = type.toLowerCase(); if (!this.reporters.hasOwnProperty(type)) { this.reporters[type] = this; } return this; }, getInstance: function (type, args) { type = type.toLowerCase(); if (this.reporters.hasOwnProperty(type)) { return new this.reporters[type](args || {}); } else { throw new Error("Invalid Reporter type"); } }, listPending: function (pendingActions) { if (pendingActions.length) { console.log("" + pendingActions.length + " pending actions"); var more = false; if (pendingActions.length > 10) { pendingActions = pendingActions.slice(0, 10); more = true; } pendingActions.forEach(function (name) { console.log(style('\t%s', ["red", "bold"]), name); }); if (more) { console.log(style('\t...', ["red", "bold"])); } } }, list: function (errors) { console.log(); errors.forEach(function (test, i) { // format var fmt = ' %s.%d) %s:\n' + style(' %s', "red") + style('\n%s\n', ["red", "bold"]); // msg var errs = test.error; _((_.isArray(errs) ? errs : [errs])).forEach(function (err, j) { if (err) { var message = err.message || '', stack = err.stack || message, index = stack.indexOf(message) + message.length, msg = stack.slice(0, index); // indent stack trace without msg stack = stack.slice(index ? index + 1 : index) .replace(/^/gm, ' '); console.log(fmt, (i + 1), j, test.test.get("fullName"), msg, stack); } }); }); } } }).as(module);