Separate clear stack and run it after each spec
[finishes #50197985][fix #109418332] - Fixes #985 - Fixes #945 - Fixes #366
This commit is contained in:
73
spec/core/ClearStackSpec.js
Normal file
73
spec/core/ClearStackSpec.js
Normal file
@@ -0,0 +1,73 @@
|
||||
describe("ClearStack", function() {
|
||||
it("works in an integrationy way", function(done) {
|
||||
var global = {
|
||||
setTimeout: typeof setTimeout === 'undefined' ? undefined : setTimeout,
|
||||
setImmediate: typeof setImmediate === 'undefined' ? undefined : setImmediate,
|
||||
MessageChannel: typeof MessageChannel === 'undefined' ? undefined : MessageChannel,
|
||||
process: typeof process === 'undefined' ? undefined : process
|
||||
},
|
||||
clearStack = jasmineUnderTest.getClearStack(global);
|
||||
|
||||
clearStack(function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("uses nextTick when available", function() {
|
||||
var nextTick = jasmine.createSpy('nextTick').and.callFake(function(fn) { fn() }),
|
||||
global = { process: { nextTick: nextTick } },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
expect(nextTick).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("uses setImmediate when available", function() {
|
||||
var setImmediate = jasmine.createSpy('setImmediate').and.callFake(function(fn) { fn() }),
|
||||
global = { setImmediate: setImmediate },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
expect(setImmediate).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("uses MessageChannels when available", function() {
|
||||
var fakeChannel = {
|
||||
port1: {},
|
||||
port2: { postMessage: function() { fakeChannel.port1.onmessage(); } }
|
||||
},
|
||||
global = { MessageChannel: function() { return fakeChannel; } },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
});
|
||||
|
||||
it("falls back to setTimeout", function() {
|
||||
var setTimeout = jasmine.createSpy('setTimeout').and.callFake(function(fn) { fn() }),
|
||||
global = { setTimeout: setTimeout },
|
||||
clearStack = jasmineUnderTest.getClearStack(global),
|
||||
called = false;
|
||||
|
||||
clearStack(function() {
|
||||
called = true;
|
||||
});
|
||||
|
||||
expect(called).toBe(true);
|
||||
expect(setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 0);
|
||||
});
|
||||
});
|
||||
@@ -1130,6 +1130,7 @@ describe("Env integration", function() {
|
||||
env.fail();
|
||||
innerDone();
|
||||
}, 1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
|
||||
env.it('specifies a message', function(innerDone) {
|
||||
@@ -1137,12 +1138,14 @@ describe("Env integration", function() {
|
||||
env.fail('messy message');
|
||||
innerDone();
|
||||
}, 1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
|
||||
env.it('fails via the done callback', function(innerDone) {
|
||||
setTimeout(function() {
|
||||
innerDone.fail('done failed');
|
||||
}, 1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
|
||||
env.it('has a message from an Error', function(innerDone) {
|
||||
@@ -1150,14 +1153,11 @@ describe("Env integration", function() {
|
||||
env.fail(new Error('error message'));
|
||||
innerDone();
|
||||
}, 1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
});
|
||||
|
||||
env.execute();
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
jasmine.clock().tick(1);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1186,7 +1186,7 @@ describe("Env integration", function() {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('should only run focused suites', function(){
|
||||
it('should only run focused suites', function(done){
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
calls = [];
|
||||
|
||||
@@ -1572,14 +1572,17 @@ describe("Env integration", function() {
|
||||
});
|
||||
|
||||
it("produces an understandable error message when an 'expect' is used outside of a current spec", function(done) {
|
||||
var env = new jasmineUnderTest.Env();
|
||||
var env = new jasmineUnderTest.Env(),
|
||||
reporter = jasmine.createSpyObj('fakeReporter', ['jasmineDone']);
|
||||
|
||||
reporter.jasmineDone.and.callFake(done);
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.describe("A Suite", function() {
|
||||
env.it("an async spec that is actually synchronous", function(underTestCallback) {
|
||||
underTestCallback();
|
||||
expect(function() { env.expect('a').toEqual('a'); }).toThrowError(/'expect' was used when there was no current spec/);
|
||||
done();
|
||||
});
|
||||
expect(function() { env.expect('a').toEqual('a'); }).toThrowError(/'expect' was used when there was no current spec/);
|
||||
});
|
||||
|
||||
env.execute();
|
||||
|
||||
@@ -475,7 +475,7 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it('focused runnables unfocus ancestor focused suites', function() {
|
||||
it('focused runnables unfocus ancestor focused suites', function(done) {
|
||||
var actions = [];
|
||||
|
||||
env.fdescribe('focused suite', function() {
|
||||
@@ -518,7 +518,7 @@ describe("jasmine spec running", function () {
|
||||
env.execute();
|
||||
});
|
||||
|
||||
it("should allow top level suites to be disabled", function() {
|
||||
it("should allow top level suites to be disabled", function(done) {
|
||||
var specInADisabledSuite = jasmine.createSpy("specInADisabledSuite"),
|
||||
otherSpec = jasmine.createSpy("otherSpec");
|
||||
|
||||
|
||||
36
src/core/ClearStack.js
Normal file
36
src/core/ClearStack.js
Normal file
@@ -0,0 +1,36 @@
|
||||
getJasmineRequireObj().clearStack = function(j$) {
|
||||
function messageChannelImpl(global) {
|
||||
var channel = new global.MessageChannel(),
|
||||
head = {},
|
||||
tail = head;
|
||||
|
||||
channel.port1.onmessage = function() {
|
||||
head = head.next;
|
||||
var task = head.task;
|
||||
delete head.task;
|
||||
task();
|
||||
};
|
||||
|
||||
return function clearStack(fn) {
|
||||
tail = tail.next = { task: fn };
|
||||
channel.port2.postMessage(0);
|
||||
};
|
||||
}
|
||||
|
||||
function getClearStack(global) {
|
||||
if (global && global.process && j$.isFunction_(global.process.nextTick)) {
|
||||
return global.process.nextTick;
|
||||
} else if (j$.isFunction_(global.setImmediate)) {
|
||||
return global.setImmediate;
|
||||
} else if (!j$.util.isUndefined(global.MessageChannel)) {
|
||||
return messageChannelImpl(global);
|
||||
} else if (j$.isFunction_(global.setTimeout)) {
|
||||
var realSetTimeout = global.setTimeout;
|
||||
return function clearStack(fn) {
|
||||
realSetTimeout(fn, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return getClearStack;
|
||||
};
|
||||
@@ -11,6 +11,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
var realSetTimeout = j$.getGlobal().setTimeout;
|
||||
var realClearTimeout = j$.getGlobal().clearTimeout;
|
||||
var clearStack = j$.getClearStack(j$.getGlobal());
|
||||
this.clock = new j$.Clock(global, function () { return new j$.DelayedFunctionScheduler(); }, new j$.MockDate(global));
|
||||
|
||||
var runnableResources = {};
|
||||
@@ -154,16 +155,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
var maximumSpecCallbackDepth = 20;
|
||||
var currentSpecCallbackDepth = 0;
|
||||
|
||||
function clearStack(fn) {
|
||||
currentSpecCallbackDepth++;
|
||||
if (currentSpecCallbackDepth >= maximumSpecCallbackDepth) {
|
||||
currentSpecCallbackDepth = 0;
|
||||
realSetTimeout(fn, 0);
|
||||
} else {
|
||||
fn();
|
||||
}
|
||||
}
|
||||
|
||||
var catchException = function(e) {
|
||||
return j$.Spec.isPendingSpecException(e) || catchExceptions;
|
||||
};
|
||||
|
||||
@@ -42,11 +42,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
|
||||
}
|
||||
}
|
||||
|
||||
var runnerDone = iterativeIndex >= length;
|
||||
|
||||
if (runnerDone) {
|
||||
this.clearStack(this.onComplete);
|
||||
}
|
||||
this.clearStack(this.onComplete);
|
||||
|
||||
function attemptSync(queueableFn) {
|
||||
try {
|
||||
|
||||
@@ -30,6 +30,7 @@ var getJasmineRequireObj = (function (jasmineGlobal) {
|
||||
j$.Anything = jRequire.Anything(j$);
|
||||
j$.CallTracker = jRequire.CallTracker(j$);
|
||||
j$.MockDate = jRequire.MockDate();
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler();
|
||||
j$.Env = jRequire.Env(j$);
|
||||
|
||||
Reference in New Issue
Block a user