Re-add async support (achieved via done callbacks)
- TODO: pull out queueRunner into a new object.
This commit is contained in:
@@ -38,9 +38,11 @@
|
|||||||
return env.spyOn(obj, methodName);
|
return env.spyOn(obj, methodName);
|
||||||
},
|
},
|
||||||
|
|
||||||
clock: function() {
|
clock: env.clock,
|
||||||
return env.clock;
|
setTimeout: env.clock.setTimeout,
|
||||||
},
|
clearTimeout: env.clock.clearTimeout,
|
||||||
|
setInterval: env.clock.setInterval,
|
||||||
|
clearInterval: env.clock.clearInterval,
|
||||||
|
|
||||||
jsApiReporter: new jasmine.JsApiReporter(jasmine)
|
jsApiReporter: new jasmine.JsApiReporter(jasmine)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1958,47 +1958,60 @@ jasmine.Spec.prototype.expect = function(actual) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
jasmine.Spec.prototype.execute = function() {
|
jasmine.Spec.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
resultCallback.call(this);
|
resultCallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var befores = this.beforeFns() || [],
|
var befores = this.beforeFns() || [],
|
||||||
afters = this.afterFns() || [];
|
afters = this.afterFns() || [];
|
||||||
this.startCallback(this);
|
this.startCallback(this);
|
||||||
try {
|
var allFns = befores.concat(this.fn).concat(afters);
|
||||||
for (var i = 0; i < befores.length; i++) {
|
|
||||||
befores[i].call(this);
|
queueRunner(allFns, 0);
|
||||||
}
|
|
||||||
this.fn.call(this);
|
function attempt(fn) {
|
||||||
for (i = 0; i < afters.length; i++) {
|
try {
|
||||||
afters[i].call(this);
|
fn();
|
||||||
}
|
} catch (e) {
|
||||||
} catch (e) {
|
//TODO: weird. buildExpectationResult is really a presenter for expectations
|
||||||
//TODO: weird. buildExpectationResult is really a presenter for expectations
|
//so this should take an expectation object.
|
||||||
//so this should take an expectation object.
|
self.addExpectationResult(false, self.expectationResultFactory({
|
||||||
this.addExpectationResult(false, this.expectationResultFactory({
|
matcherName: "",
|
||||||
matcherName: "",
|
passed: false,
|
||||||
passed: false,
|
expected: "",
|
||||||
expected: "",
|
actual: "",
|
||||||
actual: "",
|
message: self.exceptionFormatter(e),
|
||||||
message: this.exceptionFormatter(e),
|
trace: e
|
||||||
trace: e
|
}));
|
||||||
}));
|
if (!self.catchExceptions) {
|
||||||
if (!this.catchExceptions) {
|
resultCallback();
|
||||||
throw e;
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
resultCallback.call(this);
|
function queueRunner(allFns, index) {
|
||||||
|
if (index >= allFns.length) {
|
||||||
|
resultCallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var fn = allFns[index];
|
||||||
|
if (fn.length > 0) {
|
||||||
|
attempt(function() { fn.call(self, function() { queueRunner(allFns, index + 1) }) });
|
||||||
|
} else {
|
||||||
|
attempt(function() { fn.call(self); });
|
||||||
|
queueRunner(allFns, index + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resultCallback() {
|
function resultCallback() {
|
||||||
this.resultCallback({
|
self.resultCallback({
|
||||||
id: this.id,
|
id: self.id,
|
||||||
status: this.status(),
|
status: self.status(),
|
||||||
description: this.description,
|
description: self.description,
|
||||||
failedExpectations: this.failedExpectations
|
failedExpectations: self.failedExpectations
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
describe("Spec (integration)", function() {
|
describe("Spec", function() {
|
||||||
it("reports results for passing tests", function() {
|
it("reports results for passing tests", function() {
|
||||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
||||||
expectationFactory = function(actual, spec) {
|
expectationFactory = function(actual, spec) {
|
||||||
expect(actual).toBe('some-actual');
|
expect(actual).toBe('some-actual');
|
||||||
return {
|
return {
|
||||||
pass: function() {
|
pass: function() {
|
||||||
spec.addExpectationResult(true);
|
spec.addExpectationResult(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
spec = new jasmine.Spec({
|
||||||
|
description: 'my test',
|
||||||
|
id: 'some-id',
|
||||||
|
fn: function() {
|
||||||
|
this.expect('some-actual').pass();
|
||||||
},
|
},
|
||||||
spec = new jasmine.Spec({
|
resultCallback: resultCallback,
|
||||||
description: 'my test',
|
expectationFactory: expectationFactory
|
||||||
id: 'some-id',
|
});
|
||||||
fn: function() {
|
|
||||||
this.expect('some-actual').pass();
|
|
||||||
},
|
|
||||||
resultCallback: resultCallback,
|
|
||||||
expectationFactory: expectationFactory
|
|
||||||
});
|
|
||||||
|
|
||||||
spec.execute();
|
spec.execute();
|
||||||
|
|
||||||
@@ -29,24 +29,24 @@ describe("Spec (integration)", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("reports results for failing tests", function() {
|
it("reports results for failing tests", function() {
|
||||||
var resultCallback = jasmine.createSpy('resultCallback'),
|
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
||||||
expectationFactory = function(actual, spec) {
|
expectationFactory = function(actual, spec) {
|
||||||
expect(actual).toBe('some-actual');
|
expect(actual).toBe('some-actual');
|
||||||
return {
|
return {
|
||||||
fail: function() {
|
fail: function() {
|
||||||
spec.addExpectationResult(true);
|
spec.addExpectationResult(true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
spec = new jasmine.Spec({
|
||||||
|
description: 'my test',
|
||||||
|
id: 'some-id',
|
||||||
|
fn: function() {
|
||||||
|
this.expect('some-actual').fail();
|
||||||
},
|
},
|
||||||
spec = new jasmine.Spec({
|
resultCallback: resultCallback,
|
||||||
description: 'my test',
|
expectationFactory: expectationFactory
|
||||||
id: 'some-id',
|
});
|
||||||
fn: function() {
|
|
||||||
this.expect('some-actual').fail();
|
|
||||||
},
|
|
||||||
resultCallback: resultCallback,
|
|
||||||
expectationFactory: expectationFactory
|
|
||||||
});
|
|
||||||
|
|
||||||
spec.execute();
|
spec.execute();
|
||||||
|
|
||||||
@@ -58,14 +58,13 @@ describe("Spec (integration)", function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
//TODO: test order of befores, spec, after.
|
|
||||||
it("executes before fns, after fns", function() {
|
it("executes before fns, after fns", function() {
|
||||||
var before = jasmine.createSpy('before'),
|
var before = originalJasmine.createSpy('before'),
|
||||||
after = jasmine.createSpy('after'),
|
after = originalJasmine.createSpy('after'),
|
||||||
fn = originalJasmine.createSpy('test body').andCallFake(function() {
|
fn = originalJasmine.createSpy('test body').andCallFake(function() {
|
||||||
expect(before).toHaveBeenCalled();
|
expect(before).toHaveBeenCalled();
|
||||||
expect(after).not.toHaveBeenCalled();
|
expect(after).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
spec = new jasmine.Spec({
|
spec = new jasmine.Spec({
|
||||||
fn: fn,
|
fn: fn,
|
||||||
beforeFns: function() {
|
beforeFns: function() {
|
||||||
@@ -86,9 +85,61 @@ describe("Spec (integration)", function() {
|
|||||||
expect(after).toHaveBeenCalled();
|
expect(after).toHaveBeenCalled();
|
||||||
expect(after.mostRecentCall.object).toBe(spec);
|
expect(after.mostRecentCall.object).toBe(spec);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
describe("Spec (real-ish unit tests)", function() {
|
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();
|
||||||
|
|
||||||
|
spec.execute();
|
||||||
|
|
||||||
|
expect(beforeCallback).toHaveBeenCalled();
|
||||||
|
expect(fnCallback).not.toHaveBeenCalled();
|
||||||
|
expect(afterCallback).not.toHaveBeenCalled();
|
||||||
|
expect(resultCallback).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
clock.tick(100);
|
||||||
|
|
||||||
|
expect(fnCallback).toHaveBeenCalled();
|
||||||
|
expect(afterCallback).not.toHaveBeenCalled();
|
||||||
|
expect(resultCallback).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
clock.tick(100);
|
||||||
|
|
||||||
|
expect(afterCallback).toHaveBeenCalled();
|
||||||
|
expect(resultCallback).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
clock.tick(100);
|
||||||
|
|
||||||
|
expect(resultCallback).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
it("status returns null by default", function() {
|
it("status returns null by default", function() {
|
||||||
var spec = new jasmine.Spec({});
|
var spec = new jasmine.Spec({});
|
||||||
expect(spec.status()).toBeNull();
|
expect(spec.status()).toBeNull();
|
||||||
@@ -110,13 +161,13 @@ describe("Spec (real-ish unit tests)", function() {
|
|||||||
it("calls the resultCallback with a failure when an exception occurs in the spec fn", function() {
|
it("calls the resultCallback with a failure when an exception occurs in the spec fn", function() {
|
||||||
//TODO: one day we should pass a stack with this.
|
//TODO: one day we should pass a stack with this.
|
||||||
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
||||||
spec = new jasmine.Spec({
|
spec = new jasmine.Spec({
|
||||||
fn: function() {
|
fn: function() {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
},
|
},
|
||||||
catchExceptions: true,
|
catchExceptions: true,
|
||||||
resultCallback: resultCallback
|
resultCallback: resultCallback
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(resultCallback).not.toHaveBeenCalled();
|
expect(resultCallback).not.toHaveBeenCalled();
|
||||||
spec.execute();
|
spec.execute();
|
||||||
@@ -129,13 +180,13 @@ describe("Spec (real-ish unit tests)", function() {
|
|||||||
it("throws when an exception occurs in the spec fn if catchExceptions is false", function() {
|
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.
|
//TODO: one day we should pass a stack with this.
|
||||||
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
var resultCallback = originalJasmine.createSpy('resultCallback'),
|
||||||
spec = new jasmine.Spec({
|
spec = new jasmine.Spec({
|
||||||
fn: function() {
|
fn: function() {
|
||||||
throw new Error();
|
throw new Error();
|
||||||
},
|
},
|
||||||
catchExceptions: false,
|
catchExceptions: false,
|
||||||
resultCallback: resultCallback
|
resultCallback: resultCallback
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(function() {
|
expect(function() {
|
||||||
spec.execute();
|
spec.execute();
|
||||||
@@ -144,22 +195,22 @@ describe("Spec (real-ish unit tests)", function() {
|
|||||||
|
|
||||||
it("should call the start callback before any befores are called", function() {
|
it("should call the start callback before any befores are called", function() {
|
||||||
var beforesWereCalled = false,
|
var beforesWereCalled = false,
|
||||||
startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
|
startCallback = originalJasmine.createSpy('start-callback').andCallFake(function() {
|
||||||
expect(beforesWereCalled).toBe(false);
|
expect(beforesWereCalled).toBe(false);
|
||||||
}),
|
}),
|
||||||
spec = new jasmine.Spec({
|
spec = new jasmine.Spec({
|
||||||
fn: function() {
|
fn: function() {
|
||||||
},
|
},
|
||||||
beforeFns: function() {
|
beforeFns: function() {
|
||||||
return [function() {
|
return [function() {
|
||||||
beforesWereCalled = true
|
beforesWereCalled = true
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
startCallback: startCallback,
|
startCallback: startCallback,
|
||||||
catchExceptions: false,
|
catchExceptions: false,
|
||||||
resultCallback: function() {
|
resultCallback: function() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
spec.execute();
|
spec.execute();
|
||||||
expect(startCallback).toHaveBeenCalled();
|
expect(startCallback).toHaveBeenCalled();
|
||||||
@@ -177,15 +228,15 @@ describe("Spec (real-ish unit tests)", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("can be disabled", function() {
|
it("can be disabled", function() {
|
||||||
var startCallback = jasmine.createSpy('startCallback'),
|
var startCallback = originalJasmine.createSpy('startCallback'),
|
||||||
specBody = jasmine.createSpy('specBody'),
|
specBody = originalJasmine.createSpy('specBody'),
|
||||||
resultCallback = jasmine.createSpy('resultCallback'),
|
resultCallback = originalJasmine.createSpy('resultCallback'),
|
||||||
spec = new jasmine.Spec({
|
spec = new jasmine.Spec({
|
||||||
startCallback: startCallback,
|
startCallback: startCallback,
|
||||||
fn: specBody,
|
fn: specBody,
|
||||||
resultCallback: resultCallback
|
resultCallback: resultCallback
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
spec.disable();
|
spec.disable();
|
||||||
expect(spec.status()).toBe('disabled');
|
expect(spec.status()).toBe('disabled');
|
||||||
@@ -198,3 +249,4 @@ describe("Spec (real-ish unit tests)", function() {
|
|||||||
expect(resultCallback).toHaveBeenCalled();
|
expect(resultCallback).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,11 @@ var jasmineInterface = {
|
|||||||
return env.spyOn(obj, methodName);
|
return env.spyOn(obj, methodName);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
clock: env.clock,
|
||||||
|
setTimeout: env.clock.setTimeout,
|
||||||
|
clearTimeout: env.clock.clearTimeout,
|
||||||
|
setInterval: env.clock.setInterval,
|
||||||
|
clearInterval: env.clock.clearInterval,
|
||||||
|
|
||||||
jsApiReporter: new jasmine.JsApiReporter(jasmine)
|
jsApiReporter: new jasmine.JsApiReporter(jasmine)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,47 +27,60 @@ jasmine.Spec.prototype.expect = function(actual) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
jasmine.Spec.prototype.execute = function() {
|
jasmine.Spec.prototype.execute = function() {
|
||||||
|
var self = this;
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
resultCallback.call(this);
|
resultCallback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var befores = this.beforeFns() || [],
|
var befores = this.beforeFns() || [],
|
||||||
afters = this.afterFns() || [];
|
afters = this.afterFns() || [];
|
||||||
this.startCallback(this);
|
this.startCallback(this);
|
||||||
try {
|
var allFns = befores.concat(this.fn).concat(afters);
|
||||||
for (var i = 0; i < befores.length; i++) {
|
|
||||||
befores[i].call(this);
|
queueRunner(allFns, 0);
|
||||||
}
|
|
||||||
this.fn.call(this);
|
function attempt(fn) {
|
||||||
for (i = 0; i < afters.length; i++) {
|
try {
|
||||||
afters[i].call(this);
|
fn();
|
||||||
}
|
} catch (e) {
|
||||||
} catch (e) {
|
//TODO: weird. buildExpectationResult is really a presenter for expectations
|
||||||
//TODO: weird. buildExpectationResult is really a presenter for expectations
|
//so this should take an expectation object.
|
||||||
//so this should take an expectation object.
|
self.addExpectationResult(false, self.expectationResultFactory({
|
||||||
this.addExpectationResult(false, this.expectationResultFactory({
|
matcherName: "",
|
||||||
matcherName: "",
|
passed: false,
|
||||||
passed: false,
|
expected: "",
|
||||||
expected: "",
|
actual: "",
|
||||||
actual: "",
|
message: self.exceptionFormatter(e),
|
||||||
message: this.exceptionFormatter(e),
|
trace: e
|
||||||
trace: e
|
}));
|
||||||
}));
|
if (!self.catchExceptions) {
|
||||||
if (!this.catchExceptions) {
|
resultCallback();
|
||||||
throw e;
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally {
|
|
||||||
resultCallback.call(this);
|
function queueRunner(allFns, index) {
|
||||||
|
if (index >= allFns.length) {
|
||||||
|
resultCallback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var fn = allFns[index];
|
||||||
|
if (fn.length > 0) {
|
||||||
|
attempt(function() { fn.call(self, function() { queueRunner(allFns, index + 1) }) });
|
||||||
|
} else {
|
||||||
|
attempt(function() { fn.call(self); });
|
||||||
|
queueRunner(allFns, index + 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resultCallback() {
|
function resultCallback() {
|
||||||
this.resultCallback({
|
self.resultCallback({
|
||||||
id: this.id,
|
id: self.id,
|
||||||
status: this.status(),
|
status: self.status(),
|
||||||
description: this.description,
|
description: self.description,
|
||||||
failedExpectations: this.failedExpectations
|
failedExpectations: self.failedExpectations
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user