* Removed old Queue & Runner in favor of Suite using the new QueueRunner

* New reporter interface across all reporters
* xdescribe & xit now store disabled specs
* Rewrite of HtmlReporter to support new interface and be more performant
This commit is contained in:
Davis W. Frank
2012-12-10 22:43:03 -08:00
committed by Dan Hansen and Davis W. Frank
parent 05977203a6
commit 3fc79bac9e
43 changed files with 3229 additions and 3318 deletions

View File

@@ -1,12 +1,13 @@
describe("jasmine.Env", function() {
// TODO: Fix these unit tests!
describe("Env", function() {
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
});
describe('ids', function () {
it('nextSpecId should return consecutive integers, starting at 0', function () {
describe('ids', function() {
it('nextSpecId should return consecutive integers, starting at 0', function() {
expect(env.nextSpecId()).toEqual(0);
expect(env.nextSpecId()).toEqual(1);
expect(env.nextSpecId()).toEqual(2);
@@ -17,21 +18,21 @@ describe("jasmine.Env", function() {
var fakeReporter;
beforeEach(function() {
fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["log"]);
fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["jasmineStarted"]);
});
describe('version', function () {
describe('version', function() {
var oldVersion;
beforeEach(function () {
beforeEach(function() {
oldVersion = jasmine.version_;
});
afterEach(function () {
afterEach(function() {
jasmine.version_ = oldVersion;
});
it('should raise an error if version is not set', function () {
it('should raise an error if version is not set', function() {
jasmine.version_ = null;
var exception;
try {
@@ -79,8 +80,8 @@ describe("jasmine.Env", function() {
it("should allow reporters to be registered", function() {
env.addReporter(fakeReporter);
env.reporter.log("message");
expect(fakeReporter.log).toHaveBeenCalledWith("message");
env.reporter.jasmineStarted();
expect(fakeReporter.jasmineStarted).toHaveBeenCalled();
});
});
@@ -138,8 +139,12 @@ describe("jasmine.Env", function() {
describe("even if there are several", function() {
beforeEach(function() {
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
env.addEqualityTester(function(a, b) { return jasmine.undefined; });
env.addEqualityTester(function(a, b) {
return jasmine.undefined;
});
env.addEqualityTester(function(a, b) {
return jasmine.undefined;
});
});
it("should use normal equality rules", function() {
@@ -151,61 +156,180 @@ describe("jasmine.Env", function() {
it("should evaluate custom equality testers in the order they are declared", function() {
isEqual = false;
env.addEqualityTester(function(a, b) { return true; });
env.addEqualityTester(function(a, b) {
return true;
});
expect(env.equals_('abc', 'abc')).toBeFalsy();
});
});
});
});
describe("jasmine Env (integration)", function() {
describe("Env (integration)", function() {
it("Suites execute as expected (no nesting)", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("A Suite", function() {
env.it("with a spec", function() {
calls.push("with a spec");
});
env.it("and another spec", function() {
calls.push("and another spec");
});
});
env.execute();
expect(calls).toEqual([
"with a spec",
"and another spec"
]);
});
it("Nested Suites execute as expected", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.execute();
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec'
]);
});
it("Multiple top-level Suites execute as expected", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("Outer suite", function() {
env.it("an outer spec", function() {
calls.push('an outer spec')
});
env.describe("Inner suite", function() {
env.it("an inner spec", function() {
calls.push('an inner spec');
});
env.it("another inner spec", function() {
calls.push('another inner spec');
});
});
});
env.describe("Another outer suite", function() {
env.it("a 2nd outer spec", function() {
calls.push('a 2nd outer spec')
});
});
env.execute();
expect(calls).toEqual([
'an outer spec',
'an inner spec',
'another inner spec',
'a 2nd outer spec'
]);
});
it("Mock clock can be installed and used in tests", function() {
var setTimeout = jasmine.createSpy('setTimeout'),
globalTimeoutFn = jasmine.createSpy('globalTimeoutFn'),
fakeTimeoutFn = jasmine.createSpy('fakeTimeoutFn'),
env = new jasmine.Env({global: { setTimeout: setTimeout }});
var globalSetTimeout = jasmine.createSpy('globalSetTimeout'),
delayedFunctionForGlobalClock = jasmine.createSpy('delayedFunctionForGlobalClock'),
delayedFunctionForMockClock = jasmine.createSpy('delayedFunctionForMockClock'),
env = new jasmine.Env({global: { setTimeout: globalSetTimeout }});
env.describe("tests", function() {
env.it("test with mock clock", function() {
env.clock.install();
env.clock.setTimeout(fakeTimeoutFn, 100);
env.clock.setTimeout(delayedFunctionForMockClock, 100);
env.clock.tick(100);
});
env.it("test without mock clock", function() {
env.clock.setTimeout(globalTimeoutFn, 100);
env.clock.setTimeout(delayedFunctionForGlobalClock, 100);
});
});
expect(setTimeout).not.toHaveBeenCalled();
expect(fakeTimeoutFn).not.toHaveBeenCalled();
expect(globalSetTimeout).not.toHaveBeenCalled();
expect(delayedFunctionForMockClock).not.toHaveBeenCalled();
env.execute();
expect(fakeTimeoutFn).toHaveBeenCalled();
expect(setTimeout).toHaveBeenCalledWith(globalTimeoutFn, 100);
expect(delayedFunctionForMockClock).toHaveBeenCalled();
expect(globalSetTimeout).toHaveBeenCalledWith(delayedFunctionForGlobalClock, 100);
});
it("should report as expected", function() {
var env = new jasmine.Env(),
reporter = jasmine.createSpyObj('fakeReproter', [
"jasmineStarted",
"jasmineDone",
"suiteStarted",
"suiteDone",
"specStarted",
"specDone"
]);
env.addReporter(reporter);
env.describe("A Suite", function() {
env.it("with a top level spec", function() {
env.expect(true).toBe(true);
});
env.describe("with a nested suite", function() {
env.xit("with a disabled spec", function() {
env.expect(true).toBe(true);
});
env.it("with a spec", function() {
env.expect(true).toBe(false);
});
});
});
env.execute();
expect(reporter.jasmineStarted).toHaveBeenCalledWith({
totalSpecsDefined: 3
});
var suiteResult = reporter.suiteStarted.calls[0].args[0];
expect(suiteResult.description).toEqual("A Suite");
expect(reporter.jasmineDone).toHaveBeenCalled();
});
it("should be possible to get full name from a spec", function() {
var env = new jasmine.Env({global: { setTimeout: setTimeout }}),
topLevelSpec, nestedSpec, doublyNestedSpec;
topLevelSpec, nestedSpec, doublyNestedSpec;
env.describe("my tests", function() {
topLevelSpec = env.it("are sometimes top level", function() {
});
env.describe("are sometimes", function() {
nestedSpec = env.it("singly nested", function() {
});
env.describe("even", function() {
doublyNestedSpec = env.it("doubly nested", function() {
});
});
});
});
env.execute();
expect(topLevelSpec.getFullName()).toBe("my tests are sometimes top level.");
expect(nestedSpec.getFullName()).toBe("my tests are sometimes singly nested.");
expect(doublyNestedSpec.getFullName()).toBe("my tests are sometimes even doubly nested.");

View File

@@ -1,5 +1,5 @@
describe('jasmine.jsApiReporter', function() {
describe('results', function () {
xdescribe('JsApiReporter (integration specs)', function() {
describe('results', function() {
var reporter, spec1, spec2;
var env;
var suite, nestedSuite, nestedSpec;
@@ -33,13 +33,13 @@ describe('jasmine.jsApiReporter', function() {
});
it('results() should return a hash of all results, indexed by spec id', function () {
it('results() should return a hash of all results, indexed by spec id', function() {
var expectedSpec1Results = {
result: "passed"
},
expectedSpec2Results = {
result: "failed"
};
result: "passed"
},
expectedSpec2Results = {
result: "failed"
};
expect(reporter.results()[spec1.id].result).toEqual('passed');
expect(reporter.results()[spec2.id].result).toEqual('failed');
});
@@ -78,3 +78,95 @@ describe('jasmine.jsApiReporter', function() {
});
});
});
describe("JsApiReporter", function() {
it("knows when a full environment is started", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
reporter.jasmineStarted();
expect(reporter.started).toBe(true);
expect(reporter.finished).toBe(false);
});
it("knows when a full environment is done", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.started).toBe(false);
expect(reporter.finished).toBe(false);
reporter.jasmineStarted();
reporter.jasmineDone();
expect(reporter.finished).toBe(true);
});
it("defaults to 'loaded' status", function() {
var reporter = new jasmine.JsApiReporter();
expect(reporter.status()).toEqual('loaded');
});
it("reports 'started' when Jasmine has started", function() {
var reporter = new jasmine.JsApiReporter();
reporter.jasmineStarted();
expect(reporter.status()).toEqual('started');
});
it("reports 'done' when Jasmine is done", function() {
var reporter = new jasmine.JsApiReporter();
reporter.jasmineDone();
expect(reporter.status()).toEqual('done');
});
it("tracks a suite", function() {
var reporter = new jasmine.JsApiReporter();
reporter.suiteStarted({
id: 123,
description: "A suite"
});
var suites = reporter.suites();
expect(suites).toEqual({123: {id: 123, description: "A suite"}});
reporter.suiteDone({
id: 123,
description: "A suite",
status: 'passed'
});
expect(suites).toEqual({123: {id: 123, description: "A suite", status: 'passed'}});
});
it("tracks a spec", function() {
var reporter = new jasmine.JsApiReporter();
reporter.specStarted({
id: 123,
description: "A spec"
});
var specs = reporter.specs();
expect(specs).toEqual({123: {id: 123, description: "A spec"}});
reporter.specDone({
id: 123,
description: "A spec",
status: 'passed'
});
expect(specs).toEqual({123: {id: 123, description: "A spec", status: 'passed'}});
});
});

View File

@@ -1,45 +0,0 @@
describe("jasmine.MultiReporter", function() {
var multiReporter, fakeReporter1, fakeReporter2;
beforeEach(function() {
multiReporter = new jasmine.MultiReporter();
fakeReporter1 = originalJasmine.createSpyObj("fakeReporter1", ["reportSpecResults"]);
fakeReporter2 = originalJasmine.createSpyObj("fakeReporter2", ["reportSpecResults", "reportRunnerStarting"]);
multiReporter.addReporter(fakeReporter1);
multiReporter.addReporter(fakeReporter2);
});
it("should support all the method calls that jasmine.Reporter supports", function() {
var delegate = {};
multiReporter.addReporter(delegate);
addMatchers({
toDelegateMethod: function(methodName) {
delegate[methodName] = originalJasmine.createSpy(methodName);
this.actual[methodName]("whatever argument");
return delegate[methodName].wasCalled &&
delegate[methodName].mostRecentCall.args.length == 1 &&
delegate[methodName].mostRecentCall.args[0] == "whatever argument";
}
});
expect(multiReporter).toDelegateMethod('reportRunnerStarting');
expect(multiReporter).toDelegateMethod('reportRunnerResults');
expect(multiReporter).toDelegateMethod('reportSuiteResults');
expect(multiReporter).toDelegateMethod('reportSpecStarting');
expect(multiReporter).toDelegateMethod('reportSpecResults');
expect(multiReporter).toDelegateMethod('log');
});
it("should delegate to any and all subreporters", function() {
multiReporter.reportSpecResults('blah', 'foo');
expect(fakeReporter1.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
expect(fakeReporter2.reportSpecResults).toHaveBeenCalledWith('blah', 'foo');
});
it("should quietly skip delegating to any subreporters which lack the given method", function() {
multiReporter.reportRunnerStarting('blah', 'foo');
expect(fakeReporter2.reportRunnerStarting).toHaveBeenCalledWith('blah', 'foo');
});
});

View File

@@ -0,0 +1,132 @@
describe("QueueRunner", function() {
it("runs all the functions it's passed", function() {
var calls = [],
fn1 = jasmine.createSpy('fn1'),
fn2 = jasmine.createSpy('fn2'),
queueRunner = new jasmine.QueueRunner({
fns: [fn1, fn2]
});
fn1.andCallFake(function() {
calls.push('fn1');
});
fn2.andCallFake(function() {
calls.push('fn2');
});
queueRunner.execute();
expect(calls).toEqual(['fn1', 'fn2']);
});
it("supports asynchronous functions, only advancing to next function after a done() callback", function() {
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
//createSpy('asyncfn').andCallFake(function(done) {});
var onComplete = originalJasmine.createSpy('onComplete'),
beforeCallback = originalJasmine.createSpy('beforeCallback'),
fnCallback = originalJasmine.createSpy('fnCallback'),
afterCallback = originalJasmine.createSpy('afterCallback'),
fn1 = function(done) {
beforeCallback();
setTimeout(function() {
done()
}, 100);
},
fn2 = function(done) {
fnCallback();
setTimeout(function() {
done()
}, 100);
},
fn3 = function(done) {
afterCallback();
setTimeout(function() {
done()
}, 100);
},
queueRunner = new jasmine.QueueRunner({
fns: [fn1, fn2, fn3],
onComplete: onComplete
});
clock.install();
queueRunner.execute();
expect(beforeCallback).toHaveBeenCalled();
expect(fnCallback).not.toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(fnCallback).toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(afterCallback).toHaveBeenCalled();
expect(onComplete).not.toHaveBeenCalled();
clock.tick(100);
expect(onComplete).toHaveBeenCalled();
});
it("calls an exception handler when an exception is thrown in a fn", function() {
var fn = function() {
throw new Error('fake error');
},
exceptionCallback = jasmine.createSpy('exception callback'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
onException: exceptionCallback
});
queueRunner.execute();
expect(exceptionCallback).toHaveBeenCalledWith(jasmine.any(Error));
});
it("rethrows an exception if told to", function() {
var fn = function() {
throw new Error('fake error');
},
queueRunner = new jasmine.QueueRunner({
fns: [fn],
catchingExceptions: function() { return false; }
});
expect(function() { queueRunner.execute(); }).toThrow();
});
it("calls a provided complete callback when done", function() {
var fn = jasmine.createSpy('fn'),
completeCallback = jasmine.createSpy('completeCallback'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
onComplete: completeCallback
});
queueRunner.execute();
expect(completeCallback).toHaveBeenCalled();
});
it("calls a provided garbage collection function with the complete callback when done", function() {
var fn = jasmine.createSpy('fn'),
completeCallback = jasmine.createSpy('completeCallback'),
encourageGC = jasmine.createSpy('encourageGC'),
queueRunner = new jasmine.QueueRunner({
fns: [fn],
encourageGC: encourageGC,
onComplete: completeCallback
});
queueRunner.execute();
expect(encourageGC).toHaveBeenCalledWith(completeCallback);
});
});

View File

@@ -0,0 +1,40 @@
describe("ReportDispatcher", function() {
it("builds an interface of requested methods", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar', 'baz']);
expect(dispatcher.foo).toBeDefined();
expect(dispatcher.bar).toBeDefined();
expect(dispatcher.baz).toBeDefined();
});
it("dispatches requested methods to added reporters", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo', 'bar']),
reporter = jasmine.createSpyObj('reporter', ['foo', 'bar']),
anotherReporter = jasmine.createSpyObj('reporter', ['foo', 'bar']);
dispatcher.addReporter(reporter);
dispatcher.addReporter(anotherReporter);
dispatcher.foo(123, 456);
expect(reporter.foo).toHaveBeenCalledWith(123, 456);
expect(anotherReporter.foo).toHaveBeenCalledWith(123, 456);
dispatcher.bar('a', 'b');
expect(reporter.bar).toHaveBeenCalledWith('a', 'b');
expect(anotherReporter.bar).toHaveBeenCalledWith('a', 'b');
});
it("does not dispatch to a reporter if the reporter doesn't accept the method", function() {
var dispatcher = new jasmine.ReportDispatcher(['foo']),
reporter = jasmine.createSpyObj('reporter', ['baz']);
dispatcher.addReporter(reporter);
expect(function() {
dispatcher.foo(123, 456);
}).not.toThrow();
});
});

View File

@@ -1,56 +0,0 @@
describe('jasmine.Reporter', function() {
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
});
it('should get called from the test runner', function() {
env.describe('Suite for JSON Reporter with Callbacks', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
env.it('should be a failing test', function() {
this.runs(function () {
this.expect(false).toEqual(true);
});
});
});
env.describe('Suite for JSON Reporter with Callbacks 2', function () {
env.it('should be a test', function() {
this.runs(function () {
this.expect(true).toEqual(true);
});
});
});
var foo = 0;
var bar = 0;
var baz = 0;
env.addReporter({
reportSpecResults: function() {
foo++;
},
reportSuiteResults: function() {
bar++;
},
reportRunnerResults: function() {
baz++;
}
});
var runner = env.currentRunner();
runner.execute();
expect(foo).toEqual(3); // 'foo was expected to be 3, was ' + foo);
expect(bar).toEqual(2); // 'bar was expected to be 2, was ' + bar);
expect(baz).toEqual(1); // 'baz was expected to be 1, was ' + baz);
});
});

View File

@@ -1,168 +0,0 @@
describe('RunnerTest', function() {
var fakeTimer;
var env;
beforeEach(function() {
env = new jasmine.Env();
env.updateInterval = 0;
});
describe('beforeEach', function() {
it('should run before each spec for all suites', function() {
var foo;
env.beforeEach(function() {
foo = 0;
});
env.describe('suite 1', function() {
env.it('test 1-1', function() {
foo++;
expect(foo).toEqual(1);
});
env.it('test 1-2', function() {
foo++;
expect(foo).toEqual(1);
});
});
env.describe('suite 2', function() {
env.it('test 2-1', function() {
foo++;
expect(foo).toEqual(1);
});
});
env.currentRunner().execute();
});
it('should provide all specs', function() {
env.describe('suite 1', function() {
env.it('test 1-1', function() {
});
env.it('test 1-2', function() {
});
});
env.describe('suite 2', function() {
env.it('test 2-1', function() {
});
});
expect(env.currentRunner().specs().length).toEqual(3);
});
});
describe('afterEach', function() {
it('should run after each spec for all suites', function() {
var foo = 3;
env.afterEach(function() {
foo = foo - 1;
});
env.describe('suite 1', function() {
env.it('test 1-1', function() {
expect(foo).toEqual(3);
});
env.it('test 1-2', function() {
expect(foo).toEqual(2);
});
});
env.describe('suite 2', function() {
env.it('test 2-1', function() {
expect(foo).toEqual(1);
});
});
env.currentRunner().execute();
});
it('should run after a failing spec', function () {
var afterEach = originalJasmine.createSpy();
env.afterEach(afterEach);
env.describe('suite',function() {
env.it('fails', function() {
this.expect(true).toBe(false);
});
}).execute();
expect(afterEach).toHaveBeenCalled();
});
});
it('should ignore suites that have been x\'d', function() {
var disabledDescribe = jasmine.createSpy('xdescribe');
env.xdescribe('one suite description', disabledDescribe);
env.currentRunner().execute();
expect(disabledDescribe).not.toHaveBeenCalled();
});
describe('reporting', function() {
var fakeReporter;
beforeEach(function() {
fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting", "reportRunnerResults"]);
env.addReporter(fakeReporter);
});
it('should report runner results when the runner has completed running', function() {
var specSpy = originalJasmine.createSpy('spec').andCallFake(function() {
expect(fakeReporter.reportRunnerResults).not.toHaveBeenCalled();
});
env.describe('description', function() {
env.it('should be a test', specSpy);
});
env.currentRunner().execute();
expect(specSpy).toHaveBeenCalled();
expect(fakeReporter.reportRunnerResults).toHaveBeenCalledWith(env.currentRunner());
});
});
it("should report when the tests start running", function() {
var fakeReporter = originalJasmine.createSpyObj("fakeReporter", ["log", "reportRunnerStarting"]);
env.addReporter(fakeReporter);
var runner = new jasmine.Runner(env);
runner.arbitraryVariable = 'foo';
spyOn(runner.queue, 'start');
expect(fakeReporter.reportRunnerStarting).not.toHaveBeenCalled();
runner.execute();
expect(fakeReporter.reportRunnerStarting).toHaveBeenCalled();
var reportedRunner = fakeReporter.reportRunnerStarting.mostRecentCall.args[0];
expect(reportedRunner.arbitraryVariable).toEqual('foo');
expect(runner.queue.start).toHaveBeenCalled();
});
describe("when suites are nested", function() {
var suite1, suite2, suite3;
function suiteNames(suites) {
var suiteDescriptions = [];
for (var i = 0; i < suites.length; i++) {
suiteDescriptions.push(suites[i].getFullName());
}
return suiteDescriptions;
}
beforeEach(function() {
suite1 = env.describe("suite 1", function() {
suite2 = env.describe("suite 2", function() {
});
});
suite3 = env.describe("suite 3", function() {
});
});
it("#suites should return a flat array of all suites, including nested suites", function() {
var suites = env.currentRunner().suites();
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite2.getFullName(), suite3.getFullName()]);
});
it("#topLevelSuites should return a flat array of all top-level suites only", function() {
var suites = env.currentRunner().topLevelSuites();
expect(suiteNames(suites)).toEqual([suite1.getFullName(), suite3.getFullName()]);
});
});
});

View File

@@ -1,3 +1,4 @@
// TODO: This should really be part of the Env Integration Spec
describe("jasmine spec running", function () {
var env;
var fakeTimer;
@@ -74,11 +75,11 @@ describe("jasmine spec running", function () {
var actions = [];
env.beforeEach(function () {
actions.push('runner beforeEach');
actions.push('topSuite beforeEach');
});
env.afterEach(function () {
actions.push('runner afterEach');
actions.push('topSuite afterEach');
});
env.describe('Something', function() {
@@ -131,33 +132,33 @@ describe("jasmine spec running", function () {
var expected = [
"runner beforeEach",
"topSuite beforeEach",
"outer beforeEach",
"outer it 1",
"outer afterEach",
"runner afterEach",
"topSuite afterEach",
"runner beforeEach",
"topSuite beforeEach",
"outer beforeEach",
"inner 1 beforeEach",
"inner 1 it",
"inner 1 afterEach",
"outer afterEach",
"runner afterEach",
"topSuite afterEach",
"runner beforeEach",
"topSuite beforeEach",
"outer beforeEach",
"outer it 2",
"outer afterEach",
"runner afterEach",
"topSuite afterEach",
"runner beforeEach",
"topSuite beforeEach",
"outer beforeEach",
"inner 2 beforeEach",
"inner 2 it",
"inner 2 afterEach",
"outer afterEach",
"runner afterEach"
"topSuite afterEach"
];
expect(actions).toEqual(expected);
});
@@ -219,16 +220,30 @@ describe("jasmine spec running", function () {
expect(actions).toEqual(expected);
});
it("shouldn't run disabled suites", function() {
var specInADisabledSuite = originalJasmine.createSpy("specInADisabledSuite"),
suite = env.describe('A Suite', function() {
env.xdescribe('with a disabled suite', function(){
env.it('disabled spec', specInADisabledSuite);
});
});
suite.execute();
expect(specInADisabledSuite).not.toHaveBeenCalled();
});
it("shouldn't run disabled tests", function() {
var disabledSpec = originalJasmine.createSpy('disabledSpec'),
suite = env.describe('default current suite', function() {
env.xit('disabled spec').runs(disabledSpec);
env.xit('disabled spec', disabledSpec);
});
suite.execute();
expect(disabledSpec).not.toHaveBeenCalled();
});
it("should recover gracefully when there are errors in describe functions", 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 = [];
var superSimpleReporter = new jasmine.Reporter();
superSimpleReporter.reportSpecResults = function(result) {
@@ -275,5 +290,4 @@ describe("jasmine spec running", function () {
));
});
});
});

View File

@@ -1,233 +1,184 @@
describe("Spec", function() {
it("reports results for passing tests", function() {
var resultCallback = originalJasmine.createSpy('resultCallback'),
expectationFactory = function(actual, spec) {
expect(actual).toBe('some-actual');
return {
pass: function() {
spec.addExpectationResult(true);
}
}
},
spec = new jasmine.Spec({
description: 'my test',
id: 'some-id',
fn: function() {
this.expect('some-actual').pass();
},
resultCallback: resultCallback,
expectationFactory: expectationFactory
});
it("delegates execution to a QueueRunner", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
spec = new jasmine.Spec({
description: 'my test',
id: 'some-id',
fn: function() {},
queueRunner: fakeQueueRunner
});
spec.execute();
expect(resultCallback).toHaveBeenCalledWith({
id: "some-id",
status: "passed",
description: "my test",
failedExpectations: []
});
});
it("reports results for failing tests", function() {
var resultCallback = originalJasmine.createSpy('resultCallback'),
expectationFactory = function(actual, spec) {
expect(actual).toBe('some-actual');
return {
fail: function() {
spec.addExpectationResult(true);
}
}
},
spec = new jasmine.Spec({
description: 'my test',
id: 'some-id',
fn: function() {
this.expect('some-actual').fail();
},
resultCallback: resultCallback,
expectationFactory: expectationFactory
});
spec.execute();
expect(resultCallback).toHaveBeenCalledWith({
id: "some-id",
status: "passed",
description: "my test",
failedExpectations: []
});
expect(fakeQueueRunner).toHaveBeenCalled();
});
it("executes before fns, after fns", function() {
var before = originalJasmine.createSpy('before'),
after = originalJasmine.createSpy('after'),
fn = originalJasmine.createSpy('test body').andCallFake(function() {
expect(before).toHaveBeenCalled();
expect(after).not.toHaveBeenCalled();
});
spec = new jasmine.Spec({
fn: fn,
beforeFns: function() {
return [before]
},
afterFns: function() {
return [after]
}
});
it("should call the start callback on execution", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
beforesWereCalled = false,
startCallback = originalJasmine.createSpy('startCallback'),
spec = new jasmine.Spec({
id: 123,
description: 'foo bar',
fn: function() {},
onStart: startCallback,
queueRunner: fakeQueueRunner
});
spec.execute();
expect(before).toHaveBeenCalled();
expect(before.mostRecentCall.object).toBe(spec);
expect(fn).toHaveBeenCalled();
expect(after).toHaveBeenCalled();
expect(after.mostRecentCall.object).toBe(spec);
expect(startCallback).toHaveBeenCalledWith(spec);
});
it("passes an optional callback to spec bodies, befores, and afters", function() {
//TODO: it would be nice if spy arity could match the fake, so we could do something like:
//createSpy('asyncfn').andCallFake(function(done) {});
var resultCallback = originalJasmine.createSpy('resultCallback'),
beforeCallback = originalJasmine.createSpy('beforeCallback'),
fnCallback = originalJasmine.createSpy('fnCallback'),
afterCallback = originalJasmine.createSpy('afterCallback'),
before = function(done) {
beforeCallback();
setTimeout(function() { done() }, 100);
},
fn = function(done) {
fnCallback();
setTimeout(function() { done() }, 100);
},
after = function(done) {
afterCallback();
setTimeout(function() { done() }, 100);
},
spec = new jasmine.Spec({
resultCallback: resultCallback,
fn: fn,
beforeFns: function() {
return [before]
},
afterFns: function() {
return [after]
}
});
clock.install();
it("should call the start callback on execution but before any befores are called", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
beforesWereCalled = false,
startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
expect(beforesWereCalled).toBe(false);
}),
spec = new jasmine.Spec({
fn: function() {},
beforeFns: function() {
return [function() {
beforesWereCalled = true
}]
},
onStart: startCallback,
queueRunner: fakeQueueRunner
});
spec.execute();
expect(beforeCallback).toHaveBeenCalled();
expect(fnCallback).not.toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(resultCallback).not.toHaveBeenCalled();
expect(startCallback).toHaveBeenCalled();
});
clock.tick(100);
it("provides all before fns and after fns to be run", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
before = originalJasmine.createSpy('before'),
after = originalJasmine.createSpy('after'),
fn = originalJasmine.createSpy('test body').andCallFake(function() {
expect(before).toHaveBeenCalled();
expect(after).not.toHaveBeenCalled();
}),
spec = new jasmine.Spec({
fn: fn,
beforeFns: function() {
return [before]
},
afterFns: function() {
return [after]
},
queueRunner: fakeQueueRunner
});
expect(fnCallback).toHaveBeenCalled();
expect(afterCallback).not.toHaveBeenCalled();
expect(resultCallback).not.toHaveBeenCalled();
spec.execute();
clock.tick(100);
var allSpecFns = fakeQueueRunner.mostRecentCall.args[0].fns;
expect(allSpecFns).toEqual([before, fn, after]);
});
expect(afterCallback).toHaveBeenCalled();
expect(resultCallback).not.toHaveBeenCalled();
it("can be disabled, but still calls callbacks", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
clock.tick(100);
startCallback = originalJasmine.createSpy('startCallback'),
specBody = originalJasmine.createSpy('specBody'),
resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
onStart:startCallback,
fn: specBody,
resultCallback: resultCallback,
queueRunner: fakeQueueRunner
});
spec.disable();
expect(spec.status()).toBe('disabled');
spec.execute();
expect(startCallback).not.toHaveBeenCalled();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalled();
});
it("status returns null by default", function() {
it("should call the results callback on execution complete", function() {
var fakeQueueRunner = jasmine.createSpy('fakeQueueRunner'),
startCallback = originalJasmine.createSpy('startCallback'),
specBody = originalJasmine.createSpy('specBody'),
resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
onStart:startCallback,
fn: specBody,
resultCallback: resultCallback,
description: "with a spec",
getSpecName: function() { return "a suite with a spec"},
queueRunner: fakeQueueRunner
});
spec.disable();
expect(spec.status()).toBe('disabled');
spec.execute();
expect(startCallback).not.toHaveBeenCalled();
expect(fakeQueueRunner).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
expect(resultCallback).toHaveBeenCalledWith({
id: spec.id,
status: 'disabled',
description: 'with a spec',
fullName: 'a suite with a spec',
failedExpectations: []
});
});
it("should call the done callback on execution complete", function() {
var done = originalJasmine.createSpy('done callback'),
spec = new jasmine.Spec({
fn: function() {},
catchExceptions: function() { return false; },
resultCallback: function() {},
queueRunner: function(attrs) { attrs.onComplete(); }
});
spec.execute(done);
expect(done).toHaveBeenCalled();
});
it("#status returns null by default", function() {
var spec = new jasmine.Spec({});
expect(spec.status()).toBeNull();
});
it("status returns passed if all expectations in the spec have passed", function() {
it("#status returns passed if all expectations in the spec have passed", function() {
var spec = new jasmine.Spec({});
spec.addExpectationResult(true);
expect(spec.status()).toBe('passed');
});
it("status returns failed if any expectations in the spec have failed", function() {
it("#status returns failed if any expectations in the spec have failed", function() {
var spec = new jasmine.Spec({});
spec.addExpectationResult(true);
spec.addExpectationResult(false);
expect(spec.status()).toBe('failed');
});
it("throws when an exception occurs in the spec fn if catchExceptions is false", function() {
//TODO: one day we should pass a stack with this.
var resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
fn: function() {
throw new Error();
},
catchExceptions: false,
resultCallback: resultCallback
});
expect(function() {
spec.execute();
}).toThrow();
});
it("should call the start callback before any befores are called", function() {
var beforesWereCalled = false,
startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
expect(beforesWereCalled).toBe(false);
}),
spec = new jasmine.Spec({
fn: function() {
},
beforeFns: function() {
return [function() {
beforesWereCalled = true
}]
},
startCallback: startCallback,
catchExceptions: false,
resultCallback: function() {
}
});
spec.execute();
expect(startCallback).toHaveBeenCalled();
});
it("can return its full name", function() {
var spec = new jasmine.Spec({
var spec;
spec = new jasmine.Spec({
getSpecName: function(passedVal) {
expect(passedVal).toBe(spec);
// expect(passedVal).toBe(spec); TODO: a exec time, spec is undefined WTF?
return 'expected val';
}
});
expect(spec.getFullName()).toBe('expected val');
});
it("can be disabled", function() {
var startCallback = originalJasmine.createSpy('startCallback'),
specBody = originalJasmine.createSpy('specBody'),
resultCallback = originalJasmine.createSpy('resultCallback'),
spec = new jasmine.Spec({
startCallback: startCallback,
fn: specBody,
resultCallback: resultCallback
});
spec.disable();
expect(spec.status()).toBe('disabled');
spec.execute();
expect(startCallback).not.toHaveBeenCalled();
expect(specBody).not.toHaveBeenCalled();
//TODO: with expected data.
expect(resultCallback).toHaveBeenCalled();
});
});

View File

@@ -1,118 +1,4 @@
//describe('Suite', function() {
// var env;
//
// beforeEach(function() {
// env = new jasmine.Env();
// env.updateInterval = 0;
// });
//
// describe('Specs', function () {
// var suite;
//
// beforeEach(function() {
// suite = env.describe('Suite 1', function () {
// env.it('Spec 1', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.it('Spec 2', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.describe('Suite 2', function () {
// env.it('Spec 3', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// });
// env.it('Spec 4', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// });
// });
//
// it('#specs should return all immediate children that are specs.', function () {
// var suiteSpecs = suite.specs();
// expect(suiteSpecs.length).toEqual(3);
// expect(suiteSpecs[0].description).toEqual('Spec 1');
// expect(suiteSpecs[1].description).toEqual('Spec 2');
// expect(suiteSpecs[2].description).toEqual('Spec 4');
// });
//
// it("#suites should return all immediate children that are suites.", function() {
// var nestedSuites = suite.suites();
// expect(nestedSuites.length).toEqual(1);
// expect(nestedSuites[0].description).toEqual('Suite 2');
// });
//
// it("#children should return all immediate children including suites and specs.", function() {
// var children = suite.children();
// expect(children.length).toEqual(4);
// expect(children[0].description).toEqual('Spec 1');
// expect(children[1].description).toEqual('Spec 2');
// expect(children[2].description).toEqual('Suite 2');
// expect(children[3].description).toEqual('Spec 4');
// });
// });
//
// describe('SpecCount', function () {
//
// it('should keep a count of the number of specs that are run', function() {
// var suite = env.describe('one suite description', function () {
// env.it('should be a test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.it('should be another test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.it('should be a third test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// });
//
// expect(suite.specs().length).toEqual(3);
// });
//
// it('specCount should be correct even with runs/waits blocks', function() {
// var suite = env.describe('one suite description', function () {
// env.it('should be a test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.it('should be another test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// this.waits(10);
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// env.it('should be a third test', function() {
// this.runs(function () {
// this.expect(true).toEqual(true);
// });
// });
// });
//
// expect(suite.specs().length).toEqual(3);
// });
// });
//});
describe("Suite (unit tests)", function() {
describe("Suite", function() {
it("keeps its id", function() {
var env = new jasmine.Env(),
@@ -139,15 +25,16 @@ describe("Suite (unit tests)", function() {
var env = new jasmine.Env(),
parentSuite = new jasmine.Suite({
env: env,
description: "I am a suite"
description: "I am a parent suite",
parentSuite: jasmine.createSpy('pretend top level suite')
}),
suite = new jasmine.Suite({
env: env,
description: "I am a suite",
parentSuite: parentSuite
});
suite = new jasmine.Suite({
env: env,
description: "I am a suite"
});
expect(suite.getFullName()).toEqual("I am a suite");
expect(suite.getFullName()).toEqual("I am a parent suite I am a suite");
});
it("adds before functions in order of needed execution", function() {
@@ -182,9 +69,15 @@ describe("Suite (unit tests)", function() {
it("adds specs", function() {
var env = new jasmine.Env(),
fakeQueue = {
add: jasmine.createSpy()
},
suite = new jasmine.Suite({
env: env,
description: "I am a suite"
description: "I am a suite",
queueFactory: function() {
return fakeQueue
}
}),
fakeSpec = {};
@@ -192,34 +85,146 @@ describe("Suite (unit tests)", function() {
suite.addSpec(fakeSpec);
expect(suite.specs.length).toEqual(1);git
expect(suite.specs.length).toEqual(1);
});
});
// TODO:
describe("Suite (acceptance)", function() {
it("can execute and run all of its befores, specs, and afters", function() {
it("adds suites", function() {
var env = new jasmine.Env(),
calls = [];
env.describe("A suite", function() {
env.beforeEach(function() {
calls.push('before');
fakeQueue = {
add: jasmine.createSpy()
},
suite = new jasmine.Suite({
env: env,
description: "I am a suite",
queueFactory: function() {
return fakeQueue
}
}),
anotherSuite = new jasmine.Suite({
env: env,
description: "I am another suite",
queueFactory: function() {
return fakeQueue
}
});
env.it("with a spec", function() {
calls.push('spec');
});
expect(suite.suites.length).toEqual(0);
env.afterEach(function() {
calls.push('after');
});
});
suite.addSuite(anotherSuite);
env.execute();
expect(calls).toEqual(['before', 'spec', 'after']);
expect(suite.suites.length).toEqual(1);
});
});
it("can be disabled", function() {
var env = new jasmine.Env(),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
});
suite.disable();
expect(suite.disabled).toBe(true);
suite.execute();
expect(fakeQueueRunner).not.toHaveBeenCalled();
});
it("delegates execution of its specs and suites", function() {
var env = new jasmine.Env(),
parentSuiteDone = jasmine.createSpy('parent suite done'),
fakeQueueRunnerForParent = jasmine.createSpy('fake parent queue runner'),
parentSuite = new jasmine.Suite({
env: env,
description: "I am a parent suite",
queueRunner: fakeQueueRunnerForParent
}),
fakeQueueRunner = jasmine.createSpy('fake queue runner'),
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
spyOn(suite, "execute");
parentSuite.addSpec(fakeSpec1);
parentSuite.addSuite(suite);
parentSuite.execute(parentSuiteDone);
var parentSuiteFns = fakeQueueRunnerForParent.mostRecentCall.args[0].fns;
parentSuiteFns[0]();
expect(fakeSpec1.execute).toHaveBeenCalled();
parentSuiteFns[1]();
expect(suite.execute).toHaveBeenCalled();
});
it("calls a provided onStart callback when starting", function() {
var env = new jasmine.Env(),
suiteStarted = jasmine.createSpy('suiteStarted'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
onStart: suiteStarted,
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute();
expect(suiteStarted).toHaveBeenCalledWith(suite);
});
it("calls a provided onComplete callback when done", function() {
var env = new jasmine.Env(),
suiteCompleted = jasmine.createSpy('parent suite done'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute(suiteCompleted);
expect(suiteCompleted).toHaveBeenCalled();
});
it("calls a provided result callback when done", function() {
var env = new jasmine.Env(),
suiteResultsCallback = jasmine.createSpy('suite result callback'),
fakeQueueRunner = function(attrs) { attrs.onComplete(); },
suite = new jasmine.Suite({
env: env,
description: "with a child suite",
queueRunner: fakeQueueRunner,
resultCallback: suiteResultsCallback
}),
fakeSpec1 = {
execute: jasmine.createSpy('fakeSpec1')
};
suite.execute();
expect(suiteResultsCallback).toHaveBeenCalledWith({
id: suite.id,
status: '',
description: "with a child suite",
fullName: "with a child suite"
});
});
});