Merge branch 'beforeAll' into master
Conflicts: lib/jasmine-core/boot.js lib/jasmine-core/boot/boot.js lib/jasmine-core/jasmine.css lib/jasmine-core/jasmine.js spec/core/SpecSpec.js spec/core/SuiteSpec.js spec/core/integration/EnvSpec.js spec/node_suite.js src/core/Env.js src/core/requireCore.js src/core/util.js
This commit is contained in:
@@ -54,7 +54,8 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
};
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
@@ -89,9 +90,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
@@ -116,6 +120,13 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
@@ -160,6 +171,17 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
|
||||
@@ -46,7 +46,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols;
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
@@ -83,6 +84,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
@@ -178,6 +183,15 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
|
||||
var errorBarClassName = 'bar errored';
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
|
||||
}
|
||||
}
|
||||
|
||||
var results = find('.results');
|
||||
results.appendChild(summary);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ body { overflow-y: scroll; }
|
||||
.jasmine_html-reporter .bar.failed { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .bar.passed { background-color: #007069; }
|
||||
.jasmine_html-reporter .bar.skipped { background-color: #bababa; }
|
||||
.jasmine_html-reporter .bar.errored { background-color: #ca3a11; }
|
||||
.jasmine_html-reporter .bar.menu { background-color: #fff; color: #aaaaaa; }
|
||||
.jasmine_html-reporter .bar.menu a { color: #333333; }
|
||||
.jasmine_html-reporter .bar a { color: white; }
|
||||
|
||||
@@ -55,6 +55,7 @@ getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher();
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
j$.SpyStrategy = jRequire.SpyStrategy();
|
||||
j$.Suite = jRequire.Suite();
|
||||
j$.Timer = jRequire.Timer();
|
||||
@@ -242,6 +243,21 @@ getJasmineRequireObj().util = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
util.clone = function(obj) {
|
||||
if (Object.prototype.toString.apply(obj) === '[object Array]') {
|
||||
return obj.slice();
|
||||
}
|
||||
|
||||
var cloned = {};
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
cloned[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return cloned;
|
||||
};
|
||||
|
||||
return util;
|
||||
};
|
||||
|
||||
@@ -251,17 +267,16 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
this.id = attrs.id;
|
||||
this.description = attrs.description || '';
|
||||
this.fn = attrs.fn;
|
||||
this.beforeFns = attrs.beforeFns || function() { return []; };
|
||||
this.afterFns = attrs.afterFns || function() { return []; };
|
||||
this.queueableFn = attrs.queueableFn;
|
||||
this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
|
||||
this.userContext = attrs.userContext || function() { return {}; };
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.exceptionFormatter = attrs.exceptionFormatter || function() {};
|
||||
this.getSpecName = attrs.getSpecName || function() { return ''; };
|
||||
this.expectationResultFactory = attrs.expectationResultFactory || function() { };
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
|
||||
if (!this.fn) {
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
}
|
||||
|
||||
@@ -297,30 +312,16 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns());
|
||||
var fns = this.beforeAndAfterFns();
|
||||
var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
|
||||
|
||||
this.queueRunnerFactory({
|
||||
fns: allFns,
|
||||
onException: onException,
|
||||
queueableFns: allFns,
|
||||
onException: function() { self.onException.apply(self, arguments); },
|
||||
onComplete: complete,
|
||||
enforceTimeout: function() { return true; }
|
||||
userContext: this.userContext()
|
||||
});
|
||||
|
||||
function onException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
self.pend();
|
||||
return;
|
||||
}
|
||||
|
||||
self.addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
});
|
||||
}
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.status();
|
||||
self.resultCallback(self.result);
|
||||
@@ -331,6 +332,21 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.onException = function onException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
this.pend();
|
||||
return;
|
||||
}
|
||||
|
||||
this.addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
});
|
||||
};
|
||||
|
||||
Spec.prototype.disable = function() {
|
||||
this.disabled = true;
|
||||
};
|
||||
@@ -355,6 +371,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.isExecutable = function() {
|
||||
return !this.disabled && !this.markedPending;
|
||||
};
|
||||
|
||||
Spec.prototype.getFullName = function() {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
@@ -388,11 +408,19 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
|
||||
|
||||
var runnableLookupTable = {};
|
||||
|
||||
var spies = [];
|
||||
var runnableResources = {};
|
||||
|
||||
var currentSpec = null;
|
||||
var currentSuite = null;
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
|
||||
var currentSuite = function() {
|
||||
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
|
||||
};
|
||||
|
||||
var currentRunnable = function() {
|
||||
return currentSpec || currentSuite();
|
||||
};
|
||||
|
||||
var reporter = new j$.ReportDispatcher([
|
||||
'jasmineStarted',
|
||||
@@ -407,11 +435,21 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
var equalityTesters = [];
|
||||
|
||||
var customEqualityTesters = [];
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
customEqualityTesters.push(tester);
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom Equalities must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Matchers must be added in a before function or a spec');
|
||||
}
|
||||
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
|
||||
for (var matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
@@ -429,7 +467,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.Factory({
|
||||
util: j$.matchersUtil,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -439,30 +478,44 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
var specStarted = function(spec) {
|
||||
currentSpec = spec;
|
||||
reporter.specStarted(spec.result);
|
||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
|
||||
|
||||
if(runnableResources[parentRunnableId]){
|
||||
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
|
||||
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
};
|
||||
|
||||
var beforeFns = function(suite) {
|
||||
var clearResourcesForRunnable = function(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite, runnablesExplictlySet) {
|
||||
return function() {
|
||||
var befores = [];
|
||||
var befores = [],
|
||||
afters = [],
|
||||
beforeAlls = [],
|
||||
afterAlls = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return befores.reverse();
|
||||
};
|
||||
};
|
||||
|
||||
var afterFns = function(suite) {
|
||||
return function() {
|
||||
var afters = [];
|
||||
while(suite) {
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
if (runnablesExplictlySet()) {
|
||||
beforeAlls = beforeAlls.concat(suite.beforeAllFns);
|
||||
afterAlls = afterAlls.concat(suite.afterAllFns);
|
||||
}
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return afters;
|
||||
return {
|
||||
befores: beforeAlls.reverse().concat(befores.reverse()),
|
||||
afters: afters.concat(afterAlls)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -520,65 +573,54 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
id: getNextSuiteId(),
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
queueRunner: queueRunnerFactory,
|
||||
resultCallback: function() {} // TODO - hook this up
|
||||
resultCallback: function(attrs) {
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
});
|
||||
runnableLookupTable[topSuite.id] = topSuite;
|
||||
currentSuite = topSuite;
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
runnablesToRun = runnablesToRun || [topSuite.id];
|
||||
if(runnablesToRun) {
|
||||
runnablesExplictlySet = true;
|
||||
} else if (focusedRunnables.length) {
|
||||
runnablesExplictlySet = true;
|
||||
runnablesToRun = focusedRunnables;
|
||||
} else {
|
||||
runnablesToRun = [topSuite.id];
|
||||
}
|
||||
|
||||
var allFns = [];
|
||||
for(var i = 0; i < runnablesToRun.length; i++) {
|
||||
var runnable = runnableLookupTable[runnablesToRun[i]];
|
||||
allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
|
||||
allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable));
|
||||
}
|
||||
|
||||
reporter.jasmineStarted({
|
||||
totalSpecsDefined: totalSpecsDefined
|
||||
});
|
||||
|
||||
queueRunnerFactory({fns: allFns, onComplete: reporter.jasmineDone});
|
||||
queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone});
|
||||
};
|
||||
|
||||
this.addReporter = function(reporterToAdd) {
|
||||
reporter.addReporter(reporterToAdd);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
j$.Expectation.addMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Spies must be created in a before function or a spec');
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
}});
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(methodName + ' has already been spied upon');
|
||||
}
|
||||
|
||||
var spy = j$.createSpy(methodName, obj[methodName]);
|
||||
|
||||
spies.push({
|
||||
spy: spy,
|
||||
baseObj: obj,
|
||||
methodName: methodName,
|
||||
originalValue: obj[methodName]
|
||||
});
|
||||
|
||||
obj[methodName] = spy;
|
||||
|
||||
return spy;
|
||||
this.spyOn = function() {
|
||||
return spyRegistry.spyOn.apply(spyRegistry, arguments);
|
||||
};
|
||||
|
||||
var suiteFactory = function(description) {
|
||||
@@ -586,40 +628,33 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
env: self,
|
||||
id: getNextSuiteId(),
|
||||
description: description,
|
||||
parentSuite: currentSuite,
|
||||
parentSuite: currentDeclarationSuite,
|
||||
queueRunner: queueRunnerFactory,
|
||||
onStart: suiteStarted,
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
resultCallback: function(attrs) {
|
||||
if (!suite.disabled) {
|
||||
clearResourcesForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
}
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
});
|
||||
|
||||
runnableLookupTable[suite.id] = suite;
|
||||
return suite;
|
||||
|
||||
function suiteStarted(suite) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result);
|
||||
}
|
||||
};
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
|
||||
var parentSuite = currentSuite;
|
||||
parentSuite.addChild(suite);
|
||||
currentSuite = suite;
|
||||
|
||||
var declarationError = null;
|
||||
try {
|
||||
specDefinitions.call(suite);
|
||||
} catch (e) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
this.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentSuite = parentSuite;
|
||||
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
return suite;
|
||||
};
|
||||
|
||||
@@ -629,15 +664,75 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return suite;
|
||||
};
|
||||
|
||||
var focusedRunnables = [];
|
||||
|
||||
this.fdescribe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
suite.isFocused = true;
|
||||
|
||||
focusedRunnables.push(suite.id);
|
||||
unfocusAncestor();
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
function addSpecsToSuite(suite, specDefinitions) {
|
||||
var parentSuite = currentDeclarationSuite;
|
||||
parentSuite.addChild(suite);
|
||||
currentDeclarationSuite = suite;
|
||||
|
||||
var declarationError = null;
|
||||
try {
|
||||
specDefinitions.call(suite);
|
||||
} catch (e) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
self.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentDeclarationSuite = parentSuite;
|
||||
}
|
||||
|
||||
function findFocusedAncestor(suite) {
|
||||
while (suite) {
|
||||
if (suite.isFocused) {
|
||||
return suite.id;
|
||||
}
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function unfocusAncestor() {
|
||||
var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
|
||||
if (focusedAncestor) {
|
||||
for (var i = 0; i < focusedRunnables.length; i++) {
|
||||
if (focusedRunnables[i] === focusedAncestor) {
|
||||
focusedRunnables.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var runnablesExplictlySet = false;
|
||||
|
||||
var runnablesExplictlySetGetter = function(){
|
||||
return runnablesExplictlySet;
|
||||
};
|
||||
|
||||
var specFactory = function(description, fn, suite) {
|
||||
totalSpecsDefined++;
|
||||
|
||||
var spec = new j$.Spec({
|
||||
id: getNextSpecId(),
|
||||
beforeFns: beforeFns(suite),
|
||||
afterFns: afterFns(suite),
|
||||
beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter),
|
||||
expectationFactory: expectationFactory,
|
||||
exceptionFormatter: exceptionFormatter,
|
||||
resultCallback: specResultCallback,
|
||||
getSpecName: function(spec) {
|
||||
return getSpecName(spec, suite);
|
||||
@@ -646,7 +741,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
description: description,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
fn: fn
|
||||
userContext: function() { return suite.clonedSharedUserContext(); },
|
||||
queueableFn: { fn: fn, type: 'it', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } }
|
||||
});
|
||||
|
||||
runnableLookupTable[spec.id] = spec;
|
||||
@@ -657,30 +753,22 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
return spec;
|
||||
|
||||
function removeAllSpies() {
|
||||
for (var i = 0; i < spies.length; i++) {
|
||||
var spyEntry = spies[i];
|
||||
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
|
||||
}
|
||||
spies = [];
|
||||
}
|
||||
|
||||
function specResultCallback(result) {
|
||||
removeAllSpies();
|
||||
j$.Expectation.resetMatchers();
|
||||
customEqualityTesters = [];
|
||||
clearResourcesForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
reporter.specDone(result);
|
||||
}
|
||||
};
|
||||
|
||||
var suiteStarted = function(suite) {
|
||||
reporter.suiteStarted(suite.result);
|
||||
function specStarted(spec) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result);
|
||||
}
|
||||
};
|
||||
|
||||
this.it = function(description, fn) {
|
||||
var spec = specFactory(description, fn, currentSuite);
|
||||
currentSuite.addChild(spec);
|
||||
var spec = specFactory(description, fn, currentDeclarationSuite);
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
return spec;
|
||||
};
|
||||
|
||||
@@ -690,20 +778,36 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.fit = function(description, fn ){
|
||||
var spec = this.it(description, fn);
|
||||
|
||||
focusedRunnables.push(spec.id);
|
||||
unfocusAncestor();
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.expect = function(actual) {
|
||||
if (!currentSpec) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
|
||||
}
|
||||
|
||||
return currentSpec.expect(actual);
|
||||
return currentRunnable().expect(actual);
|
||||
};
|
||||
|
||||
this.beforeEach = function(beforeEachFunction) {
|
||||
currentSuite.beforeEach(beforeEachFunction);
|
||||
currentDeclarationSuite.beforeEach({ fn: beforeEachFunction, type: 'beforeEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.beforeAll = function(beforeAllFunction) {
|
||||
currentDeclarationSuite.beforeAll({ fn: beforeAllFunction, type: 'beforeAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.afterEach = function(afterEachFunction) {
|
||||
currentSuite.afterEach(afterEachFunction);
|
||||
currentDeclarationSuite.afterEach({ fn: afterEachFunction, type: 'afterEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.afterAll = function(afterAllFunction) {
|
||||
currentDeclarationSuite.afterAll({ fn: afterAllFunction, type: 'afterAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.pending = function() {
|
||||
@@ -1185,8 +1289,6 @@ getJasmineRequireObj().ExceptionFormatter = function() {
|
||||
|
||||
getJasmineRequireObj().Expectation = function() {
|
||||
|
||||
var matchers = {};
|
||||
|
||||
function Expectation(options) {
|
||||
this.util = options.util || { buildFailureMessage: function() {} };
|
||||
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||
@@ -1194,8 +1296,9 @@ getJasmineRequireObj().Expectation = function() {
|
||||
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||
this.isNot = options.isNot;
|
||||
|
||||
for (var matcherName in matchers) {
|
||||
this[matcherName] = matchers[matcherName];
|
||||
var customMatchers = options.customMatchers || {};
|
||||
for (var matcherName in customMatchers) {
|
||||
this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1262,19 +1365,6 @@ getJasmineRequireObj().Expectation = function() {
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.addMatchers = function(matchersToAdd) {
|
||||
for (var name in matchersToAdd) {
|
||||
var matcher = matchersToAdd[name];
|
||||
matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.resetMatchers = function() {
|
||||
for (var name in matchers) {
|
||||
delete matchers[name];
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.Factory = function(options) {
|
||||
options = options || {};
|
||||
|
||||
@@ -1605,31 +1695,31 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
function QueueRunner(attrs) {
|
||||
this.fns = attrs.fns || [];
|
||||
this.queueableFns = attrs.queueableFns || [];
|
||||
this.onComplete = attrs.onComplete || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.onException = attrs.onException || function() {};
|
||||
this.catchException = attrs.catchException || function() { return true; };
|
||||
this.enforceTimeout = attrs.enforceTimeout || function() { return false; };
|
||||
this.userContext = {};
|
||||
this.userContext = attrs.userContext || {};
|
||||
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.run(this.fns, 0);
|
||||
this.run(this.queueableFns, 0);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.run = function(fns, recursiveIndex) {
|
||||
var length = fns.length,
|
||||
self = this,
|
||||
iterativeIndex;
|
||||
QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
|
||||
var length = queueableFns.length,
|
||||
self = this,
|
||||
iterativeIndex;
|
||||
|
||||
|
||||
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
|
||||
var fn = fns[iterativeIndex];
|
||||
if (fn.length > 0) {
|
||||
return attemptAsync(fn);
|
||||
var queueableFn = queueableFns[iterativeIndex];
|
||||
if (queueableFn.fn.length > 0) {
|
||||
return attemptAsync(queueableFn);
|
||||
} else {
|
||||
attemptSync(fn);
|
||||
attemptSync(queueableFn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1639,41 +1729,46 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.clearStack(this.onComplete);
|
||||
}
|
||||
|
||||
function attemptSync(fn) {
|
||||
function attemptSync(queueableFn) {
|
||||
try {
|
||||
fn.call(self.userContext);
|
||||
queueableFn.fn.call(self.userContext);
|
||||
} catch (e) {
|
||||
handleException(e);
|
||||
handleException(e, queueableFn);
|
||||
}
|
||||
}
|
||||
|
||||
function attemptAsync(fn) {
|
||||
function attemptAsync(queueableFn) {
|
||||
var clearTimeout = function () {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
},
|
||||
next = once(function () {
|
||||
clearTimeout(timeoutId);
|
||||
self.run(fns, iterativeIndex + 1);
|
||||
self.run(queueableFns, iterativeIndex + 1);
|
||||
}),
|
||||
timeoutId;
|
||||
|
||||
if (self.enforceTimeout()) {
|
||||
if (queueableFn.timeout) {
|
||||
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
self.onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
|
||||
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
|
||||
onException(error, queueableFn);
|
||||
next();
|
||||
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
|
||||
}, queueableFn.timeout()]]);
|
||||
}
|
||||
|
||||
try {
|
||||
fn.call(self.userContext, next);
|
||||
queueableFn.fn.call(self.userContext, next);
|
||||
} catch (e) {
|
||||
handleException(e);
|
||||
handleException(e, queueableFn);
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
function handleException(e) {
|
||||
function onException(e, queueableFn) {
|
||||
self.onException(e);
|
||||
}
|
||||
|
||||
function handleException(e, queueableFn) {
|
||||
onException(e, queueableFn);
|
||||
if (!self.catchException(e)) {
|
||||
//TODO: set a var when we catch an exception and
|
||||
//use a finally block to close the loop in a nice way..
|
||||
@@ -1721,6 +1816,52 @@ getJasmineRequireObj().ReportDispatcher = function() {
|
||||
};
|
||||
|
||||
|
||||
getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(methodName + ' has already been spied upon');
|
||||
}
|
||||
|
||||
var spy = j$.createSpy(methodName, obj[methodName]);
|
||||
|
||||
currentSpies().push({
|
||||
spy: spy,
|
||||
baseObj: obj,
|
||||
methodName: methodName,
|
||||
originalValue: obj[methodName]
|
||||
});
|
||||
|
||||
obj[methodName] = spy;
|
||||
|
||||
return spy;
|
||||
};
|
||||
|
||||
this.clearSpies = function() {
|
||||
var spies = currentSpies();
|
||||
for (var i = 0; i < spies.length; i++) {
|
||||
var spyEntry = spies[i];
|
||||
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return SpyRegistry;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().SpyStrategy = function() {
|
||||
|
||||
function SpyStrategy(options) {
|
||||
@@ -1790,9 +1931,13 @@ getJasmineRequireObj().Suite = function() {
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.expectationFactory = attrs.expectationFactory;
|
||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||
|
||||
this.beforeFns = [];
|
||||
this.afterFns = [];
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
this.queueRunner = attrs.queueRunner || function() {};
|
||||
this.disabled = false;
|
||||
|
||||
@@ -1800,12 +1945,16 @@ getJasmineRequireObj().Suite = function() {
|
||||
|
||||
this.result = {
|
||||
id: this.id,
|
||||
status: this.disabled ? 'disabled' : '',
|
||||
description: this.description,
|
||||
fullName: this.getFullName()
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: []
|
||||
};
|
||||
}
|
||||
|
||||
Suite.prototype.expect = function(actual) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
|
||||
Suite.prototype.getFullName = function() {
|
||||
var fullName = this.description;
|
||||
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
|
||||
@@ -1825,10 +1974,18 @@ getJasmineRequireObj().Suite = function() {
|
||||
this.beforeFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.beforeAll = function(fn) {
|
||||
this.beforeAllFns.push(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.afterEach = function(fn) {
|
||||
this.afterFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.afterAll = function(fn) {
|
||||
this.afterAllFns.push(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.addChild = function(child) {
|
||||
this.children.push(child);
|
||||
};
|
||||
@@ -1845,16 +2002,25 @@ getJasmineRequireObj().Suite = function() {
|
||||
|
||||
var allFns = [];
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
allFns.push(wrapChildAsAsync(this.children[i]));
|
||||
if (this.isExecutable()) {
|
||||
allFns = allFns.concat(this.beforeAllFns);
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
allFns.push(wrapChildAsAsync(this.children[i]));
|
||||
}
|
||||
|
||||
allFns = allFns.concat(this.afterAllFns);
|
||||
}
|
||||
|
||||
this.queueRunner({
|
||||
fns: allFns,
|
||||
onComplete: complete
|
||||
queueableFns: allFns,
|
||||
onComplete: complete,
|
||||
userContext: this.sharedUserContext(),
|
||||
onException: function() { self.onException.apply(self, arguments); }
|
||||
});
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.disabled ? 'disabled' : 'finished';
|
||||
self.resultCallback(self.result);
|
||||
|
||||
if (onComplete) {
|
||||
@@ -1863,10 +2029,82 @@ getJasmineRequireObj().Suite = function() {
|
||||
}
|
||||
|
||||
function wrapChildAsAsync(child) {
|
||||
return function(done) { child.execute(done); };
|
||||
return { fn: function(done) { child.execute(done); } };
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.isExecutable = function() {
|
||||
var foundActive = false;
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
if(this.children[i].isExecutable()) {
|
||||
foundActive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return foundActive;
|
||||
};
|
||||
|
||||
Suite.prototype.sharedUserContext = function() {
|
||||
if (!this.sharedContext) {
|
||||
this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {};
|
||||
}
|
||||
|
||||
return this.sharedContext;
|
||||
};
|
||||
|
||||
Suite.prototype.clonedSharedUserContext = function() {
|
||||
return clone(this.sharedUserContext());
|
||||
};
|
||||
|
||||
Suite.prototype.onException = function() {
|
||||
if(isAfterAll(this.children)) {
|
||||
var data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: arguments[0]
|
||||
};
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.onException.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.addExpectationResult = function () {
|
||||
if(isAfterAll(this.children) && isFailure(arguments)){
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.addExpectationResult.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function isAfterAll(children) {
|
||||
return children && children[0].result.status;
|
||||
}
|
||||
|
||||
function isFailure(args) {
|
||||
return !args[0];
|
||||
}
|
||||
|
||||
function clone(obj) {
|
||||
var clonedObj = {};
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
clonedObj[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return clonedObj;
|
||||
}
|
||||
|
||||
return Suite;
|
||||
};
|
||||
|
||||
@@ -2568,6 +2806,14 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
beforeAll: function(beforeAllFunction) {
|
||||
return env.beforeAll(beforeAllFunction);
|
||||
},
|
||||
|
||||
afterAll: function(afterAllFunction) {
|
||||
return env.afterAll(afterAllFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
@@ -171,27 +171,44 @@ describe("ConsoleReporter", function() {
|
||||
|
||||
out.clear();
|
||||
|
||||
reporter.jasmineDone({});
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/true to be false/);
|
||||
expect(out.getOutput()).toMatch(/foo bar baz/);
|
||||
});
|
||||
|
||||
it("calls the onComplete callback when the suite is done", function() {
|
||||
var onComplete = jasmine.createSpy('onComplete'),
|
||||
describe('onComplete callback', function(){
|
||||
var onComplete, reporter;
|
||||
|
||||
beforeEach(function() {
|
||||
onComplete = jasmine.createSpy('onComplete');
|
||||
reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
onComplete: onComplete
|
||||
});
|
||||
reporter.jasmineStarted();
|
||||
});
|
||||
|
||||
reporter.jasmineDone({});
|
||||
it("is called when the suite is done", function() {
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
it('calls it with false if there are spec failures', function() {
|
||||
reporter.specDone({status: "failed", failedExpectations: []});
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
|
||||
it('calls it with false if there are suite failures', function() {
|
||||
reporter.specDone({status: "passed"});
|
||||
reporter.suiteDone({failedExpectations: [{ message: 'bananas' }] });
|
||||
reporter.jasmineDone();
|
||||
expect(onComplete).toHaveBeenCalledWith(false);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe("with color", function() {
|
||||
|
||||
it("reports that the suite has started to the console", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
@@ -235,5 +252,19 @@ describe("ConsoleReporter", function() {
|
||||
|
||||
expect(out.getOutput()).toEqual("\x1B[31mF\x1B[0m");
|
||||
});
|
||||
|
||||
it("displays all afterAll exceptions", function() {
|
||||
var reporter = new j$.ConsoleReporter({
|
||||
print: out.print,
|
||||
showColors: true
|
||||
});
|
||||
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'After All Exception' }] });
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'Some Other Exception' }] });
|
||||
reporter.jasmineDone();
|
||||
|
||||
expect(out.getOutput()).toMatch(/After All Exception/);
|
||||
expect(out.getOutput()).toMatch(/Some Other Exception/);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -5,68 +5,6 @@ describe("Env", function() {
|
||||
env = new j$.Env();
|
||||
});
|
||||
|
||||
it('removes all spies when env is executed', function(done) {
|
||||
var originalFoo = function() {},
|
||||
testObj = {
|
||||
foo: originalFoo
|
||||
},
|
||||
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
|
||||
env.spyOn(testObj, 'foo');
|
||||
}),
|
||||
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
|
||||
expect(testObj.foo).toBe(originalFoo);
|
||||
});
|
||||
env.describe('test suite', function() {
|
||||
env.it('spec 0', firstSpec);
|
||||
env.it('spec 1', secondSpec);
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(firstSpec).toHaveBeenCalled();
|
||||
expect(secondSpec).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
expect(function() {
|
||||
env.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks for the existence of the method", function() {
|
||||
var subject = {};
|
||||
|
||||
expect(function() {
|
||||
env.spyOn(subject, 'pants');
|
||||
}).toThrowError(/method does not exist/);
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var subject = { spiedFunc: function() {} };
|
||||
|
||||
env.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(function() {
|
||||
env.spyOn(subject, 'spiedFunc');
|
||||
}).toThrowError(/has already been spied upon/);
|
||||
});
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
var originalFunctionWasCalled = false;
|
||||
var subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
|
||||
var spy = env.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#pending", function() {
|
||||
it("throws the Pending Spec exception", function() {
|
||||
expect(function() {
|
||||
@@ -82,4 +20,3 @@ describe("Env", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
describe("Expectation", function() {
|
||||
it(".addMatchers makes matchers available to any expectation", function() {
|
||||
it("makes custom matchers available to this expectation", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {},
|
||||
toBar: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
expectation = new j$.Expectation({
|
||||
customMatchers: matchers
|
||||
});
|
||||
|
||||
expect(expectation.toFoo).toBeDefined();
|
||||
expect(expectation.toBar).toBeDefined();
|
||||
@@ -27,25 +27,6 @@ describe("Expectation", function() {
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
});
|
||||
|
||||
it(".resetMatchers should keep only core matchers", function() {
|
||||
var matchers = {
|
||||
toFoo: function() {}
|
||||
},
|
||||
coreMatchers = {
|
||||
toQuux: function() {}
|
||||
},
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addCoreMatchers(coreMatchers);
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
j$.Expectation.resetMatchers();
|
||||
|
||||
expectation = new j$.Expectation({});
|
||||
|
||||
expect(expectation.toQuux).toBeDefined();
|
||||
expect(expectation.toFoo).toBeUndefined();
|
||||
});
|
||||
|
||||
it("Factory builds an expectation/negative expectation", function() {
|
||||
var builtExpectation = j$.Expectation.Factory();
|
||||
|
||||
@@ -65,10 +46,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -94,10 +74,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
util: util,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -121,10 +100,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -155,10 +132,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
util: util,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
@@ -191,10 +166,9 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
actual: "an actual",
|
||||
customMatchers: matchers,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
|
||||
@@ -225,10 +199,8 @@ describe("Expectation", function() {
|
||||
addExpectationResult = jasmine.createSpy("addExpectationResult"),
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -259,10 +231,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -294,10 +264,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
util: util,
|
||||
addExpectationResult: addExpectationResult,
|
||||
@@ -332,10 +300,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -365,10 +331,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
@@ -403,10 +367,8 @@ describe("Expectation", function() {
|
||||
actual = "an actual",
|
||||
expectation;
|
||||
|
||||
j$.Expectation.addMatchers(matchers);
|
||||
|
||||
expectation = new j$.Expectation({
|
||||
matchers: matchers,
|
||||
customMatchers: matchers,
|
||||
actual: "an actual",
|
||||
addExpectationResult: addExpectationResult,
|
||||
isNot: true
|
||||
|
||||
@@ -135,7 +135,9 @@ describe("j$.pp", function () {
|
||||
},
|
||||
env = new j$.Env();
|
||||
|
||||
env.spyOn(TestObject, 'someFunction');
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {return [];}});
|
||||
|
||||
spyRegistry.spyOn(TestObject, 'someFunction');
|
||||
expect(j$.pp(TestObject.someFunction)).toEqual("spy on someFunction");
|
||||
|
||||
expect(j$.pp(j$.createSpy("something"))).toEqual("spy on something");
|
||||
@@ -158,4 +160,3 @@ describe("j$.pp", function () {
|
||||
expect(j$.pp(obj)).toEqual("{ foo: 'bar' }");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -2,15 +2,15 @@ describe("QueueRunner", function() {
|
||||
|
||||
it("runs all the functions it's passed", function() {
|
||||
var calls = [],
|
||||
fn1 = jasmine.createSpy('fn1'),
|
||||
fn2 = jasmine.createSpy('fn2'),
|
||||
queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2]
|
||||
queueableFns: [queueableFn1, queueableFn2]
|
||||
});
|
||||
fn1.and.callFake(function() {
|
||||
queueableFn1.fn.and.callFake(function() {
|
||||
calls.push('fn1');
|
||||
});
|
||||
fn2.and.callFake(function() {
|
||||
queueableFn2.fn.and.callFake(function() {
|
||||
calls.push('fn2');
|
||||
});
|
||||
|
||||
@@ -20,19 +20,19 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("calls each function with a consistent 'this'-- an empty object", function() {
|
||||
var fn1 = jasmine.createSpy('fn1'),
|
||||
fn2 = jasmine.createSpy('fn2'),
|
||||
fn3 = function(done) { asyncContext = this; done(); },
|
||||
var queueableFn1 = { fn: jasmine.createSpy('fn1') },
|
||||
queueableFn2 = { fn: jasmine.createSpy('fn2') },
|
||||
queueableFn3 = { fn: function(done) { asyncContext = this; done(); } },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2, fn3]
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3]
|
||||
}),
|
||||
asyncContext;
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
var context = fn1.calls.first().object;
|
||||
var context = queueableFn1.fn.calls.first().object;
|
||||
expect(context).toEqual({});
|
||||
expect(fn2.calls.first().object).toBe(context);
|
||||
expect(queueableFn2.fn.calls.first().object).toBe(context);
|
||||
expect(asyncContext).toBe(context);
|
||||
});
|
||||
|
||||
@@ -53,20 +53,20 @@ describe("QueueRunner", function() {
|
||||
beforeCallback = jasmine.createSpy('beforeCallback'),
|
||||
fnCallback = jasmine.createSpy('fnCallback'),
|
||||
afterCallback = jasmine.createSpy('afterCallback'),
|
||||
fn1 = function(done) {
|
||||
queueableFn1 = { fn: function(done) {
|
||||
beforeCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
fn2 = function(done) {
|
||||
} },
|
||||
queueableFn2 = { fn: function(done) {
|
||||
fnCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
fn3 = function(done) {
|
||||
} },
|
||||
queueableFn3 = { fn: function(done) {
|
||||
afterCallback();
|
||||
setTimeout(done, 100);
|
||||
},
|
||||
} },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn1, fn2, fn3],
|
||||
queueableFns: [queueableFn1, queueableFn2, queueableFn3],
|
||||
onComplete: onComplete
|
||||
});
|
||||
|
||||
@@ -94,54 +94,54 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("sets a timeout if requested for asynchronous functions so they don't go on forever", function() {
|
||||
var beforeFn = function(done) { },
|
||||
fn = jasmine.createSpy('fn'),
|
||||
var timeout = 3,
|
||||
beforeFn = { fn: function(done) { }, type: 'before', timeout: function() { return timeout; } },
|
||||
queueableFn = { fn: jasmine.createSpy('fn'), type: 'queueable' },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [beforeFn, fn],
|
||||
queueableFns: [beforeFn, queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException,
|
||||
enforceTimeout: function() { return true; }
|
||||
onException: onException
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
|
||||
jasmine.clock().tick(timeout);
|
||||
|
||||
expect(onException).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
expect(fn).toHaveBeenCalled();
|
||||
expect(queueableFn.fn).toHaveBeenCalled();
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("by default does not set a timeout for asynchronous functions", function() {
|
||||
var beforeFn = function(done) { },
|
||||
fn = jasmine.createSpy('fn'),
|
||||
var beforeFn = { fn: function(done) { } },
|
||||
queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [beforeFn, fn],
|
||||
queueableFns: [beforeFn, queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException,
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
|
||||
jasmine.clock().tick(j$.DEFAULT_TIMEOUT_INTERVAL);
|
||||
|
||||
expect(onException).not.toHaveBeenCalled();
|
||||
expect(fn).not.toHaveBeenCalled();
|
||||
expect(queueableFn.fn).not.toHaveBeenCalled();
|
||||
expect(onComplete).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("clears the timeout when an async function throws an exception, to prevent additional onException calls", function() {
|
||||
var fn = function(done) { throw new Error("error!"); },
|
||||
it("clears the timeout when an async function throws an exception, to prevent additional exception reporting", function() {
|
||||
var queueableFn = { fn: function(done) { throw new Error("error!"); } },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException
|
||||
});
|
||||
@@ -156,11 +156,11 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("clears the timeout when the done callback is called", function() {
|
||||
var fn = function(done) { done(); },
|
||||
var queueableFn = { fn: function(done) { done(); } },
|
||||
onComplete = jasmine.createSpy('onComplete'),
|
||||
onException = jasmine.createSpy('onException'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: onComplete,
|
||||
onException: onException
|
||||
});
|
||||
@@ -174,75 +174,78 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("only moves to the next spec the first time you call done", function() {
|
||||
var fn = function(done) {done(); done();},
|
||||
nextFn = jasmine.createSpy('nextFn');
|
||||
var queueableFn = { fn: function(done) {done(); done();} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextFn.calls.count()).toEqual(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it("does not move to the next spec if done is called after an exception has ended the spec", function() {
|
||||
var fn = function(done) {
|
||||
var queueableFn = { fn: function(done) {
|
||||
setTimeout(done, 1);
|
||||
throw new Error('error!');
|
||||
},
|
||||
nextFn = jasmine.createSpy('nextFn');
|
||||
} },
|
||||
nextQueueableFn = { fn: jasmine.createSpy('nextFn') };
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
jasmine.clock().tick(1);
|
||||
expect(nextFn.calls.count()).toEqual(1);
|
||||
expect(nextQueueableFn.fn.calls.count()).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
it("calls an exception handler when an exception is thrown in a fn", function() {
|
||||
var fn = function() {
|
||||
it("calls exception handlers when an exception is thrown in a fn", function() {
|
||||
var queueableFn = { type: 'queueable',
|
||||
fn: function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
exceptionCallback = jasmine.createSpy('exception callback'),
|
||||
} },
|
||||
onExceptionCallback = jasmine.createSpy('on exception callback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
onException: exceptionCallback
|
||||
queueableFns: [queueableFn],
|
||||
onException: onExceptionCallback
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
|
||||
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
expect(onExceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
|
||||
});
|
||||
|
||||
it("rethrows an exception if told to", function() {
|
||||
var fn = function() {
|
||||
var queueableFn = { fn: function() {
|
||||
throw new Error('fake error');
|
||||
},
|
||||
} },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
catchException: function(e) { return false; }
|
||||
});
|
||||
|
||||
expect(queueRunner.execute).toThrow();
|
||||
expect(function() {
|
||||
queueRunner.execute();
|
||||
}).toThrowError('fake error');
|
||||
});
|
||||
|
||||
it("continues running the functions even after an exception is thrown in an async spec", function() {
|
||||
var fn = function(done) { throw new Error("error"); },
|
||||
nextFn = jasmine.createSpy("nextFunction"),
|
||||
var queueableFn = { fn: function(done) { throw new Error("error"); } },
|
||||
nextQueueableFn = { fn: jasmine.createSpy("nextFunction") },
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn, nextFn]
|
||||
queueableFns: [queueableFn, nextQueueableFn]
|
||||
});
|
||||
|
||||
queueRunner.execute();
|
||||
expect(nextFn).toHaveBeenCalled();
|
||||
expect(nextQueueableFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls a provided complete callback when done", function() {
|
||||
var fn = jasmine.createSpy('fn'),
|
||||
var queueableFn = { fn: jasmine.createSpy('fn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [fn],
|
||||
queueableFns: [queueableFn],
|
||||
onComplete: completeCallback
|
||||
});
|
||||
|
||||
@@ -252,12 +255,12 @@ describe("QueueRunner", function() {
|
||||
});
|
||||
|
||||
it("calls a provided stack clearing function when done", function() {
|
||||
var asyncFn = function(done) { done() },
|
||||
afterFn = jasmine.createSpy('afterFn'),
|
||||
var asyncFn = { fn: function(done) { done() } },
|
||||
afterFn = { fn: jasmine.createSpy('afterFn') },
|
||||
completeCallback = jasmine.createSpy('completeCallback'),
|
||||
clearStack = jasmine.createSpy('clearStack'),
|
||||
queueRunner = new j$.QueueRunner({
|
||||
fns: [asyncFn, afterFn],
|
||||
queueableFns: [asyncFn, afterFn],
|
||||
clearStack: clearStack,
|
||||
onComplete: completeCallback
|
||||
});
|
||||
@@ -265,7 +268,7 @@ describe("QueueRunner", function() {
|
||||
clearStack.and.callFake(function(fn) { fn(); });
|
||||
|
||||
queueRunner.execute();
|
||||
expect(afterFn).toHaveBeenCalled();
|
||||
expect(afterFn.fn).toHaveBeenCalled();
|
||||
expect(clearStack).toHaveBeenCalledWith(completeCallback);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -29,7 +29,7 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
@@ -44,7 +44,7 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
id: 123,
|
||||
description: 'foo bar',
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
onStart: startCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
@@ -66,7 +66,7 @@ describe("Spec", function() {
|
||||
expect(beforesWereCalled).toBe(false);
|
||||
}),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
beforeFns: function() {
|
||||
return [function() {
|
||||
beforesWereCalled = true
|
||||
@@ -85,25 +85,22 @@ describe("Spec", function() {
|
||||
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
|
||||
before = jasmine.createSpy('before'),
|
||||
after = jasmine.createSpy('after'),
|
||||
fn = jasmine.createSpy('test body').and.callFake(function() {
|
||||
queueableFn = { fn: jasmine.createSpy('test body').and.callFake(function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
}),
|
||||
}) },
|
||||
spec = new j$.Spec({
|
||||
fn: fn,
|
||||
beforeFns: function() {
|
||||
return [before]
|
||||
},
|
||||
afterFns: function() {
|
||||
return [after]
|
||||
queueableFn: queueableFn,
|
||||
beforeAndAfterFns: function() {
|
||||
return {befores: [before], afters: [after]}
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
spec.execute();
|
||||
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].fns;
|
||||
expect(allSpecFns).toEqual([before, fn, after]);
|
||||
var allSpecFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
expect(allSpecFns).toEqual([before, queueableFn, after]);
|
||||
});
|
||||
|
||||
it("is marked pending if created without a function body", function() {
|
||||
@@ -113,7 +110,7 @@ describe("Spec", function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart: startCallback,
|
||||
fn: null,
|
||||
queueableFn: { fn: null },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
@@ -129,7 +126,7 @@ describe("Spec", function() {
|
||||
resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
onStart:startCallback,
|
||||
fn: specBody,
|
||||
queueableFn: { fn: specBody },
|
||||
resultCallback: resultCallback,
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
@@ -158,7 +155,8 @@ describe("Spec", function() {
|
||||
getSpecName: function() {
|
||||
return "a suite with a spec"
|
||||
},
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
queueRunnerFactory: fakeQueueRunner,
|
||||
queueableFn: { fn: null }
|
||||
});
|
||||
|
||||
spec.pend();
|
||||
@@ -183,7 +181,7 @@ describe("Spec", function() {
|
||||
it("should call the done callback on execution complete", function() {
|
||||
var done = jasmine.createSpy('done callback'),
|
||||
spec = new j$.Spec({
|
||||
fn: function() {},
|
||||
queueableFn: { fn: function() {} },
|
||||
catchExceptions: function() { return false; },
|
||||
resultCallback: function() {},
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); }
|
||||
@@ -194,19 +192,19 @@ describe("Spec", function() {
|
||||
expect(done).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("#status returns passing by default", function(){
|
||||
var spec = new j$.Spec({ fn: function () {} });
|
||||
expect(spec.status()).toBe("passed");
|
||||
it("#status returns passing by default", function() {
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns passed if all expectations in the spec have passed", function() {
|
||||
var spec = new j$.Spec({fn: jasmine.createSpy("spec body")});
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body")} });
|
||||
spec.addExpectationResult(true);
|
||||
expect(spec.status()).toBe('passed');
|
||||
});
|
||||
|
||||
it("#status returns failed if any expectations in the spec have failed", function() {
|
||||
var spec = new j$.Spec({ fn: jasmine.createSpy("spec body") });
|
||||
var spec = new j$.Spec({queueableFn: { fn: jasmine.createSpy("spec body") } });
|
||||
spec.addExpectationResult(true);
|
||||
spec.addExpectationResult(false);
|
||||
expect(spec.status()).toBe('failed');
|
||||
@@ -215,7 +213,7 @@ describe("Spec", function() {
|
||||
it("keeps track of passed and failed expectations", function() {
|
||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
||||
spec = new j$.Spec({
|
||||
fn: jasmine.createSpy("spec body"),
|
||||
queueableFn: { fn: jasmine.createSpy("spec body") },
|
||||
expectationResultFactory: function (data) { return data; },
|
||||
queueRunnerFactory: function(attrs) { attrs.onComplete(); },
|
||||
resultCallback: resultCallback
|
||||
@@ -233,7 +231,8 @@ describe("Spec", function() {
|
||||
var specNameSpy = jasmine.createSpy('specNameSpy').and.returnValue('expected val');
|
||||
|
||||
var spec = new j$.Spec({
|
||||
getSpecName: specNameSpy
|
||||
getSpecName: specNameSpy,
|
||||
queueableFn: { fn: null }
|
||||
});
|
||||
|
||||
expect(spec.getFullName()).toBe('expected val');
|
||||
@@ -248,7 +247,7 @@ describe("Spec", function() {
|
||||
spec = new j$.Spec({
|
||||
description: 'my test',
|
||||
id: 'some-id',
|
||||
fn: function() { },
|
||||
queueableFn: { fn: function() { } },
|
||||
queueRunnerFactory: fakeQueueRunner
|
||||
});
|
||||
|
||||
|
||||
55
spec/core/SpyRegistrySpec.js
Normal file
55
spec/core/SpyRegistrySpec.js
Normal file
@@ -0,0 +1,55 @@
|
||||
describe("SpyRegistry", function() {
|
||||
describe("#spyOn", function() {
|
||||
it("checks for the existence of the object", function() {
|
||||
var spyRegistry = new j$.SpyRegistry();
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(void 0, 'pants');
|
||||
}).toThrowError(/could not find an object/);
|
||||
});
|
||||
|
||||
it("checks for the existence of the method", function() {
|
||||
var spyRegistry = new j$.SpyRegistry(),
|
||||
subject = {};
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, 'pants');
|
||||
}).toThrowError(/method does not exist/);
|
||||
});
|
||||
|
||||
it("checks if it has already been spied upon", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
subject = { spiedFunc: function() {} };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(function() {
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
}).toThrowError(/has already been spied upon/);
|
||||
});
|
||||
|
||||
it("overrides the method on the object and returns the spy", function() {
|
||||
var originalFunctionWasCalled = false,
|
||||
spyRegistry = new j$.SpyRegistry(),
|
||||
subject = { spiedFunc: function() { originalFunctionWasCalled = true; } };
|
||||
|
||||
var spy = spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#clearSpies", function() {
|
||||
it("restores the original functions on the spied-upon objects", function() {
|
||||
var spies = [],
|
||||
spyRegistry = new j$.SpyRegistry({currentSpies: function() { return spies; }}),
|
||||
originalFunction = function() {},
|
||||
subject = { spiedFunc: originalFunction };
|
||||
|
||||
spyRegistry.spyOn(subject, 'spiedFunc');
|
||||
spyRegistry.clearSpies();
|
||||
|
||||
expect(subject.spiedFunc).toBe(originalFunction);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -52,6 +52,31 @@ describe("Suite", function() {
|
||||
expect(suite.beforeFns).toEqual([innerBefore, outerBefore]);
|
||||
});
|
||||
|
||||
it("runs beforeAll functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
firstBefore = jasmine.createSpy('outerBeforeAll'),
|
||||
lastBefore = jasmine.createSpy('insideBeforeAll'),
|
||||
fakeIt = {execute: jasmine.createSpy('it'), isExecutable: function() { return true; } };
|
||||
|
||||
suite.beforeAll(firstBefore);
|
||||
suite.beforeAll(lastBefore);
|
||||
suite.addChild(fakeIt);
|
||||
|
||||
suite.execute();
|
||||
var suiteFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
suiteFns[0]();
|
||||
expect(firstBefore).toHaveBeenCalled();
|
||||
suiteFns[1]();
|
||||
expect(lastBefore).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("adds after functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
suite = new j$.Suite({
|
||||
@@ -67,6 +92,31 @@ describe("Suite", function() {
|
||||
expect(suite.afterFns).toEqual([innerAfter, outerAfter]);
|
||||
});
|
||||
|
||||
it("runs afterAll functions in order of needed execution", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
suite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
firstAfter = jasmine.createSpy('outerAfterAll'),
|
||||
lastAfter = jasmine.createSpy('insideAfterAll'),
|
||||
fakeIt = {execute: jasmine.createSpy('it'), isExecutable: function() { return true; } };
|
||||
|
||||
suite.afterAll(firstAfter);
|
||||
suite.afterAll(lastAfter);
|
||||
suite.addChild(fakeIt);
|
||||
|
||||
suite.execute();
|
||||
var suiteFns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
suiteFns[1]();
|
||||
expect(firstAfter).toHaveBeenCalled();
|
||||
suiteFns[2]();
|
||||
expect(lastAfter).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("can be disabled, but still calls callbacks", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
|
||||
@@ -93,7 +143,7 @@ describe("Suite", function() {
|
||||
expect(onComplete).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("delegates execution of its specs and suites", function() {
|
||||
it("delegates execution of its specs, suites, beforeAlls, and afterAlls", function() {
|
||||
var env = new j$.Env(),
|
||||
parentSuiteDone = jasmine.createSpy('parent suite done'),
|
||||
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
|
||||
@@ -109,22 +159,57 @@ describe("Suite", function() {
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
};
|
||||
execute: jasmine.createSpy('fakeSpec1'),
|
||||
isExecutable: function() { return true; }
|
||||
},
|
||||
beforeAllFn = { fn: jasmine.createSpy('beforeAll') },
|
||||
afterAllFn = { fn: jasmine.createSpy('afterAll') };
|
||||
|
||||
spyOn(suite, "execute");
|
||||
|
||||
parentSuite.addChild(fakeSpec1);
|
||||
parentSuite.addChild(suite);
|
||||
parentSuite.beforeAll(beforeAllFn);
|
||||
parentSuite.afterAll(afterAllFn);
|
||||
|
||||
parentSuite.execute(parentSuiteDone);
|
||||
|
||||
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].fns;
|
||||
var parentSuiteFns = fakeQueueRunnerForParent.calls.mostRecent().args[0].queueableFns;
|
||||
|
||||
parentSuiteFns[0]();
|
||||
parentSuiteFns[0].fn();
|
||||
expect(beforeAllFn.fn).toHaveBeenCalled();
|
||||
parentSuiteFns[1].fn();
|
||||
expect(fakeSpec1.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[1]();
|
||||
parentSuiteFns[2].fn();
|
||||
expect(suite.execute).toHaveBeenCalled();
|
||||
parentSuiteFns[3].fn();
|
||||
expect(afterAllFn.fn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("does not run beforeAll or afterAll if there are no child specs to run", function() {
|
||||
var env = new j$.Env(),
|
||||
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
|
||||
fakeQueueRunnerForChild = jasmine.createSpy('fake child queue runner'),
|
||||
parentSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunnerForParent
|
||||
}),
|
||||
childSuite = new j$.Suite({
|
||||
env: env,
|
||||
description: "I am a suite",
|
||||
queueRunner: fakeQueueRunnerForChild,
|
||||
parentSuite: parentSuite
|
||||
}),
|
||||
beforeAllFn = jasmine.createSpy('beforeAll'),
|
||||
afterAllFn = jasmine.createSpy('afterAll');
|
||||
|
||||
parentSuite.addChild(childSuite);
|
||||
parentSuite.beforeAll(beforeAllFn);
|
||||
parentSuite.afterAll(afterAllFn);
|
||||
|
||||
parentSuite.execute();
|
||||
expect(fakeQueueRunnerForParent).toHaveBeenCalledWith(jasmine.objectContaining({queueableFns: []}));
|
||||
});
|
||||
|
||||
it("calls a provided onStart callback when starting", function() {
|
||||
@@ -138,7 +223,8 @@ describe("Suite", function() {
|
||||
queueRunner: fakeQueueRunner
|
||||
}),
|
||||
fakeSpec1 = {
|
||||
execute: jasmine.createSpy('fakeSpec1')
|
||||
execute: jasmine.createSpy('fakeSpec1'),
|
||||
isExecutable: function() { return true; }
|
||||
};
|
||||
|
||||
suite.execute();
|
||||
@@ -182,9 +268,10 @@ describe("Suite", function() {
|
||||
|
||||
expect(suiteResultsCallback).toHaveBeenCalledWith({
|
||||
id: suite.id,
|
||||
status: '',
|
||||
status: 'finished',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite"
|
||||
fullName: "with a child suite",
|
||||
failedExpectations: []
|
||||
});
|
||||
});
|
||||
|
||||
@@ -210,7 +297,8 @@ describe("Suite", function() {
|
||||
id: suite.id,
|
||||
status: 'disabled',
|
||||
description: "with a child suite",
|
||||
fullName: "with a child suite"
|
||||
fullName: "with a child suite",
|
||||
failedExpectations: []
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -38,13 +38,13 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("passes the spec if the custom matcher passes", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: function() { return { pass: true }; } };
|
||||
}
|
||||
});
|
||||
|
||||
env.it("spec using custom matcher", function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: function() { return { pass: true }; } };
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
@@ -57,16 +57,16 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("uses the negative compare function for a negative comparison, if provided", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
env.it("spec with custom negative comparison matcher", function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() { return { pass: true }; },
|
||||
negativeCompare: function() { return { pass: true }; }
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).not.toBeReal();
|
||||
});
|
||||
|
||||
@@ -79,17 +79,17 @@ describe("Custom Matchers (Integration)", function() {
|
||||
});
|
||||
|
||||
it("generates messages with the same rules as built in matchers absent a custom message", function(done) {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
env.it('spec with an expectation', function() {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return {
|
||||
compare: function() {
|
||||
return { pass: false };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
env.it('spec with an expectation', function() {
|
||||
env.expect("a").toBeReal();
|
||||
});
|
||||
|
||||
@@ -103,13 +103,14 @@ describe("Custom Matchers (Integration)", function() {
|
||||
|
||||
it("passes the expected and actual arguments to the comparison function", function(done) {
|
||||
var argumentSpy = jasmine.createSpy("argument spy").and.returnValue({ pass: true });
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: argumentSpy };
|
||||
}
|
||||
});
|
||||
|
||||
env.it('spec with an expectation', function () {
|
||||
env.addMatchers({
|
||||
toBeReal: function() {
|
||||
return { compare: argumentSpy };
|
||||
}
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
env.expect(true).toBeReal("arg");
|
||||
env.expect(true).toBeReal("arg1", "arg2");
|
||||
@@ -130,12 +131,13 @@ describe("Custom Matchers (Integration)", function() {
|
||||
argumentSpy = jasmine.createSpy("argument spy").and.returnValue(matcherFactory),
|
||||
customEqualityFn = function() { return true; };
|
||||
|
||||
env.addCustomEqualityTester(customEqualityFn);
|
||||
env.addMatchers({
|
||||
toBeReal: argumentSpy
|
||||
});
|
||||
|
||||
env.it("spec with expectation", function() {
|
||||
env.addCustomEqualityTester(customEqualityFn);
|
||||
env.addMatchers({
|
||||
toBeReal: argumentSpy
|
||||
});
|
||||
|
||||
env.expect(true).toBeReal();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,44 @@
|
||||
describe("Env integration", function() {
|
||||
beforeEach(function() {
|
||||
jasmine.addMatchers({
|
||||
toHaveFailedExpecationsForSuite: function(util, customeEqualityTesters) {
|
||||
return {
|
||||
compare: function(actual, suiteName, expectedFailures) {
|
||||
var foundSuite = false, expectations = true, foundFailures = [];
|
||||
for (var i = 0; i < actual.calls.count(); i++) {
|
||||
var args = actual.calls.argsFor(i)[0];
|
||||
|
||||
if (args.description === suiteName) {
|
||||
foundSuite = true;
|
||||
|
||||
for (var j = 0; j < args.failedExpectations.length; j++) {
|
||||
foundFailures.push(args.failedExpectations[j].message);
|
||||
}
|
||||
|
||||
for (var j = 0; j < expectedFailures.length; j++) {
|
||||
var failure = foundFailures[j];
|
||||
var expectedFailure = expectedFailures[j];
|
||||
|
||||
if (Object.prototype.toString.call(expectedFailure) === '[object RegExp]') {
|
||||
expectations = expectations && expectedFailure.test(failure);
|
||||
} else {
|
||||
expectations = expectations && failure === expectedFailure;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
pass: foundSuite && expectations,
|
||||
message: !foundSuite ? 'The suite "' + suiteName + '" never finished' :
|
||||
'Expected suite "' + suiteName + '" to have failures ' + jasmine.pp(expectedFailures) + ' but it had ' + jasmine.pp(foundFailures)
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("Suites execute as expected (no nesting)", function(done) {
|
||||
var env = new j$.Env(),
|
||||
@@ -80,7 +120,7 @@ describe("Env integration", function() {
|
||||
|
||||
env.describe("Outer suite", function() {
|
||||
env.it("an outer spec", function() {
|
||||
calls.push('an outer spec')
|
||||
calls.push('an outer spec');
|
||||
});
|
||||
env.describe("Inner suite", function() {
|
||||
env.it("an inner spec", function() {
|
||||
@@ -212,6 +252,305 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("calls associated beforeAlls/afterAlls only once per suite", function(done) {
|
||||
var env = new j$.Env(),
|
||||
before = jasmine.createSpy('beforeAll'),
|
||||
after = jasmine.createSpy('afterAll');
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
expect(after).toHaveBeenCalled();
|
||||
expect(after.calls.count()).toBe(1);
|
||||
expect(before.calls.count()).toBe(1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
env.describe("with beforeAll and afterAll", function() {
|
||||
env.it("spec", function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
env.it("another spec", function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
env.beforeAll(before);
|
||||
env.afterAll(after);
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("calls associated beforeAlls/afterAlls only once per suite for async", function(done) {
|
||||
var env = new j$.Env(),
|
||||
before = jasmine.createSpy('beforeAll'),
|
||||
after = jasmine.createSpy('afterAll');
|
||||
|
||||
env.addReporter({
|
||||
jasmineDone: function() {
|
||||
expect(after).toHaveBeenCalled();
|
||||
expect(after.calls.count()).toBe(1);
|
||||
expect(before.calls.count()).toBe(1);
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
env.describe("with beforeAll and afterAll", function() {
|
||||
env.it("spec", function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
env.it("another spec", function() {
|
||||
expect(before).toHaveBeenCalled();
|
||||
expect(after).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
env.beforeAll(function(beforeCallbackUnderTest) {
|
||||
before();
|
||||
beforeCallbackUnderTest();
|
||||
});
|
||||
|
||||
env.afterAll(function(afterCallbackUnderTest) {
|
||||
after();
|
||||
afterCallbackUnderTest();
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("calls associated beforeAlls/afterAlls with the cascaded 'this'", function(done) {
|
||||
var env = new j$.Env();
|
||||
|
||||
env.addReporter({jasmineDone: done});
|
||||
|
||||
env.describe("with beforeAll and afterAll", function() {
|
||||
env.beforeAll(function() {
|
||||
this.x = 1;
|
||||
});
|
||||
|
||||
env.it("has an x at the root", function() {
|
||||
expect(this.x).toBe(1);
|
||||
});
|
||||
|
||||
env.describe("child that deletes", function() {
|
||||
env.beforeAll(function() {
|
||||
expect(this.x).toBe(1);
|
||||
delete this.x;
|
||||
});
|
||||
|
||||
env.it("has no x", function() {
|
||||
expect(this.x).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
env.describe("child should still have x", function() {
|
||||
env.beforeAll(function(innerDone) {
|
||||
expect(this.x).toBe(1);
|
||||
innerDone();
|
||||
});
|
||||
|
||||
env.it("has an x", function() {
|
||||
expect(this.x).toBe(1);
|
||||
delete this.x;
|
||||
});
|
||||
|
||||
env.it("still has an x", function() {
|
||||
expect(this.x).toBe(1);
|
||||
});
|
||||
|
||||
env.it("adds a y", function() {
|
||||
this.y = 2;
|
||||
expect(this.y).toBe(2);
|
||||
});
|
||||
|
||||
env.it("doesn't have y that was added in sibling", function() {
|
||||
expect(this.y).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("fails all underlying specs when the beforeAll fails", function (done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone", "jasmineDone" ]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.specDone.calls.count()).toEqual(2);
|
||||
|
||||
expect(reporter.specDone.calls.argsFor(0)[0])
|
||||
.toEqual(jasmine.objectContaining({status: 'failed'}));
|
||||
expect(reporter.specDone.calls.argsFor(0)[0].failedExpectations[0].message)
|
||||
.toEqual("Expected 1 to be 2.");
|
||||
|
||||
expect(reporter.specDone.calls.argsFor(1)[0])
|
||||
.toEqual(jasmine.objectContaining({status: 'failed'}));
|
||||
expect(reporter.specDone.calls.argsFor(1)[0].failedExpectations[0].message)
|
||||
.toEqual("Expected 1 to be 2.");
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('A suite', function(){
|
||||
env.beforeAll(function() {
|
||||
env.expect(1).toBe(2);
|
||||
});
|
||||
|
||||
env.it("spec that will be failed", function() {
|
||||
});
|
||||
|
||||
env.describe("nesting", function() {
|
||||
env.it("another spec to fail", function() {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
describe('suiteDone reporting', function(){
|
||||
it("reports when an afterAll fails an expectation", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('my suite', [
|
||||
'Expected 1 to equal 2.',
|
||||
'Expected 2 to equal 3.'
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('my suite', function() {
|
||||
env.it('my spec', function() {
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
env.expect(1).toEqual(2);
|
||||
env.expect(2).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("if there are no specs, it still reports correctly", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('outer suite', [
|
||||
'Expected 1 to equal 2.',
|
||||
'Expected 2 to equal 3.'
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('outer suite', function() {
|
||||
env.describe('inner suite', function() {
|
||||
env.it('spec', function(){ });
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
env.expect(1).toEqual(2);
|
||||
env.expect(2).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("reports when afterAll throws an exception", function(done) {
|
||||
var env = new j$.Env(),
|
||||
error = new Error('After All Exception'),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('my suite', [
|
||||
(/^Error: After All Exception/)
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('my suite', function() {
|
||||
env.it('my spec', function() {
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("reports when an async afterAll fails an expectation", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('my suite', [
|
||||
'Expected 1 to equal 2.'
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('my suite', function() {
|
||||
env.it('my spec', function() {
|
||||
});
|
||||
|
||||
env.afterAll(function(afterAllDone) {
|
||||
env.expect(1).toEqual(2);
|
||||
afterAllDone();
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("reports when an async afterAll throws an exception", function(done) {
|
||||
var env = new j$.Env(),
|
||||
error = new Error('After All Exception'),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('my suite', [
|
||||
(/^Error: After All Exception/)
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe('my suite', function() {
|
||||
env.it('my spec', function() {
|
||||
});
|
||||
|
||||
env.afterAll(function(afterAllDone) {
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
it("Allows specifying which specs and suites to run", function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [],
|
||||
@@ -248,21 +587,61 @@ describe("Env integration", function() {
|
||||
env.execute([secondSuite.id, firstSpec.id]);
|
||||
});
|
||||
|
||||
it("Functions can be spied on and have their calls tracked", function () {
|
||||
var env = new j$.Env();
|
||||
it('runs before and after all functions for runnables provided to .execute()', function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [],
|
||||
first_spec,
|
||||
second_spec;
|
||||
|
||||
var originalFunctionWasCalled = false;
|
||||
var subject = {
|
||||
spiedFunc: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
return "original result";
|
||||
}
|
||||
};
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual([
|
||||
"before",
|
||||
"first spec",
|
||||
"after",
|
||||
"before",
|
||||
"second spec",
|
||||
"after"
|
||||
]);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.describe("first suite", function() {
|
||||
env.beforeAll(function() {
|
||||
calls.push("before");
|
||||
});
|
||||
env.afterAll(function() {
|
||||
calls.push("after")
|
||||
});
|
||||
first_spec = env.it("spec", function() {
|
||||
calls.push('first spec');
|
||||
});
|
||||
second_spec = env.it("spec 2", function() {
|
||||
calls.push("second spec");
|
||||
});
|
||||
});
|
||||
|
||||
env.execute([first_spec.id, second_spec.id]);
|
||||
});
|
||||
|
||||
it("Functions can be spied on and have their calls tracked", function (done) {
|
||||
var env = new j$.Env();
|
||||
|
||||
var originalFunctionWasCalled = false;
|
||||
var subject = {
|
||||
spiedFunc: function() {
|
||||
originalFunctionWasCalled = true;
|
||||
return "original result";
|
||||
}
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: done});
|
||||
|
||||
env.it("works with spies", function() {
|
||||
var spy = env.spyOn(subject, 'spiedFunc').and.returnValue("stubbed result");
|
||||
|
||||
expect(subject.spiedFunc).toEqual(spy);
|
||||
|
||||
expect(subject.spiedFunc.calls.any()).toEqual(false);
|
||||
expect(subject.spiedFunc.calls.count()).toEqual(0);
|
||||
|
||||
@@ -281,6 +660,67 @@ describe("Env integration", function() {
|
||||
expect(subject.spiedFunc.calls.mostRecent().args).toEqual(['bar']);
|
||||
expect(subject.spiedFunc.calls.mostRecent().returnValue).toEqual("original result");
|
||||
expect(originalFunctionWasCalled).toEqual(true);
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('removes all spies added in a spec after the spec is complete', function(done) {
|
||||
var env = new j$.Env(),
|
||||
originalFoo = function() {},
|
||||
testObj = {
|
||||
foo: originalFoo
|
||||
},
|
||||
firstSpec = jasmine.createSpy('firstSpec').and.callFake(function() {
|
||||
env.spyOn(testObj, 'foo');
|
||||
}),
|
||||
secondSpec = jasmine.createSpy('secondSpec').and.callFake(function() {
|
||||
expect(testObj.foo).toBe(originalFoo);
|
||||
});
|
||||
env.describe('test suite', function() {
|
||||
env.it('spec 0', firstSpec);
|
||||
env.it('spec 1', secondSpec);
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(firstSpec).toHaveBeenCalled();
|
||||
expect(secondSpec).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({ jasmineDone: assertions });
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('removes all spies added in a suite after the suite is complete', function(done) {
|
||||
var env = new j$.Env(),
|
||||
originalFoo = function() {},
|
||||
testObj = {
|
||||
foo: originalFoo
|
||||
};
|
||||
|
||||
env.describe('test suite', function() {
|
||||
env.beforeAll(function() { env.spyOn(testObj, 'foo');})
|
||||
|
||||
env.it('spec 0', function() {
|
||||
expect(j$.isSpy(testObj.foo)).toBe(true);
|
||||
});
|
||||
|
||||
env.it('spec 1', function() {
|
||||
expect(j$.isSpy(testObj.foo)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('another suite', function() {
|
||||
env.it('spec 2', function() {
|
||||
expect(j$.isSpy(testObj.foo)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter({ jasmineDone: done });
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Mock clock can be installed and used in tests", function(done) {
|
||||
@@ -345,11 +785,11 @@ describe("Env integration", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
originalTimeout = j$.DEFAULT_TIMEOUT_INTERVAL;
|
||||
jasmine.getEnv().clock.install();
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
jasmine.getEnv().clock.uninstall();
|
||||
jasmine.clock().uninstall();
|
||||
j$.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
|
||||
});
|
||||
|
||||
@@ -371,7 +811,63 @@ describe("Env integration", function() {
|
||||
|
||||
env.it("async spec that doesn't call done", function(underTestCallback) {
|
||||
env.expect(true).toBeTruthy();
|
||||
jasmine.getEnv().clock.tick(8416);
|
||||
jasmine.clock().tick(8416);
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should wait a specified interval before failing beforeAll's and their associated specs that haven't called done", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [ "specDone", "jasmineDone" ]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.specDone.calls.count()).toEqual(2);
|
||||
expect(reporter.specDone.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({status: 'failed'}));
|
||||
expect(reporter.specDone.calls.argsFor(1)[0]).toEqual(jasmine.objectContaining({status: 'failed'}));
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
j$.DEFAULT_TIMEOUT_INTERVAL = 1290;
|
||||
|
||||
env.beforeAll(function(done) {
|
||||
jasmine.clock().tick(1290);
|
||||
});
|
||||
|
||||
env.it("spec that will be failed", function() {
|
||||
});
|
||||
|
||||
env.describe("nesting", function() {
|
||||
env.it("another spec to fail", function() {
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should wait the specified interval before reporting an afterAll that fails to call done", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReport', ['jasmineDone','suiteDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
expect(reporter.suiteDone).toHaveFailedExpecationsForSuite('my suite', [
|
||||
(/^Error: Timeout - Async callback was not invoked within timeout specified by jasmine\.DEFAULT_TIMEOUT_INTERVAL\./)
|
||||
]);
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
j$.DEFAULT_TIMEOUT_INTERVAL = 3000;
|
||||
|
||||
env.describe('my suite', function() {
|
||||
env.it('my spec', function() {
|
||||
});
|
||||
|
||||
env.afterAll(function(innerDone) {
|
||||
jasmine.clock().tick(3001);
|
||||
innerDone();
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
@@ -436,7 +932,58 @@ describe("Env integration", function() {
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: something is wrong with this spec
|
||||
describe('focused tests', function() {
|
||||
it('should only run the focused tests', function(done) {
|
||||
var env = new j$.Env(),
|
||||
calls = [];
|
||||
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual(['focused']);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.describe('a suite', function() {
|
||||
env.fit('is focused', function() {
|
||||
calls.push('focused');
|
||||
});
|
||||
|
||||
env.it('is not focused', function() {
|
||||
calls.push('freakout');
|
||||
})
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should only run focused suites', function(){
|
||||
var env = new j$.Env(),
|
||||
calls = [];
|
||||
|
||||
var assertions = function() {
|
||||
expect(calls).toEqual(['focused']);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.fdescribe('a focused suite', function() {
|
||||
env.it('is focused', function() {
|
||||
calls.push('focused');
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('a regular suite', function() {
|
||||
env.it('is not focused', function() {
|
||||
calls.push('freakout');
|
||||
})
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
it("should report as expected", function(done) {
|
||||
var env = new j$.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
@@ -502,11 +1049,7 @@ describe("Env integration", function() {
|
||||
it("Custom equality testers should be per spec", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
@@ -536,30 +1079,42 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Custom matchers should be per spec", function() {
|
||||
it("Custom equality testers should be per suite", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
matchers = {
|
||||
toFoo: function() {}
|
||||
},
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var firstSpecResult = reporter.specDone.calls.first().args[0],
|
||||
secondSpecResult = reporter.specDone.calls.argsFor(0)[0],
|
||||
thirdSpecResult = reporter.specDone.calls.mostRecent().args[0];
|
||||
|
||||
expect(firstSpecResult.status).toEqual("passed");
|
||||
expect(secondSpecResult.status).toEqual("passed");
|
||||
expect(thirdSpecResult.status).toEqual("failed");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("testing custom matchers", function() {
|
||||
env.it("with a custom matcher", function() {
|
||||
env.addMatchers(matchers);
|
||||
expect(env.expect().toFoo).toBeDefined();
|
||||
env.describe("testing custom equality testers", function() {
|
||||
env.beforeAll(function() { env.addCustomEqualityTester(function(a, b) { return true; }); });
|
||||
|
||||
env.it("with a custom tester", function() {
|
||||
env.expect("a").toEqual("b");
|
||||
});
|
||||
|
||||
env.it("without a custom matcher", function() {
|
||||
expect(env.expect().toFoo).toBeUndefined();
|
||||
env.it("with the same custom tester", function() {
|
||||
env.expect("a").toEqual("b");
|
||||
});
|
||||
});
|
||||
|
||||
env.describe("another suite", function() {
|
||||
env.it("without the custom tester", function(){
|
||||
env.expect("a").toEqual("b");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -569,11 +1124,7 @@ describe("Env integration", function() {
|
||||
it("Custom equality testers for toContain should be per spec", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineStarted",
|
||||
"jasmineDone",
|
||||
"suiteStarted",
|
||||
"suiteDone",
|
||||
"specStarted",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
@@ -596,7 +1147,7 @@ describe("Env integration", function() {
|
||||
});
|
||||
|
||||
env.it("without a custom tester", function() {
|
||||
env.expect("a").toContain("b");
|
||||
env.expect(["a"]).toContain("b");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -616,5 +1167,166 @@ describe("Env integration", function() {
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
it("Custom equality testers for toContain should be per suite", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', [
|
||||
"jasmineDone",
|
||||
"specDone"
|
||||
]);
|
||||
|
||||
reporter.jasmineDone.and.callFake(function() {
|
||||
var firstSpecResult = reporter.specDone.calls.first().args[0],
|
||||
secondSpecResult = reporter.specDone.calls.argsFor(1)[0],
|
||||
thirdSpecResult = reporter.specDone.calls.mostRecent().args[0];
|
||||
|
||||
expect(firstSpecResult.status).toEqual("passed");
|
||||
expect(secondSpecResult.status).toEqual("passed");
|
||||
expect(thirdSpecResult.status).toEqual("failed");
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("testing custom equality testers", function() {
|
||||
env.beforeAll(function() { env.addCustomEqualityTester(function(a, b) { return true; })});
|
||||
|
||||
env.it("with a custom tester", function() {
|
||||
env.expect(["a"]).toContain("b");
|
||||
});
|
||||
|
||||
env.it("also with the custom tester", function() {
|
||||
env.expect(["a"]).toContain("b");
|
||||
});
|
||||
});
|
||||
|
||||
env.describe("another suite", function() {
|
||||
env.it("without the custom tester", function() {
|
||||
env.expect(["a"]).toContain("b");
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Custom matchers should be per spec", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
matchers = {
|
||||
toFoo: function() {}
|
||||
};
|
||||
|
||||
env.describe("testing custom matchers", function() {
|
||||
env.it("with a custom matcher", function() {
|
||||
env.addMatchers(matchers);
|
||||
expect(env.expect().toFoo).toBeDefined();
|
||||
});
|
||||
|
||||
env.it("without a custom matcher", function() {
|
||||
expect(env.expect().toFoo).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter({jasmineDone: done});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("Custom matchers should be per suite", function(done) {
|
||||
var env = new j$.Env({global: { setTimeout: setTimeout }}),
|
||||
matchers = {
|
||||
toFoo: function() {}
|
||||
};
|
||||
|
||||
env.describe("testing custom matchers", function() {
|
||||
env.beforeAll(function() { env.addMatchers(matchers); });
|
||||
|
||||
env.it("with a custom matcher", function() {
|
||||
expect(env.expect().toFoo).toBeDefined();
|
||||
});
|
||||
|
||||
env.it("with the same custom matcher", function() {
|
||||
expect(env.expect().toFoo).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
env.describe("another suite", function() {
|
||||
env.it("no longer has the custom matcher", function() {
|
||||
expect(env.expect().toFoo).not.toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
env.addReporter({jasmineDone: done});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('throws an exception if you try to create a spy outside of a runnable', function (done) {
|
||||
var env = new j$.Env(),
|
||||
obj = {fn: function () {}},
|
||||
exception;
|
||||
|
||||
env.describe("a suite", function () {
|
||||
try {
|
||||
env.spyOn(obj, 'fn');
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(exception.message).toBe('Spies must be created in a before function or a spec');
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('throws an exception if you try to add a matcher outside of a runnable', function (done) {
|
||||
var env = new j$.Env(),
|
||||
obj = {fn: function () {}},
|
||||
exception;
|
||||
|
||||
env.describe("a suite", function () {
|
||||
try {
|
||||
env.addMatchers({myMatcher: function(actual,expected){return false;}});
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(exception.message).toBe('Matchers must be added in a before function or a spec');
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('throws an exception if you try to add a custom equality outside of a runnable', function (done) {
|
||||
var env = new j$.Env(),
|
||||
obj = {fn: function () {}},
|
||||
exception;
|
||||
|
||||
env.describe("a suite", function () {
|
||||
try {
|
||||
env.addCustomEqualityTester(function(first, second) {return true;});
|
||||
} catch(e) {
|
||||
exception = e;
|
||||
}
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(exception.message).toBe('Custom Equalities must be added in a before function or a spec');
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -159,7 +159,7 @@ describe("jasmine spec running", function () {
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
}
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
@@ -228,6 +228,257 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls before beforeEachs and afterAlls after afterEachs', function() {
|
||||
var actions = [];
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('runner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('runner afterAll');
|
||||
});
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('runner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function () {
|
||||
actions.push('runner afterEach');
|
||||
});
|
||||
|
||||
env.describe('Something', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner afterEach');
|
||||
});
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('inner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('inner afterAll');
|
||||
});
|
||||
|
||||
env.it('does something or other', function() {
|
||||
actions.push('it');
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll"
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should run beforeAlls and afterAlls as beforeEachs and afterEachs in the order declared when runnablesToRun is provided', function() {
|
||||
var actions = [],
|
||||
spec,
|
||||
spec2;
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('runner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('runner afterAll');
|
||||
});
|
||||
|
||||
env.beforeEach(function () {
|
||||
actions.push('runner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function () {
|
||||
actions.push('runner afterEach');
|
||||
});
|
||||
|
||||
env.describe('Something', function() {
|
||||
env.beforeEach(function() {
|
||||
actions.push('inner beforeEach');
|
||||
});
|
||||
|
||||
env.afterEach(function() {
|
||||
actions.push('inner afterEach');
|
||||
});
|
||||
|
||||
env.beforeAll(function() {
|
||||
actions.push('inner beforeAll');
|
||||
});
|
||||
|
||||
env.afterAll(function() {
|
||||
actions.push('inner afterAll');
|
||||
});
|
||||
|
||||
spec = env.it('does something', function() {
|
||||
actions.push('it');
|
||||
});
|
||||
|
||||
spec2 = env.it('does something or other', function() {
|
||||
actions.push('it2');
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll",
|
||||
|
||||
"runner beforeAll",
|
||||
"inner beforeAll",
|
||||
"runner beforeEach",
|
||||
"inner beforeEach",
|
||||
"it2",
|
||||
"inner afterEach",
|
||||
"runner afterEach",
|
||||
"inner afterAll",
|
||||
"runner afterAll"
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute([spec.id, spec2.id]);
|
||||
});
|
||||
|
||||
describe('focused runnables', function() {
|
||||
it('runs the relevant alls and eachs for each runnable', function(done) {
|
||||
var actions = [];
|
||||
env.beforeAll(function() {actions.push('beforeAll')});
|
||||
env.afterAll(function() {actions.push('afterAll')});
|
||||
env.beforeEach(function() {actions.push('beforeEach')});
|
||||
env.afterEach(function() {actions.push('afterEach')});
|
||||
|
||||
env.fdescribe('a focused suite', function() {
|
||||
env.it('is run', function() {
|
||||
actions.push('spec in fdescribe')
|
||||
});
|
||||
});
|
||||
|
||||
env.describe('an unfocused suite', function() {
|
||||
env.fit('has a focused spec', function() {
|
||||
actions.push('focused spec')
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = [
|
||||
'beforeAll',
|
||||
'beforeEach',
|
||||
'spec in fdescribe',
|
||||
'afterEach',
|
||||
'afterAll',
|
||||
|
||||
'beforeAll',
|
||||
'beforeEach',
|
||||
'focused spec',
|
||||
'afterEach',
|
||||
'afterAll'
|
||||
];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused specs in focused suites cause non-focused siblings to not run', function(done){
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.fit('focused spec', function() {
|
||||
actions.push('focused spec')
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['focused spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused suites in focused suites cause non-focused siblings to not run', function(done){
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.fdescribe('inner focused suite', function() {
|
||||
env.it('inner spec', function() {
|
||||
actions.push('inner spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['inner spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused runnables unfocus ancestor focused suites', function() {
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
env.it('unfocused spec', function() {
|
||||
actions.push('unfocused spec')
|
||||
});
|
||||
env.describe('inner focused suite', function() {
|
||||
env.fit('focused spec', function() {
|
||||
actions.push('focused spec');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
var expected = ['focused spec'];
|
||||
expect(actions).toEqual(expected);
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
env.execute();
|
||||
});
|
||||
});
|
||||
|
||||
it("shouldn't run disabled suites", function(done) {
|
||||
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
|
||||
suite = env.describe('A Suite', function() {
|
||||
@@ -236,10 +487,36 @@ describe("jasmine spec running", function () {
|
||||
});
|
||||
});
|
||||
|
||||
suite.execute(function() {
|
||||
var assertions = function() {
|
||||
expect(specInADisabledSuite).not.toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should allow top level suites to be disabled", function() {
|
||||
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
|
||||
otherSpec = jasmine.createSpy("otherSpec");
|
||||
|
||||
env.xdescribe('A disabled suite', function() {
|
||||
env.it('spec inside a disabled suite', specInADisabledSuite);
|
||||
});
|
||||
env.describe('Another suite', function() {
|
||||
env.it('another spec', otherSpec);
|
||||
});
|
||||
|
||||
var assertions = function() {
|
||||
expect(specInADisabledSuite).not.toHaveBeenCalled();
|
||||
expect(otherSpec).toHaveBeenCalled();
|
||||
done();
|
||||
};
|
||||
|
||||
env.addReporter({jasmineDone: assertions});
|
||||
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should set all pending specs to pending when a suite is run", function(done) {
|
||||
@@ -254,7 +531,6 @@ describe("jasmine spec running", function () {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// TODO: is this useful? It doesn't catch syntax errors
|
||||
xit("should recover gracefully when there are errors in describe functions", function() {
|
||||
var specs = [];
|
||||
|
||||
@@ -179,6 +179,34 @@ describe("New HtmlReporter", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("when there are suite failures", function () {
|
||||
it("displays the exceptions in their own alert bars", function(){
|
||||
var env = new j$.Env(),
|
||||
container = document.createElement("div"),
|
||||
getContainer = function() { return container; },
|
||||
reporter = new j$.HtmlReporter({
|
||||
env: env,
|
||||
getContainer: getContainer,
|
||||
createElement: function() { return document.createElement.apply(document, arguments); },
|
||||
createTextNode: function() { return document.createTextNode.apply(document, arguments); }
|
||||
});
|
||||
|
||||
reporter.initialize();
|
||||
|
||||
reporter.jasmineStarted({});
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'My After All Exception' }] });
|
||||
reporter.suiteDone({ failedExpectations: [{ message: 'My Other Exception' }] });
|
||||
reporter.jasmineDone({});
|
||||
|
||||
var alertBars = container.querySelectorAll(".alert .bar");
|
||||
|
||||
expect(alertBars.length).toEqual(3);
|
||||
expect(alertBars[1].innerHTML).toMatch(/My After All Exception/);
|
||||
expect(alertBars[1].getAttribute("class")).toEqual('bar errored');
|
||||
expect(alertBars[2].innerHTML).toMatch(/My Other Exception/);
|
||||
});
|
||||
});
|
||||
|
||||
describe("when Jasmine is done", function() {
|
||||
it("adds EMPTY to the link title of specs that have no expectations", function() {
|
||||
if (!window.console) {
|
||||
|
||||
195
spec/node_suite.js
Normal file
195
spec/node_suite.js
Normal file
@@ -0,0 +1,195 @@
|
||||
var fs = require('fs');
|
||||
var util = require('util');
|
||||
var path = require('path');
|
||||
|
||||
// boot code for jasmine
|
||||
var jasmineRequire = require('../lib/jasmine-core/jasmine.js');
|
||||
var jasmine = jasmineRequire.core(jasmineRequire);
|
||||
|
||||
var consoleFns = require('../lib/console/console.js');
|
||||
extend(jasmineRequire, consoleFns);
|
||||
jasmineRequire.console(jasmineRequire, jasmine);
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var jasmineInterface = {
|
||||
describe: function(description, specDefinitions) {
|
||||
return env.describe(description, specDefinitions);
|
||||
},
|
||||
|
||||
xdescribe: function(description, specDefinitions) {
|
||||
return env.xdescribe(description, specDefinitions);
|
||||
},
|
||||
|
||||
it: function(desc, func) {
|
||||
return env.it(desc, func);
|
||||
},
|
||||
|
||||
xit: function(desc, func) {
|
||||
return env.xit(desc, func);
|
||||
},
|
||||
|
||||
beforeEach: function(beforeEachFunction) {
|
||||
return env.beforeEach(beforeEachFunction);
|
||||
},
|
||||
|
||||
afterEach: function(afterEachFunction) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
spyOn: function(obj, methodName) {
|
||||
return env.spyOn(obj, methodName);
|
||||
},
|
||||
|
||||
jsApiReporter: new jasmine.JsApiReporter({
|
||||
timer: new jasmine.Timer()
|
||||
}),
|
||||
|
||||
beforeAll: function(beforeAllFunction) {
|
||||
return env.beforeAll(beforeAllFunction);
|
||||
},
|
||||
|
||||
afterAll: function(afterAllFunction) {
|
||||
return env.afterAll(afterAllFunction);
|
||||
}
|
||||
};
|
||||
|
||||
extend(global, jasmineInterface);
|
||||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) destination[property] = source[property];
|
||||
return destination;
|
||||
}
|
||||
|
||||
jasmine.addCustomEqualityTester = function(tester) {
|
||||
env.addCustomEqualityTester(tester);
|
||||
};
|
||||
|
||||
jasmine.addMatchers = function(matchers) {
|
||||
return env.addMatchers(matchers);
|
||||
};
|
||||
|
||||
jasmine.clock = function() {
|
||||
return env.clock;
|
||||
};
|
||||
|
||||
// Jasmine "runner"
|
||||
function executeSpecs(specs, done, isVerbose, showColors) {
|
||||
global.jasmine = jasmine;
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var filename = specs[i];
|
||||
require(filename.replace(/\.\w+$/, ""));
|
||||
}
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
var consoleReporter = new jasmine.ConsoleReporter({
|
||||
print: util.print,
|
||||
onComplete: done,
|
||||
showColors: showColors,
|
||||
timer: new jasmine.Timer()
|
||||
});
|
||||
|
||||
env.addReporter(consoleReporter);
|
||||
env.execute();
|
||||
}
|
||||
|
||||
function getFiles(dir, matcher) {
|
||||
var allFiles = [];
|
||||
|
||||
if (fs.statSync(dir).isFile() && dir.match(matcher)) {
|
||||
allFiles.push(dir);
|
||||
} else {
|
||||
var files = fs.readdirSync(dir);
|
||||
for (var i = 0, len = files.length; i < len; ++i) {
|
||||
var filename = dir + '/' + files[i];
|
||||
if (fs.statSync(filename).isFile() && filename.match(matcher)) {
|
||||
allFiles.push(filename);
|
||||
} else if (fs.statSync(filename).isDirectory()) {
|
||||
var subfiles = getFiles(filename);
|
||||
subfiles.forEach(function(result) {
|
||||
allFiles.push(result);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return allFiles;
|
||||
}
|
||||
|
||||
function getSpecFiles(dir) {
|
||||
return getFiles(dir, new RegExp("Spec.js$"));
|
||||
}
|
||||
|
||||
var j$require = (function() {
|
||||
var exported = {},
|
||||
j$req;
|
||||
|
||||
global.getJasmineRequireObj = getJasmineRequireObj;
|
||||
|
||||
j$req = require(__dirname + "/../src/core/requireCore.js");
|
||||
extend(j$req, require(__dirname + "/../src/console/requireConsole.js"));
|
||||
|
||||
var srcFiles = getFiles(__dirname + "/../src/core");
|
||||
srcFiles.push(__dirname + "/../src/version.js");
|
||||
srcFiles.push(__dirname + "/../src/console/ConsoleReporter.js");
|
||||
|
||||
for (var i = 0; i < srcFiles.length; i++) {
|
||||
require(srcFiles[i]);
|
||||
}
|
||||
extend(j$req, exported);
|
||||
|
||||
delete global.getJasmineRequireObj;
|
||||
|
||||
return j$req;
|
||||
|
||||
function getJasmineRequireObj() {
|
||||
return exported;
|
||||
}
|
||||
}());
|
||||
|
||||
j$ = j$require.core(j$require);
|
||||
j$require.console(j$require, j$);
|
||||
|
||||
// options from command line
|
||||
var isVerbose = false;
|
||||
var showColors = true;
|
||||
var perfSuite = false;
|
||||
|
||||
process.argv.forEach(function(arg) {
|
||||
switch (arg) {
|
||||
case '--color':
|
||||
showColors = true;
|
||||
break;
|
||||
case '--noColor':
|
||||
showColors = false;
|
||||
break;
|
||||
case '--verbose':
|
||||
isVerbose = true;
|
||||
break;
|
||||
case '--perf':
|
||||
perfSuite = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
specs = [];
|
||||
|
||||
if (perfSuite) {
|
||||
specs = getFiles(__dirname + '/performance', new RegExp("test.js$"));
|
||||
} else {
|
||||
var consoleSpecs = getSpecFiles(__dirname + "/console"),
|
||||
coreSpecs = getSpecFiles(__dirname + "/core"),
|
||||
specs = consoleSpecs.concat(coreSpecs);
|
||||
}
|
||||
|
||||
executeSpecs(specs, function(passed) {
|
||||
if (passed) {
|
||||
process.exit(0);
|
||||
} else {
|
||||
process.exit(1);
|
||||
}
|
||||
}, isVerbose, showColors);
|
||||
@@ -19,7 +19,8 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
red: '\x1B[31m',
|
||||
yellow: '\x1B[33m',
|
||||
none: '\x1B[0m'
|
||||
};
|
||||
},
|
||||
failedSuites = [];
|
||||
|
||||
this.jasmineStarted = function() {
|
||||
specCount = 0;
|
||||
@@ -54,9 +55,12 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
printNewline();
|
||||
var seconds = timer.elapsed() / 1000;
|
||||
print('Finished in ' + seconds + ' ' + plural('second', seconds));
|
||||
|
||||
printNewline();
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
suiteFailureDetails(failedSuites[i]);
|
||||
}
|
||||
|
||||
onComplete(failureCount === 0);
|
||||
};
|
||||
|
||||
@@ -81,6 +85,13 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
}
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failureCount++;
|
||||
failedSuites.push(result);
|
||||
}
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function printNewline() {
|
||||
@@ -125,6 +136,17 @@ getJasmineRequireObj().ConsoleReporter = function() {
|
||||
|
||||
printNewline();
|
||||
}
|
||||
|
||||
function suiteFailureDetails(result) {
|
||||
for (var i = 0; i < result.failedExpectations.length; i++) {
|
||||
printNewline();
|
||||
print(colored('red', 'An error was thrown in an afterAll'));
|
||||
printNewline();
|
||||
print(colored('red', 'AfterAll ' + result.failedExpectations[i].message));
|
||||
|
||||
}
|
||||
printNewline();
|
||||
}
|
||||
}
|
||||
|
||||
return ConsoleReporter;
|
||||
|
||||
292
src/core/Env.js
292
src/core/Env.js
@@ -14,11 +14,19 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
this.clock = new j$.Clock(global, new j$.DelayedFunctionScheduler(), new j$.MockDate(global));
|
||||
|
||||
var runnableLookupTable = {};
|
||||
|
||||
var spies = [];
|
||||
var runnableResources = {};
|
||||
|
||||
var currentSpec = null;
|
||||
var currentSuite = null;
|
||||
var currentlyExecutingSuites = [];
|
||||
var currentDeclarationSuite = null;
|
||||
|
||||
var currentSuite = function() {
|
||||
return currentlyExecutingSuites[currentlyExecutingSuites.length - 1];
|
||||
};
|
||||
|
||||
var currentRunnable = function() {
|
||||
return currentSpec || currentSuite();
|
||||
};
|
||||
|
||||
var reporter = new j$.ReportDispatcher([
|
||||
'jasmineStarted',
|
||||
@@ -33,11 +41,21 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return true;
|
||||
};
|
||||
|
||||
var equalityTesters = [];
|
||||
|
||||
var customEqualityTesters = [];
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
customEqualityTesters.push(tester);
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Custom Equalities must be added in a before function or a spec');
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Matchers must be added in a before function or a spec');
|
||||
}
|
||||
var customMatchers = runnableResources[currentRunnable().id].customMatchers;
|
||||
for (var matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
@@ -55,7 +73,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.Factory({
|
||||
util: j$.matchersUtil,
|
||||
customEqualityTesters: customEqualityTesters,
|
||||
customEqualityTesters: runnableResources[spec.id].customEqualityTesters,
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -65,30 +84,44 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
var specStarted = function(spec) {
|
||||
currentSpec = spec;
|
||||
reporter.specStarted(spec.result);
|
||||
var defaultResourcesForRunnable = function(id, parentRunnableId) {
|
||||
var resources = {spies: [], customEqualityTesters: [], customMatchers: {}};
|
||||
|
||||
if(runnableResources[parentRunnableId]){
|
||||
resources.customEqualityTesters = j$.util.clone(runnableResources[parentRunnableId].customEqualityTesters);
|
||||
resources.customMatchers = j$.util.clone(runnableResources[parentRunnableId].customMatchers);
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
};
|
||||
|
||||
var beforeFns = function(suite) {
|
||||
var clearResourcesForRunnable = function(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
};
|
||||
|
||||
var beforeAndAfterFns = function(suite, runnablesExplictlySet) {
|
||||
return function() {
|
||||
var befores = [];
|
||||
var befores = [],
|
||||
afters = [],
|
||||
beforeAlls = [],
|
||||
afterAlls = [];
|
||||
|
||||
while(suite) {
|
||||
befores = befores.concat(suite.beforeFns);
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return befores.reverse();
|
||||
};
|
||||
};
|
||||
|
||||
var afterFns = function(suite) {
|
||||
return function() {
|
||||
var afters = [];
|
||||
while(suite) {
|
||||
afters = afters.concat(suite.afterFns);
|
||||
|
||||
if (runnablesExplictlySet()) {
|
||||
beforeAlls = beforeAlls.concat(suite.beforeAllFns);
|
||||
afterAlls = afterAlls.concat(suite.afterAllFns);
|
||||
}
|
||||
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
return afters;
|
||||
return {
|
||||
befores: beforeAlls.reverse().concat(befores.reverse()),
|
||||
afters: afters.concat(afterAlls)
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -146,65 +179,54 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
id: getNextSuiteId(),
|
||||
description: 'Jasmine__TopLevel__Suite',
|
||||
queueRunner: queueRunnerFactory,
|
||||
resultCallback: function() {} // TODO - hook this up
|
||||
resultCallback: function(attrs) {
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
});
|
||||
runnableLookupTable[topSuite.id] = topSuite;
|
||||
currentSuite = topSuite;
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
currentDeclarationSuite = topSuite;
|
||||
|
||||
this.topSuite = function() {
|
||||
return topSuite;
|
||||
};
|
||||
|
||||
this.execute = function(runnablesToRun) {
|
||||
runnablesToRun = runnablesToRun || [topSuite.id];
|
||||
if(runnablesToRun) {
|
||||
runnablesExplictlySet = true;
|
||||
} else if (focusedRunnables.length) {
|
||||
runnablesExplictlySet = true;
|
||||
runnablesToRun = focusedRunnables;
|
||||
} else {
|
||||
runnablesToRun = [topSuite.id];
|
||||
}
|
||||
|
||||
var allFns = [];
|
||||
for(var i = 0; i < runnablesToRun.length; i++) {
|
||||
var runnable = runnableLookupTable[runnablesToRun[i]];
|
||||
allFns.push((function(runnable) { return function(done) { runnable.execute(done); }; })(runnable));
|
||||
allFns.push((function(runnable) { return { fn: function(done) { runnable.execute(done); } }; })(runnable));
|
||||
}
|
||||
|
||||
reporter.jasmineStarted({
|
||||
totalSpecsDefined: totalSpecsDefined
|
||||
});
|
||||
|
||||
queueRunnerFactory({fns: allFns, onComplete: reporter.jasmineDone});
|
||||
queueRunnerFactory({queueableFns: allFns, onComplete: reporter.jasmineDone});
|
||||
};
|
||||
|
||||
this.addReporter = function(reporterToAdd) {
|
||||
reporter.addReporter(reporterToAdd);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
j$.Expectation.addMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
var spyRegistry = new j$.SpyRegistry({currentSpies: function() {
|
||||
if(!currentRunnable()) {
|
||||
throw new Error('Spies must be created in a before function or a spec');
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
}});
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(methodName + ' has already been spied upon');
|
||||
}
|
||||
|
||||
var spy = j$.createSpy(methodName, obj[methodName]);
|
||||
|
||||
spies.push({
|
||||
spy: spy,
|
||||
baseObj: obj,
|
||||
methodName: methodName,
|
||||
originalValue: obj[methodName]
|
||||
});
|
||||
|
||||
obj[methodName] = spy;
|
||||
|
||||
return spy;
|
||||
this.spyOn = function() {
|
||||
return spyRegistry.spyOn.apply(spyRegistry, arguments);
|
||||
};
|
||||
|
||||
var suiteFactory = function(description) {
|
||||
@@ -212,40 +234,33 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
env: self,
|
||||
id: getNextSuiteId(),
|
||||
description: description,
|
||||
parentSuite: currentSuite,
|
||||
parentSuite: currentDeclarationSuite,
|
||||
queueRunner: queueRunnerFactory,
|
||||
onStart: suiteStarted,
|
||||
expectationFactory: expectationFactory,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
resultCallback: function(attrs) {
|
||||
if (!suite.disabled) {
|
||||
clearResourcesForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
}
|
||||
reporter.suiteDone(attrs);
|
||||
}
|
||||
});
|
||||
|
||||
runnableLookupTable[suite.id] = suite;
|
||||
return suite;
|
||||
|
||||
function suiteStarted(suite) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result);
|
||||
}
|
||||
};
|
||||
|
||||
this.describe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
|
||||
var parentSuite = currentSuite;
|
||||
parentSuite.addChild(suite);
|
||||
currentSuite = suite;
|
||||
|
||||
var declarationError = null;
|
||||
try {
|
||||
specDefinitions.call(suite);
|
||||
} catch (e) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
this.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentSuite = parentSuite;
|
||||
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
return suite;
|
||||
};
|
||||
|
||||
@@ -255,15 +270,75 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return suite;
|
||||
};
|
||||
|
||||
var focusedRunnables = [];
|
||||
|
||||
this.fdescribe = function(description, specDefinitions) {
|
||||
var suite = suiteFactory(description);
|
||||
suite.isFocused = true;
|
||||
|
||||
focusedRunnables.push(suite.id);
|
||||
unfocusAncestor();
|
||||
addSpecsToSuite(suite, specDefinitions);
|
||||
|
||||
return suite;
|
||||
};
|
||||
|
||||
function addSpecsToSuite(suite, specDefinitions) {
|
||||
var parentSuite = currentDeclarationSuite;
|
||||
parentSuite.addChild(suite);
|
||||
currentDeclarationSuite = suite;
|
||||
|
||||
var declarationError = null;
|
||||
try {
|
||||
specDefinitions.call(suite);
|
||||
} catch (e) {
|
||||
declarationError = e;
|
||||
}
|
||||
|
||||
if (declarationError) {
|
||||
self.it('encountered a declaration exception', function() {
|
||||
throw declarationError;
|
||||
});
|
||||
}
|
||||
|
||||
currentDeclarationSuite = parentSuite;
|
||||
}
|
||||
|
||||
function findFocusedAncestor(suite) {
|
||||
while (suite) {
|
||||
if (suite.isFocused) {
|
||||
return suite.id;
|
||||
}
|
||||
suite = suite.parentSuite;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function unfocusAncestor() {
|
||||
var focusedAncestor = findFocusedAncestor(currentDeclarationSuite);
|
||||
if (focusedAncestor) {
|
||||
for (var i = 0; i < focusedRunnables.length; i++) {
|
||||
if (focusedRunnables[i] === focusedAncestor) {
|
||||
focusedRunnables.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var runnablesExplictlySet = false;
|
||||
|
||||
var runnablesExplictlySetGetter = function(){
|
||||
return runnablesExplictlySet;
|
||||
};
|
||||
|
||||
var specFactory = function(description, fn, suite) {
|
||||
totalSpecsDefined++;
|
||||
|
||||
var spec = new j$.Spec({
|
||||
id: getNextSpecId(),
|
||||
beforeFns: beforeFns(suite),
|
||||
afterFns: afterFns(suite),
|
||||
beforeAndAfterFns: beforeAndAfterFns(suite, runnablesExplictlySetGetter),
|
||||
expectationFactory: expectationFactory,
|
||||
exceptionFormatter: exceptionFormatter,
|
||||
resultCallback: specResultCallback,
|
||||
getSpecName: function(spec) {
|
||||
return getSpecName(spec, suite);
|
||||
@@ -272,7 +347,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
description: description,
|
||||
expectationResultFactory: expectationResultFactory,
|
||||
queueRunnerFactory: queueRunnerFactory,
|
||||
fn: fn
|
||||
userContext: function() { return suite.clonedSharedUserContext(); },
|
||||
queueableFn: { fn: fn, type: 'it', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } }
|
||||
});
|
||||
|
||||
runnableLookupTable[spec.id] = spec;
|
||||
@@ -283,30 +359,22 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
return spec;
|
||||
|
||||
function removeAllSpies() {
|
||||
for (var i = 0; i < spies.length; i++) {
|
||||
var spyEntry = spies[i];
|
||||
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
|
||||
}
|
||||
spies = [];
|
||||
}
|
||||
|
||||
function specResultCallback(result) {
|
||||
removeAllSpies();
|
||||
j$.Expectation.resetMatchers();
|
||||
customEqualityTesters = [];
|
||||
clearResourcesForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
reporter.specDone(result);
|
||||
}
|
||||
};
|
||||
|
||||
var suiteStarted = function(suite) {
|
||||
reporter.suiteStarted(suite.result);
|
||||
function specStarted(spec) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result);
|
||||
}
|
||||
};
|
||||
|
||||
this.it = function(description, fn) {
|
||||
var spec = specFactory(description, fn, currentSuite);
|
||||
currentSuite.addChild(spec);
|
||||
var spec = specFactory(description, fn, currentDeclarationSuite);
|
||||
currentDeclarationSuite.addChild(spec);
|
||||
return spec;
|
||||
};
|
||||
|
||||
@@ -316,20 +384,36 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.fit = function(description, fn ){
|
||||
var spec = this.it(description, fn);
|
||||
|
||||
focusedRunnables.push(spec.id);
|
||||
unfocusAncestor();
|
||||
return spec;
|
||||
};
|
||||
|
||||
this.expect = function(actual) {
|
||||
if (!currentSpec) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error('\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out');
|
||||
}
|
||||
|
||||
return currentSpec.expect(actual);
|
||||
return currentRunnable().expect(actual);
|
||||
};
|
||||
|
||||
this.beforeEach = function(beforeEachFunction) {
|
||||
currentSuite.beforeEach(beforeEachFunction);
|
||||
currentDeclarationSuite.beforeEach({ fn: beforeEachFunction, type: 'beforeEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.beforeAll = function(beforeAllFunction) {
|
||||
currentDeclarationSuite.beforeAll({ fn: beforeAllFunction, type: 'beforeAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.afterEach = function(afterEachFunction) {
|
||||
currentSuite.afterEach(afterEachFunction);
|
||||
currentDeclarationSuite.afterEach({ fn: afterEachFunction, type: 'afterEach', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.afterAll = function(afterAllFunction) {
|
||||
currentDeclarationSuite.afterAll({ fn: afterAllFunction, type: 'afterAll', timeout: function() { return j$.DEFAULT_TIMEOUT_INTERVAL; } });
|
||||
};
|
||||
|
||||
this.pending = function() {
|
||||
@@ -343,7 +427,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
message += error.message || error;
|
||||
}
|
||||
|
||||
currentSpec.addExpectationResult(false, {
|
||||
currentRunnable().addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
getJasmineRequireObj().Expectation = function() {
|
||||
|
||||
var matchers = {};
|
||||
|
||||
function Expectation(options) {
|
||||
this.util = options.util || { buildFailureMessage: function() {} };
|
||||
this.customEqualityTesters = options.customEqualityTesters || [];
|
||||
@@ -9,8 +7,9 @@ getJasmineRequireObj().Expectation = function() {
|
||||
this.addExpectationResult = options.addExpectationResult || function(){};
|
||||
this.isNot = options.isNot;
|
||||
|
||||
for (var matcherName in matchers) {
|
||||
this[matcherName] = matchers[matcherName];
|
||||
var customMatchers = options.customMatchers || {};
|
||||
for (var matcherName in customMatchers) {
|
||||
this[matcherName] = Expectation.prototype.wrapCompare(matcherName, customMatchers[matcherName]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,19 +76,6 @@ getJasmineRequireObj().Expectation = function() {
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.addMatchers = function(matchersToAdd) {
|
||||
for (var name in matchersToAdd) {
|
||||
var matcher = matchersToAdd[name];
|
||||
matchers[name] = Expectation.prototype.wrapCompare(name, matcher);
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.resetMatchers = function() {
|
||||
for (var name in matchers) {
|
||||
delete matchers[name];
|
||||
}
|
||||
};
|
||||
|
||||
Expectation.Factory = function(options) {
|
||||
options = options || {};
|
||||
|
||||
|
||||
@@ -11,31 +11,31 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
|
||||
function QueueRunner(attrs) {
|
||||
this.fns = attrs.fns || [];
|
||||
this.queueableFns = attrs.queueableFns || [];
|
||||
this.onComplete = attrs.onComplete || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.onException = attrs.onException || function() {};
|
||||
this.catchException = attrs.catchException || function() { return true; };
|
||||
this.enforceTimeout = attrs.enforceTimeout || function() { return false; };
|
||||
this.userContext = {};
|
||||
this.userContext = attrs.userContext || {};
|
||||
this.timer = attrs.timeout || {setTimeout: setTimeout, clearTimeout: clearTimeout};
|
||||
}
|
||||
|
||||
QueueRunner.prototype.execute = function() {
|
||||
this.run(this.fns, 0);
|
||||
this.run(this.queueableFns, 0);
|
||||
};
|
||||
|
||||
QueueRunner.prototype.run = function(fns, recursiveIndex) {
|
||||
var length = fns.length,
|
||||
self = this,
|
||||
iterativeIndex;
|
||||
QueueRunner.prototype.run = function(queueableFns, recursiveIndex) {
|
||||
var length = queueableFns.length,
|
||||
self = this,
|
||||
iterativeIndex;
|
||||
|
||||
|
||||
for(iterativeIndex = recursiveIndex; iterativeIndex < length; iterativeIndex++) {
|
||||
var fn = fns[iterativeIndex];
|
||||
if (fn.length > 0) {
|
||||
return attemptAsync(fn);
|
||||
var queueableFn = queueableFns[iterativeIndex];
|
||||
if (queueableFn.fn.length > 0) {
|
||||
return attemptAsync(queueableFn);
|
||||
} else {
|
||||
attemptSync(fn);
|
||||
attemptSync(queueableFn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,41 +45,46 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
this.clearStack(this.onComplete);
|
||||
}
|
||||
|
||||
function attemptSync(fn) {
|
||||
function attemptSync(queueableFn) {
|
||||
try {
|
||||
fn.call(self.userContext);
|
||||
queueableFn.fn.call(self.userContext);
|
||||
} catch (e) {
|
||||
handleException(e);
|
||||
handleException(e, queueableFn);
|
||||
}
|
||||
}
|
||||
|
||||
function attemptAsync(fn) {
|
||||
function attemptAsync(queueableFn) {
|
||||
var clearTimeout = function () {
|
||||
Function.prototype.apply.apply(self.timer.clearTimeout, [j$.getGlobal(), [timeoutId]]);
|
||||
},
|
||||
next = once(function () {
|
||||
clearTimeout(timeoutId);
|
||||
self.run(fns, iterativeIndex + 1);
|
||||
self.run(queueableFns, iterativeIndex + 1);
|
||||
}),
|
||||
timeoutId;
|
||||
|
||||
if (self.enforceTimeout()) {
|
||||
if (queueableFn.timeout) {
|
||||
timeoutId = Function.prototype.apply.apply(self.timer.setTimeout, [j$.getGlobal(), [function() {
|
||||
self.onException(new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.'));
|
||||
var error = new Error('Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.');
|
||||
onException(error, queueableFn);
|
||||
next();
|
||||
}, j$.DEFAULT_TIMEOUT_INTERVAL]]);
|
||||
}, queueableFn.timeout()]]);
|
||||
}
|
||||
|
||||
try {
|
||||
fn.call(self.userContext, next);
|
||||
queueableFn.fn.call(self.userContext, next);
|
||||
} catch (e) {
|
||||
handleException(e);
|
||||
handleException(e, queueableFn);
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
function handleException(e) {
|
||||
function onException(e, queueableFn) {
|
||||
self.onException(e);
|
||||
}
|
||||
|
||||
function handleException(e, queueableFn) {
|
||||
onException(e, queueableFn);
|
||||
if (!self.catchException(e)) {
|
||||
//TODO: set a var when we catch an exception and
|
||||
//use a finally block to close the loop in a nice way..
|
||||
|
||||
@@ -4,17 +4,16 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
this.id = attrs.id;
|
||||
this.description = attrs.description || '';
|
||||
this.fn = attrs.fn;
|
||||
this.beforeFns = attrs.beforeFns || function() { return []; };
|
||||
this.afterFns = attrs.afterFns || function() { return []; };
|
||||
this.queueableFn = attrs.queueableFn;
|
||||
this.beforeAndAfterFns = attrs.beforeAndAfterFns || function() { return {befores: [], afters: []}; };
|
||||
this.userContext = attrs.userContext || function() { return {}; };
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.exceptionFormatter = attrs.exceptionFormatter || function() {};
|
||||
this.getSpecName = attrs.getSpecName || function() { return ''; };
|
||||
this.expectationResultFactory = attrs.expectationResultFactory || function() { };
|
||||
this.queueRunnerFactory = attrs.queueRunnerFactory || function() {};
|
||||
this.catchingExceptions = attrs.catchingExceptions || function() { return true; };
|
||||
|
||||
if (!this.fn) {
|
||||
if (!this.queueableFn.fn) {
|
||||
this.pend();
|
||||
}
|
||||
|
||||
@@ -50,30 +49,16 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
return;
|
||||
}
|
||||
|
||||
var allFns = this.beforeFns().concat(this.fn).concat(this.afterFns());
|
||||
var fns = this.beforeAndAfterFns();
|
||||
var allFns = fns.befores.concat(this.queueableFn).concat(fns.afters);
|
||||
|
||||
this.queueRunnerFactory({
|
||||
fns: allFns,
|
||||
onException: onException,
|
||||
queueableFns: allFns,
|
||||
onException: function() { self.onException.apply(self, arguments); },
|
||||
onComplete: complete,
|
||||
enforceTimeout: function() { return true; }
|
||||
userContext: this.userContext()
|
||||
});
|
||||
|
||||
function onException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
self.pend();
|
||||
return;
|
||||
}
|
||||
|
||||
self.addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
});
|
||||
}
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.status();
|
||||
self.resultCallback(self.result);
|
||||
@@ -84,6 +69,21 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.onException = function onException(e) {
|
||||
if (Spec.isPendingSpecException(e)) {
|
||||
this.pend();
|
||||
return;
|
||||
}
|
||||
|
||||
this.addExpectationResult(false, {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: e
|
||||
});
|
||||
};
|
||||
|
||||
Spec.prototype.disable = function() {
|
||||
this.disabled = true;
|
||||
};
|
||||
@@ -108,6 +108,10 @@ getJasmineRequireObj().Spec = function(j$) {
|
||||
}
|
||||
};
|
||||
|
||||
Spec.prototype.isExecutable = function() {
|
||||
return !this.disabled && !this.markedPending;
|
||||
};
|
||||
|
||||
Spec.prototype.getFullName = function() {
|
||||
return this.getSpecName(this);
|
||||
};
|
||||
|
||||
45
src/core/SpyRegistry.js
Normal file
45
src/core/SpyRegistry.js
Normal file
@@ -0,0 +1,45 @@
|
||||
getJasmineRequireObj().SpyRegistry = function(j$) {
|
||||
|
||||
function SpyRegistry(options) {
|
||||
options = options || {};
|
||||
var currentSpies = options.currentSpies || function() { return []; };
|
||||
|
||||
this.spyOn = function(obj, methodName) {
|
||||
if (j$.util.isUndefined(obj)) {
|
||||
throw new Error('spyOn could not find an object to spy upon for ' + methodName + '()');
|
||||
}
|
||||
|
||||
if (j$.util.isUndefined(obj[methodName])) {
|
||||
throw new Error(methodName + '() method does not exist');
|
||||
}
|
||||
|
||||
if (obj[methodName] && j$.isSpy(obj[methodName])) {
|
||||
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
|
||||
throw new Error(methodName + ' has already been spied upon');
|
||||
}
|
||||
|
||||
var spy = j$.createSpy(methodName, obj[methodName]);
|
||||
|
||||
currentSpies().push({
|
||||
spy: spy,
|
||||
baseObj: obj,
|
||||
methodName: methodName,
|
||||
originalValue: obj[methodName]
|
||||
});
|
||||
|
||||
obj[methodName] = spy;
|
||||
|
||||
return spy;
|
||||
};
|
||||
|
||||
this.clearSpies = function() {
|
||||
var spies = currentSpies();
|
||||
for (var i = 0; i < spies.length; i++) {
|
||||
var spyEntry = spies[i];
|
||||
spyEntry.baseObj[spyEntry.methodName] = spyEntry.originalValue;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return SpyRegistry;
|
||||
};
|
||||
@@ -7,9 +7,13 @@ getJasmineRequireObj().Suite = function() {
|
||||
this.onStart = attrs.onStart || function() {};
|
||||
this.resultCallback = attrs.resultCallback || function() {};
|
||||
this.clearStack = attrs.clearStack || function(fn) {fn();};
|
||||
this.expectationFactory = attrs.expectationFactory;
|
||||
this.expectationResultFactory = attrs.expectationResultFactory;
|
||||
|
||||
this.beforeFns = [];
|
||||
this.afterFns = [];
|
||||
this.beforeAllFns = [];
|
||||
this.afterAllFns = [];
|
||||
this.queueRunner = attrs.queueRunner || function() {};
|
||||
this.disabled = false;
|
||||
|
||||
@@ -17,12 +21,16 @@ getJasmineRequireObj().Suite = function() {
|
||||
|
||||
this.result = {
|
||||
id: this.id,
|
||||
status: this.disabled ? 'disabled' : '',
|
||||
description: this.description,
|
||||
fullName: this.getFullName()
|
||||
fullName: this.getFullName(),
|
||||
failedExpectations: []
|
||||
};
|
||||
}
|
||||
|
||||
Suite.prototype.expect = function(actual) {
|
||||
return this.expectationFactory(actual, this);
|
||||
};
|
||||
|
||||
Suite.prototype.getFullName = function() {
|
||||
var fullName = this.description;
|
||||
for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) {
|
||||
@@ -42,10 +50,18 @@ getJasmineRequireObj().Suite = function() {
|
||||
this.beforeFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.beforeAll = function(fn) {
|
||||
this.beforeAllFns.push(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.afterEach = function(fn) {
|
||||
this.afterFns.unshift(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.afterAll = function(fn) {
|
||||
this.afterAllFns.push(fn);
|
||||
};
|
||||
|
||||
Suite.prototype.addChild = function(child) {
|
||||
this.children.push(child);
|
||||
};
|
||||
@@ -62,16 +78,25 @@ getJasmineRequireObj().Suite = function() {
|
||||
|
||||
var allFns = [];
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
allFns.push(wrapChildAsAsync(this.children[i]));
|
||||
if (this.isExecutable()) {
|
||||
allFns = allFns.concat(this.beforeAllFns);
|
||||
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
allFns.push(wrapChildAsAsync(this.children[i]));
|
||||
}
|
||||
|
||||
allFns = allFns.concat(this.afterAllFns);
|
||||
}
|
||||
|
||||
this.queueRunner({
|
||||
fns: allFns,
|
||||
onComplete: complete
|
||||
queueableFns: allFns,
|
||||
onComplete: complete,
|
||||
userContext: this.sharedUserContext(),
|
||||
onException: function() { self.onException.apply(self, arguments); }
|
||||
});
|
||||
|
||||
function complete() {
|
||||
self.result.status = self.disabled ? 'disabled' : 'finished';
|
||||
self.resultCallback(self.result);
|
||||
|
||||
if (onComplete) {
|
||||
@@ -80,10 +105,82 @@ getJasmineRequireObj().Suite = function() {
|
||||
}
|
||||
|
||||
function wrapChildAsAsync(child) {
|
||||
return function(done) { child.execute(done); };
|
||||
return { fn: function(done) { child.execute(done); } };
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.isExecutable = function() {
|
||||
var foundActive = false;
|
||||
for(var i = 0; i < this.children.length; i++) {
|
||||
if(this.children[i].isExecutable()) {
|
||||
foundActive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return foundActive;
|
||||
};
|
||||
|
||||
Suite.prototype.sharedUserContext = function() {
|
||||
if (!this.sharedContext) {
|
||||
this.sharedContext = this.parentSuite ? clone(this.parentSuite.sharedUserContext()) : {};
|
||||
}
|
||||
|
||||
return this.sharedContext;
|
||||
};
|
||||
|
||||
Suite.prototype.clonedSharedUserContext = function() {
|
||||
return clone(this.sharedUserContext());
|
||||
};
|
||||
|
||||
Suite.prototype.onException = function() {
|
||||
if(isAfterAll(this.children)) {
|
||||
var data = {
|
||||
matcherName: '',
|
||||
passed: false,
|
||||
expected: '',
|
||||
actual: '',
|
||||
error: arguments[0]
|
||||
};
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.onException.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Suite.prototype.addExpectationResult = function () {
|
||||
if(isAfterAll(this.children) && isFailure(arguments)){
|
||||
var data = arguments[1];
|
||||
this.result.failedExpectations.push(this.expectationResultFactory(data));
|
||||
} else {
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
child.addExpectationResult.apply(child, arguments);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function isAfterAll(children) {
|
||||
return children && children[0].result.status;
|
||||
}
|
||||
|
||||
function isFailure(args) {
|
||||
return !args[0];
|
||||
}
|
||||
|
||||
function clone(obj) {
|
||||
var clonedObj = {};
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
clonedObj[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return clonedObj;
|
||||
}
|
||||
|
||||
return Suite;
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.QueueRunner = jRequire.QueueRunner(j$);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher();
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.SpyRegistry = jRequire.SpyRegistry(j$);
|
||||
j$.SpyStrategy = jRequire.SpyStrategy();
|
||||
j$.Suite = jRequire.Suite();
|
||||
j$.Timer = jRequire.Timer();
|
||||
|
||||
@@ -24,6 +24,14 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return env.afterEach(afterEachFunction);
|
||||
},
|
||||
|
||||
beforeAll: function(beforeAllFunction) {
|
||||
return env.beforeAll(beforeAllFunction);
|
||||
},
|
||||
|
||||
afterAll: function(afterAllFunction) {
|
||||
return env.afterAll(afterAllFunction);
|
||||
},
|
||||
|
||||
expect: function(actual) {
|
||||
return env.expect(actual);
|
||||
},
|
||||
|
||||
@@ -40,5 +40,20 @@ getJasmineRequireObj().util = function() {
|
||||
return false;
|
||||
};
|
||||
|
||||
util.clone = function(obj) {
|
||||
if (Object.prototype.toString.apply(obj) === '[object Array]') {
|
||||
return obj.slice();
|
||||
}
|
||||
|
||||
var cloned = {};
|
||||
for (var prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
cloned[prop] = obj[prop];
|
||||
}
|
||||
}
|
||||
|
||||
return cloned;
|
||||
};
|
||||
|
||||
return util;
|
||||
};
|
||||
|
||||
@@ -17,7 +17,8 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
failureCount = 0,
|
||||
pendingSpecCount = 0,
|
||||
htmlReporterMain,
|
||||
symbols;
|
||||
symbols,
|
||||
failedSuites = [];
|
||||
|
||||
this.initialize = function() {
|
||||
clearPrior();
|
||||
@@ -54,6 +55,10 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
};
|
||||
|
||||
this.suiteDone = function(result) {
|
||||
if (result.failedExpectations && result.failedExpectations.length > 0) {
|
||||
failedSuites.push(result);
|
||||
}
|
||||
|
||||
if (currentParent == topResults) {
|
||||
return;
|
||||
}
|
||||
@@ -149,6 +154,15 @@ jasmineRequire.HtmlReporter = function(j$) {
|
||||
|
||||
alert.appendChild(createDom('span', {className: statusBarClassName}, statusBarMessage));
|
||||
|
||||
for(i = 0; i < failedSuites.length; i++) {
|
||||
var failedSuite = failedSuites[i];
|
||||
for(var j = 0; j < failedSuite.failedExpectations.length; j++) {
|
||||
var errorBarMessage = 'AfterAll ' + failedSuite.failedExpectations[j].message;
|
||||
var errorBarClassName = 'bar errored';
|
||||
alert.appendChild(createDom('span', {className: errorBarClassName}, errorBarMessage));
|
||||
}
|
||||
}
|
||||
|
||||
var results = find('.results');
|
||||
results.appendChild(summary);
|
||||
|
||||
|
||||
@@ -194,6 +194,10 @@ body {
|
||||
background-color: $neutral-color;
|
||||
}
|
||||
|
||||
&.errored {
|
||||
background-color: $failing-color;
|
||||
}
|
||||
|
||||
&.menu {
|
||||
background-color: #fff;
|
||||
color: $faint-text-color;
|
||||
|
||||
Reference in New Issue
Block a user