jasmine/lib/jasmine.js

351 lines
7.5 KiB
JavaScript
Raw Normal View History

// Crockford's helpers
// Object.create instead of new Object
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {
};
F.prototype = o;
return new F();
};
}
// Klass.method instead of Klass.prototype.name = function
2008-12-01 20:26:12 +00:00
if (typeof Function.method !== 'function') {
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
}
}
/*
* Jasmine internal classes & objects
*/
2008-12-04 00:23:17 +00:00
/*
* object for holding results; allows for the results array to hold another nestedResults()
*
*/
var nestedResults = function() {
var that = {
totalCount: 0,
passedCount: 0,
failedCount: 0,
results: [],
rollupCounts: function (result) {
that.totalCount += result.totalCount;
that.passedCount += result.passedCount;
that.failedCount += result.failedCount;
},
push: function (result) {
if (result.results) {
that.rollupCounts(result);
} else {
that.totalCount++;
result.passed ? that.passedCount++ : that.failedCount++;
}
that.results.push(result);
}
}
return that;
}
/*
* base for Runner & Suite: allows for a queue of functions to get executed, allowing for
* any one action to complete, including asynchronous calls, before going to the next
* action.
*
**/
var actionCollection = function () {
var that = {
actions: [],
index: 0,
finished: false,
2008-12-02 21:59:39 +00:00
results: nestedResults(),
finish: function () {
if (that.finishCallback) {
that.finishCallback();
}
that.finished = true;
},
2008-12-02 21:59:39 +00:00
report: function (result) {
that.results.push(result);
},
execute: function () {
if (that.actions.length > 0) {
that.next();
}
},
getCurrentAction: function () {
return that.actions[that.index];
},
next: function() {
if (that.index >= that.actions.length) {
that.finish();
return;
}
var currentAction = that.getCurrentAction();
if (that.beforeEach) {
that.beforeEach.apply(currentAction);
}
currentAction.execute();
that.waitForDone(currentAction);
},
waitForDone: function(action) {
var id = setInterval(function () {
if (action.finished) {
clearInterval(id);
2008-12-02 21:59:39 +00:00
that.report(action.results);
if (that.afterEach) {
that.afterEach.apply(action);
}
that.index++;
that.next();
}
}, 150);
}
}
return that;
}
/*
* queuedFunction is how actionCollection's actions are implemented
*/
var queuedFunction = function(func, timeout, spec) {
var that = {
func: func,
next: function () {
spec.finish(); // default value is to be done after one function
},
execute: function () {
if (timeout > 0) {
setTimeout(function () {
that.func.apply(spec);
that.next();
}, timeout);
} else {
that.func.apply(spec);
that.next();
}
}
}
return that;
}
/******************************************************************************
* Jasmine
******************************************************************************/
var Jasmine = {}
Jasmine.init = function () {
var that = {
currentSpec: null,
currentSuite: null,
currentRunner: null,
execute: function () {
that.currentRunner.execute();
}
}
return that;
}
var jasmine = Jasmine.init();
/*
* Jasmine.Matchers methods; add your own with Jasmine.Matchers.method() - don't forget to write a test
*
*/
2008-12-04 00:23:17 +00:00
Jasmine.Matchers = function (actual, results) {
this.actual = actual;
this.passing_message = 'Passed.'
2008-12-02 21:59:39 +00:00
this.results = results || nestedResults();
}
Jasmine.Matchers.method('report', function (result, failing_message) {
this.results.push({
passed: result,
message: result ? this.passing_message : failing_message
});
return result;
});
Jasmine.Matchers.method('should_equal', function (expected) {
return this.report((this.actual === expected),
'Expected ' + expected + ' but got ' + this.actual + '.');
});
Jasmine.Matchers.method('should_not_equal', function (expected) {
return this.report((this.actual !== expected),
'Expected ' + expected + ' to not equal ' + this.actual + ', but it does.');
});
/*
* Jasmine spec constructor
*/
2008-12-01 20:26:12 +00:00
var it = function (description, func) {
2008-12-01 20:26:12 +00:00
var that = {
description: description,
queue: [],
currentTimeout: 0,
finished: false,
2008-12-02 21:59:39 +00:00
results: nestedResults(),
expects_that: function (actual) {
return new Jasmine.Matchers(actual, that.results);
},
2008-12-01 23:15:34 +00:00
2008-12-01 20:26:12 +00:00
waits: function (timeout) {
that.currentTimeout = timeout;
2008-12-01 20:26:12 +00:00
return that;
},
2008-12-01 23:15:34 +00:00
resetTimeout: function() {
that.currentTimeout = 0;
},
2008-12-01 23:15:34 +00:00
finishCallback: function () {
if (jasmine.reporter) {
jasmine.reporter.reportSpecResults(that.results);
}
},
finish: function() {
that.finishCallback();
that.finished = true;
},
2008-12-01 23:15:34 +00:00
2008-12-01 20:26:12 +00:00
execute: function () {
if (that.queue[0]) {
that.queue[0].execute();
2008-12-01 20:26:12 +00:00
}
}
};
2008-12-01 20:26:12 +00:00
var addToQueue = function(func) {
2008-12-01 23:15:34 +00:00
var currentFunction = queuedFunction(func, that.currentTimeout, that);
that.queue.push(currentFunction);
2008-12-01 23:15:34 +00:00
if (that.queue.length > 1) {
var previousFunction = that.queue[that.queue.length - 2];
previousFunction.next = function () {
currentFunction.execute();
}
}
2008-12-01 23:15:34 +00:00
that.resetTimeout();
2008-12-01 20:26:12 +00:00
return that;
}
2008-12-01 20:26:12 +00:00
that.runs = addToQueue;
jasmine.currentSuite.specs.push(that);
jasmine.currentSpec = that;
2008-12-02 01:57:21 +00:00
if (func) {
func();
}
2008-12-02 01:57:21 +00:00
that.results.description = description;
2008-12-01 20:26:12 +00:00
return that;
}
var runs = function (func) {
jasmine.currentSpec.runs(func);
}
var waits = function (timeout) {
jasmine.currentSpec.waits(timeout);
}
var beforeEach = function (beforeEach) {
jasmine.currentSuite.beforeEach = beforeEach;
}
var afterEach = function (afterEach) {
jasmine.currentSuite.afterEach = afterEach;
}
var describe = function (description, spec_definitions) {
var that = actionCollection();
that.description = description;
that.specs = that.actions;
jasmine.currentSuite = that;
jasmine.currentRunner.suites.push(that);
spec_definitions();
that.results.description = description;
that.finishCallback = function () {
if (jasmine.reporter) {
jasmine.reporter.reportSuiteResults(that.results);
}
}
2008-12-02 01:57:21 +00:00
return that;
}
2008-12-04 00:23:17 +00:00
var Runner = function () {
var that = actionCollection();
that.suites = that.actions;
that.results.description = 'All Jasmine Suites';
2008-12-02 21:59:39 +00:00
2008-12-04 18:56:58 +00:00
that.finishCallback = function () {
if (jasmine.reporter) {
jasmine.reporter.reportRunnerResults(that.results);
2008-12-04 18:56:58 +00:00
}
}
jasmine.currentRunner = that;
return that;
}
jasmine.currentRunner = Runner();
/* JasmineReporters.reporter
* Base object that will get called whenever a Spec, Suite, or Runner is done. It is up to
* descendants of this object to do something with the results (see json_reporter.js)
*/
Jasmine.Reporters = {};
Jasmine.Reporters.reporter = function (callbacks) {
var that = {
callbacks: callbacks || {},
doCallback: function (callback, results) {
if (callback) { callback(results); }
},
reportRunnerResults: function (results) { that.doCallback(that.callbacks.runnerCallback, results); },
reportSuiteResults: function (results) { that.doCallback(that.callbacks.suiteCallback, results); },
reportSpecResults: function (results) { that.doCallback(that.callbacks.specCallback, results);}
}
return that;
}