Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Re-add async support (achieved via done callbacks)

- TODO: pull out queueRunner into a new object.
  • Loading branch information...
commit a526ebf26179afaad719e73de198c265031e5241 1 parent c2e1327
Davis W. Frank & Rajan Agaskar authored
View
8 lib/jasmine-core/boot/boot.js
@@ -38,9 +38,11 @@
return env.spyOn(obj, methodName);
},
- clock: function() {
- return env.clock;
- },
+ clock: env.clock,
+ setTimeout: env.clock.setTimeout,
+ clearTimeout: env.clock.clearTimeout,
+ setInterval: env.clock.setInterval,
+ clearInterval: env.clock.clearInterval,
jsApiReporter: new jasmine.JsApiReporter(jasmine)
};
View
69 lib/jasmine-core/jasmine.js
@@ -1958,47 +1958,60 @@ jasmine.Spec.prototype.expect = function(actual) {
};
jasmine.Spec.prototype.execute = function() {
+ var self = this;
if (this.disabled) {
- resultCallback.call(this);
+ resultCallback();
return;
}
var befores = this.beforeFns() || [],
afters = this.afterFns() || [];
this.startCallback(this);
- try {
- for (var i = 0; i < befores.length; i++) {
- befores[i].call(this);
+ var allFns = befores.concat(this.fn).concat(afters);
+
+ queueRunner(allFns, 0);
+
+ function attempt(fn) {
+ try {
+ fn();
+ } catch (e) {
+ //TODO: weird. buildExpectationResult is really a presenter for expectations
+ //so this should take an expectation object.
+ self.addExpectationResult(false, self.expectationResultFactory({
+ matcherName: "",
+ passed: false,
+ expected: "",
+ actual: "",
+ message: self.exceptionFormatter(e),
+ trace: e
+ }));
+ if (!self.catchExceptions) {
+ resultCallback();
+ throw e;
+ }
}
- this.fn.call(this);
- for (i = 0; i < afters.length; i++) {
- afters[i].call(this);
+ }
+
+ function queueRunner(allFns, index) {
+ if (index >= allFns.length) {
+ resultCallback();
+ return;
}
- } catch (e) {
- //TODO: weird. buildExpectationResult is really a presenter for expectations
- //so this should take an expectation object.
- this.addExpectationResult(false, this.expectationResultFactory({
- matcherName: "",
- passed: false,
- expected: "",
- actual: "",
- message: this.exceptionFormatter(e),
- trace: e
- }));
- if (!this.catchExceptions) {
- throw e;
+ 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);
}
}
- finally {
- resultCallback.call(this);
- }
function resultCallback() {
- this.resultCallback({
- id: this.id,
- status: this.status(),
- description: this.description,
- failedExpectations: this.failedExpectations
+ self.resultCallback({
+ id: self.id,
+ status: self.status(),
+ description: self.description,
+ failedExpectations: self.failedExpectations
});
}
};
View
212 spec/core/SpecSpec.js
@@ -1,23 +1,23 @@
-describe("Spec (integration)", function() {
+describe("Spec", function() {
it("reports results for passing tests", function() {
- var resultCallback = jasmine.createSpy('resultCallback'),
- expectationFactory = function(actual, spec) {
- expect(actual).toBe('some-actual');
- return {
- pass: function() {
- spec.addExpectationResult(true);
- }
+ 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();
},
- spec = new jasmine.Spec({
- description: 'my test',
- id: 'some-id',
- fn: function() {
- this.expect('some-actual').pass();
- },
- resultCallback: resultCallback,
- expectationFactory: expectationFactory
- });
+ resultCallback: resultCallback,
+ expectationFactory: expectationFactory
+ });
spec.execute();
@@ -29,24 +29,24 @@ describe("Spec (integration)", function() {
});
});
it("reports results for failing tests", function() {
- var resultCallback = jasmine.createSpy('resultCallback'),
- expectationFactory = function(actual, spec) {
- expect(actual).toBe('some-actual');
- return {
- fail: function() {
- spec.addExpectationResult(true);
- }
+ 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();
},
- spec = new jasmine.Spec({
- description: 'my test',
- id: 'some-id',
- fn: function() {
- this.expect('some-actual').fail();
- },
- resultCallback: resultCallback,
- expectationFactory: expectationFactory
- });
+ resultCallback: resultCallback,
+ expectationFactory: expectationFactory
+ });
spec.execute();
@@ -58,14 +58,13 @@ describe("Spec (integration)", function() {
});
});
- //TODO: test order of befores, spec, after.
it("executes before fns, after fns", function() {
- var before = jasmine.createSpy('before'),
- after = jasmine.createSpy('after'),
- fn = originalJasmine.createSpy('test body').andCallFake(function() {
- expect(before).toHaveBeenCalled();
- expect(after).not.toHaveBeenCalled();
- });
+ 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() {
@@ -86,9 +85,61 @@ describe("Spec (integration)", function() {
expect(after).toHaveBeenCalled();
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() {
var spec = new jasmine.Spec({});
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() {
//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: true,
- resultCallback: resultCallback
- });
+ spec = new jasmine.Spec({
+ fn: function() {
+ throw new Error();
+ },
+ catchExceptions: true,
+ resultCallback: resultCallback
+ });
expect(resultCallback).not.toHaveBeenCalled();
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() {
//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
- });
+ spec = new jasmine.Spec({
+ fn: function() {
+ throw new Error();
+ },
+ catchExceptions: false,
+ resultCallback: resultCallback
+ });
expect(function() {
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() {
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() {
- }
- });
+ 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();
@@ -177,15 +228,15 @@ describe("Spec (real-ish unit tests)", function() {
});
it("can be disabled", function() {
- var startCallback = jasmine.createSpy('startCallback'),
- specBody = jasmine.createSpy('specBody'),
- resultCallback = jasmine.createSpy('resultCallback'),
- spec = new jasmine.Spec({
- startCallback: startCallback,
- fn: specBody,
- resultCallback: resultCallback
+ 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');
@@ -198,3 +249,4 @@ describe("Spec (real-ish unit tests)", function() {
expect(resultCallback).toHaveBeenCalled();
});
});
+
View
5 spec/node_suite.js
@@ -49,6 +49,11 @@ var jasmineInterface = {
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)
};
View
69 src/core/Spec.js
@@ -27,47 +27,60 @@ jasmine.Spec.prototype.expect = function(actual) {
};
jasmine.Spec.prototype.execute = function() {
+ var self = this;
if (this.disabled) {
- resultCallback.call(this);
+ resultCallback();
return;
}
var befores = this.beforeFns() || [],
afters = this.afterFns() || [];
this.startCallback(this);
- try {
- for (var i = 0; i < befores.length; i++) {
- befores[i].call(this);
+ var allFns = befores.concat(this.fn).concat(afters);
+
+ queueRunner(allFns, 0);
+
+ function attempt(fn) {
+ try {
+ fn();
+ } catch (e) {
+ //TODO: weird. buildExpectationResult is really a presenter for expectations
+ //so this should take an expectation object.
+ self.addExpectationResult(false, self.expectationResultFactory({
+ matcherName: "",
+ passed: false,
+ expected: "",
+ actual: "",
+ message: self.exceptionFormatter(e),
+ trace: e
+ }));
+ if (!self.catchExceptions) {
+ resultCallback();
+ throw e;
+ }
}
- this.fn.call(this);
- for (i = 0; i < afters.length; i++) {
- afters[i].call(this);
+ }
+
+ function queueRunner(allFns, index) {
+ if (index >= allFns.length) {
+ resultCallback();
+ return;
}
- } catch (e) {
- //TODO: weird. buildExpectationResult is really a presenter for expectations
- //so this should take an expectation object.
- this.addExpectationResult(false, this.expectationResultFactory({
- matcherName: "",
- passed: false,
- expected: "",
- actual: "",
- message: this.exceptionFormatter(e),
- trace: e
- }));
- if (!this.catchExceptions) {
- throw e;
+ 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);
}
}
- finally {
- resultCallback.call(this);
- }
function resultCallback() {
- this.resultCallback({
- id: this.id,
- status: this.status(),
- description: this.description,
- failedExpectations: this.failedExpectations
+ self.resultCallback({
+ id: self.id,
+ status: self.status(),
+ description: self.description,
+ failedExpectations: self.failedExpectations
});
}
};
Please sign in to comment.
Something went wrong with that request. Please try again.