assert: function(pass, message, actual, expected) { if (this.mode === Ct.PLANNING_MODE) { throw utils.fmt("Cannot assert while test is not running (%@)", this); } var logger = this.logger(), plan = this.plan(), raises = plan ? plan.throwsOnFailure : false, showVars = arguments.length > 2, str; if (!pass) this.didFail = true; this._actualAsserts++; if (showVars) { actual = Ct.dump(actual); expected = Ct.dump(expected); } if (pass) { str = showVars ? '%@ (actual = %@, expected = %@)' : '%@'; logger.pass(this, utils.fmt(str, message, actual, expected)); } else if (raises) { throw new Ct.AssertionError(actual, expected, message); } else { str = showVars ? '%@ (actual = %@, expected = %@)' : '%@'; logger.fail(this, utils.fmt(str, message, actual, expected)); } return this; },
summarize: function(status) { this.setupDisplay(); var ret = []; ret.push(utils.fmt('Completed %@ assertions in %@ tests: ', status.assertions, status.tests)); ret.push(utils.fmt('<span class="passed">%@ passed</span>', status.passed)); var key, hasErrors; hasErrors = (status.failed + status.errors + status.warnings)>0; if (hasErrors) { for(key in status) { if (!status.hasOwnProperty(key) || (key==='passed')) continue; if ((key==='tests') || (key==='assertions')) continue; ret.push(utils.fmt('<span class="%@1">%@2 %@1</span>', key, status[key])); } } this.layer.find('.final-status').html(ret.join('')); var checkbox = this.layer.find('.hide-passed input'); if (hasErrors) { checkbox.attr('disabled', false).attr('checked', true); this.hidePassedTestsDidChange(true); } else { checkbox.attr('disabled', true).attr('checked', false); this.hidePassedTestsDidChange(false); } checkbox = null; },
info: function(message) { if (this.mode === Ct.PLANNING_MODE) { throw utils.fmt("Cannot log info while test is not running (%@)", this); } this.logger().info(this, message); return this; },
error: function(message) { if (this.mode === Ct.PLANNING_MODE) { throw utils.fmt("Cannot assert error while test is not running (%@)", this); } this.didFail = true ; this.logger().error(this, message); return this; },
emit: function() { var assertions = [], key, len, idx; len = this.entries.length; for(idx=0;idx<len;idx++) assertions.push(this.entries[idx].emit()); assertions = assertions.join(''); return utils.fmt(this.template, _text(this.name), assertions); }
explain: function(pass, verb, expected) { var actual = Ct.dump(this.val); expected = Ct.dump(actual); if (this.inverted) { pass = !pass; verb = 'not ' + verb; } var msg = utils.fmt('%@ should %@ %@', expected, verb, actual); Ct.assertion(pass, msg); return this; },
emit: function() { var statsum = [], status = this.status, assertions = [], key, len, idx ; for(key in status) if (status[key]>0) statsum.push(_text(key)); len = this.assertions.length; for(idx=0;idx<len;idx++) assertions.push(this.assertions[idx].emit()); assertions = assertions.join(''); return utils.fmt(this.template, statsum, _text(this.name), assertions, status.passed, status.failed, status.errors, status.warnings); }
init: function(actual, expected, message) { if (arguments.length === 1) utils.mixin(this, actual); else { this.actual = actual; this.expected = expected; this.message = message; } this.desc = this.message; var ret = ['AssertionError:']; if (this.message) ret.push(this.message); if ((this.actual!==undefined) || (this.expected!==undefined)) { var act = Ct.dump(this.actual), exp = Ct.dump(this.expected); ret.push(utils.fmt('(actual = "%@" - expected = "%@")', act, exp)); } this.message = ret.join(' '); return this ; },
toString: function() { var mod = this.module(); mod = (mod && mod.name) ? mod.name : '(unknown module)'; return utils.fmt("Ct.Test<%@:%@>", mod, this.name); },
emit: function() { return utils.fmt(this.template, _text(this.status), _text(this.message)); }
add: function(status, testInfo, message) { var state = this.state, testName, moduleNames, testMode, msg, len, idx, loc; if (!state || !state.isRunning) throw "plan must be running to log it"; if (!hasConsole) return; // nothing to do moduleNames = testInfo.moduleNames; if (!moduleNames || moduleNames.length===0) moduleNames = ['default']; testName = testInfo.testName || 'default'; testMode = testInfo.mode || 'test'; // find where the old and new set of modules names diverge if (!state.moduleNames) loc = 0; else { len = state.moduleNames.length; loc = -1; for(idx=0;(loc<0) && (idx<len); idx++) { if (state.moduleNames[idx] !== moduleNames[idx]) loc = idx; } if (loc<0) loc = len; } // end current module and start new one if needed if (loc !== moduleNames.length) { // exit current modules if there are any idx = state.moduleNames ? state.moduleNames.length : 0; if (console.groupEnd && (idx>loc)) { console.groupEnd(state.testName); while(--idx >= loc) console.groupEnd(state.moduleNames[idx]); } // begin new module if needed len = moduleNames.length; if (console.group && (loc<len)) { for(idx=loc;idx<len;idx++) console.group(moduleNames[idx]); console.group(testName); } state.moduleNames = moduleNames; state.testName = testName; // if module did not change, but test changed, handle that on its own } else if (state.testName !== testName) { if (state.testName && console.groupEnd) { console.groupEnd(state.testName); } if (console.group) console.group(testName); state.testName = testName ; } // now log the message itself if (testMode !== Ct.TEST_MODE) { msg = utils.fmt('%@: %@ in %@', status, message, testMode); } else msg = utils.fmt('%@: %@', status, message); switch(status) { case Ct.ERROR: case Ct.FAIL: if (console.error) console.error(msg); else console.log(msg); break; case Ct.WARN: if (console.warn) console.warn(msg); else console.log(msg); break; default: if (console.info) console.info(msg); else console.log(msg); } },