Consistently identify clenaup fns by a type tag, not position

This was already done for everything except spec cleanup fns, since the
various skip policies need to know the difference between afterEach and
afterAll.
This commit is contained in:
Steve Gravrock
2021-10-11 17:58:40 -07:00
parent 25c3f06839
commit 41f5c53959
13 changed files with 182 additions and 184 deletions

View File

@@ -870,16 +870,15 @@ getJasmineRequireObj().Spec = function(j$) {
} }
self.resultCallback(self.result, done); self.resultCallback(self.result, done);
} },
type: 'specCleanup'
}; };
var fns = this.beforeAndAfterFns(); var fns = this.beforeAndAfterFns();
var regularFns = fns.befores.concat(this.queueableFn);
var runnerConfig = { var runnerConfig = {
isLeaf: true, isLeaf: true,
queueableFns: regularFns, queueableFns: [...fns.befores, this.queueableFn, ...fns.afters],
cleanupFns: fns.afters,
onException: function() { onException: function() {
self.onException.apply(self, arguments); self.onException.apply(self, arguments);
}, },
@@ -909,11 +908,10 @@ getJasmineRequireObj().Spec = function(j$) {
if (this.markedPending || excluded === true) { if (this.markedPending || excluded === true) {
runnerConfig.queueableFns = []; runnerConfig.queueableFns = [];
runnerConfig.cleanupFns = [];
} }
runnerConfig.queueableFns.unshift(onStart); runnerConfig.queueableFns.unshift(onStart);
runnerConfig.cleanupFns.push(complete); runnerConfig.queueableFns.push(complete);
this.queueRunnerFactory(runnerConfig); this.queueRunnerFactory(runnerConfig);
}; };
@@ -3466,9 +3464,8 @@ getJasmineRequireObj().Clock = function() {
}; };
getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) { getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
function CompleteOnFirstErrorSkipPolicy(queueableFns, firstCleanupIx) { function CompleteOnFirstErrorSkipPolicy(queueableFns) {
this.queueableFns_ = queueableFns; this.queueableFns_ = queueableFns;
this.firstCleanupIx_ = firstCleanupIx;
this.erroredFnIx_ = null; this.erroredFnIx_ = null;
} }
@@ -3490,16 +3487,15 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
return false; return false;
} }
// firstCleanupIx_ isn't correct for suites with afterAll functions. const fn = this.queueableFns_[fnIx];
// Rely on the type for those. const candidateSuite = fn.suite;
if (this.queueableFns_[fnIx].type === 'afterAll') {
return false;
}
const candidateSuite = this.queueableFns_[fnIx].suite;
const errorSuite = this.queueableFns_[this.erroredFnIx_].suite; const errorSuite = this.queueableFns_[this.erroredFnIx_].suite;
const wasCleanupFn =
fn.type === 'afterEach' ||
fn.type === 'afterAll' ||
fn.type === 'specCleanup';
return ( return (
fnIx < this.firstCleanupIx_ || !wasCleanupFn ||
(candidateSuite && isDescendent(candidateSuite, errorSuite)) (candidateSuite && isDescendent(candidateSuite, errorSuite))
); );
}; };
@@ -7395,7 +7391,7 @@ getJasmineRequireObj().MockDate = function(j$) {
}; };
getJasmineRequireObj().NeverSkipPolicy = function(j$) { getJasmineRequireObj().NeverSkipPolicy = function(j$) {
function NeverSkipPolicy(queueableFns, firstCleanupIx) {} function NeverSkipPolicy(queueableFns) {}
NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx) { NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
return lastRanFnIx + 1; return lastRanFnIx + 1;
@@ -7849,9 +7845,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
function QueueRunner(attrs) { function QueueRunner(attrs) {
this.id_ = nextid++; this.id_ = nextid++;
var queueableFns = attrs.queueableFns || []; this.queueableFns = attrs.queueableFns || [];
this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
this.firstCleanupIx = queueableFns.length;
this.onComplete = attrs.onComplete || emptyFn; this.onComplete = attrs.onComplete || emptyFn;
this.clearStack = this.clearStack =
attrs.clearStack || attrs.clearStack ||
@@ -7872,7 +7866,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}; };
const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy; const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy;
this.skipPolicy_ = new SkipPolicy(this.queueableFns, this.firstCleanupIx); this.skipPolicy_ = new SkipPolicy(this.queueableFns);
this.errored_ = false; this.errored_ = false;
if (typeof this.onComplete !== 'function') { if (typeof this.onComplete !== 'function') {
@@ -8610,7 +8604,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
}; };
getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) { getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {
function SkipAfterBeforeAllErrorPolicy(queueableFns, firstCleanupIx) { function SkipAfterBeforeAllErrorPolicy(queueableFns) {
this.queueableFns_ = queueableFns; this.queueableFns_ = queueableFns;
this.skipping_ = false; this.skipping_ = false;
} }
@@ -9600,15 +9594,15 @@ getJasmineRequireObj().Suite = function(j$) {
}; };
Suite.prototype.beforeAll = function(fn) { Suite.prototype.beforeAll = function(fn) {
this.beforeAllFns.push(fn); this.beforeAllFns.push({ ...fn, type: 'beforeAll' });
}; };
Suite.prototype.afterEach = function(fn) { Suite.prototype.afterEach = function(fn) {
this.afterFns.unshift({ ...fn, suite: this }); this.afterFns.unshift({ ...fn, suite: this, type: 'afterEach' });
}; };
Suite.prototype.afterAll = function(fn) { Suite.prototype.afterAll = function(fn) {
this.afterAllFns.unshift(fn); this.afterAllFns.unshift({ ...fn, type: 'afterAll' });
}; };
Suite.prototype.startTimer = function() { Suite.prototype.startTimer = function() {
@@ -10112,16 +10106,7 @@ getJasmineRequireObj().TreeProcessor = function() {
return result; return result;
} }
return node.beforeAllFns return node.beforeAllFns.concat(result).concat(node.afterAllFns);
.map(function(fn) {
return { type: 'beforeAll', ...fn };
})
.concat(result)
.concat(
node.afterAllFns.map(function(fn) {
return { type: 'afterAll', ...fn };
})
);
} }
} }

View File

@@ -13,10 +13,9 @@ describe('CompleteOnFirstErrorSkipPolicy', function() {
describe('After something has errored', function() { describe('After something has errored', function() {
it('skips non cleanup fns', function() { it('skips non cleanup fns', function() {
const fns = arrayOfArbitraryFns(4); const fns = arrayOfArbitraryFns(4);
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy( fns[2].type = arbitraryCleanupType();
fns, fns[3].type = arbitraryCleanupType();
2 const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(fns);
);
policy.fnErrored(0); policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(2); expect(policy.skipTo(0)).toEqual(2);
@@ -24,6 +23,19 @@ describe('CompleteOnFirstErrorSkipPolicy', function() {
expect(policy.skipTo(3)).toEqual(4); expect(policy.skipTo(3)).toEqual(4);
}); });
for (const type of ['afterEach', 'specCleanup', 'afterAll']) {
it(`does not skip ${type} fns`, function() {
const fns = arrayOfArbitraryFns(2);
fns[1].type = type;
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1);
});
}
describe('When the error was in a beforeEach fn', function() { describe('When the error was in a beforeEach fn', function() {
it('runs cleanup fns defined by the current and containing suites', function() { it('runs cleanup fns defined by the current and containing suites', function() {
const parentSuite = { description: 'parentSuite' }; const parentSuite = { description: 'parentSuite' };
@@ -37,16 +49,17 @@ describe('CompleteOnFirstErrorSkipPolicy', function() {
}, },
{ {
fn: () => {}, fn: () => {},
suite: suite suite: suite,
type: arbitraryCleanupType()
}, },
{ {
fn: () => {}, fn: () => {},
suite: parentSuite suite: parentSuite,
type: arbitraryCleanupType()
} }
]; ];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy( const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns, fns
2
); );
policy.fnErrored(0); policy.fnErrored(0);
@@ -68,16 +81,17 @@ describe('CompleteOnFirstErrorSkipPolicy', function() {
}, },
{ {
fn: () => {}, fn: () => {},
suite: suite suite: suite,
type: arbitraryCleanupType()
}, },
{ {
fn: () => {}, fn: () => {},
suite: parentSuite suite: parentSuite,
type: arbitraryCleanupType()
} }
]; ];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy( const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns, fns
2
); );
policy.fnErrored(0); policy.fnErrored(0);
@@ -86,42 +100,32 @@ describe('CompleteOnFirstErrorSkipPolicy', function() {
}); });
it('does not skip cleanup fns that have no suite, such as the spec complete fn', function() { it('does not skip cleanup fns that have no suite, such as the spec complete fn', function() {
const fns = [{ fn: () => {} }, { fn: () => {} }];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(
fns,
1
);
policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1);
});
it('does not skip afterAll fns, even if before the first cleanup fn index', function() {
const fns = [ const fns = [
{ fn: () => {} }, { fn: () => {} },
{ {
fn: () => {}, fn: () => {},
type: 'afterAll' type: arbitraryCleanupType()
} }
]; ];
const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy( const policy = new jasmineUnderTest.CompleteOnFirstErrorSkipPolicy(fns);
fns,
2
);
policy.fnErrored(0); policy.fnErrored(0);
expect(policy.skipTo(0)).toEqual(1); expect(policy.skipTo(0)).toEqual(1);
}); });
}); });
}); });
});
function arrayOfArbitraryFns(n) { function arrayOfArbitraryFns(n) {
const result = []; const result = [];
for (let i = 0; i < n; i++) { for (let i = 0; i < n; i++) {
result.push({ fn: () => {} }); result.push({ fn: () => {} });
}
return result;
} }
return result; function arbitraryCleanupType() {
} return 'specCleanup';
}
});

View File

@@ -18,26 +18,6 @@ describe('QueueRunner', function() {
expect(calls).toEqual(['fn1', 'fn2']); expect(calls).toEqual(['fn1', 'fn2']);
}); });
it('runs cleanup functions after the others', function() {
var calls = [],
queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') },
queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn1],
cleanupFns: [queueableFn2]
});
queueableFn1.fn.and.callFake(function() {
calls.push('fn1');
});
queueableFn2.fn.and.callFake(function() {
calls.push('fn2');
});
queueRunner.execute();
expect(calls).toEqual(['fn1', 'fn2']);
});
it("calls each function with a consistent 'this'-- an empty object", function() { it("calls each function with a consistent 'this'-- an empty object", function() {
var queueableFn1 = { fn: jasmine.createSpy('fn1') }, var queueableFn1 = { fn: jasmine.createSpy('fn1') },
queueableFn2 = { fn: jasmine.createSpy('fn2') }, queueableFn2 = { fn: jasmine.createSpy('fn2') },
@@ -653,18 +633,13 @@ describe('QueueRunner', function() {
it('instantiates the skip policy', function() { it('instantiates the skip policy', function() {
const SkipPolicy = jasmine.createSpy('SkipPolicy ctor'); const SkipPolicy = jasmine.createSpy('SkipPolicy ctor');
const queueableFns = [{ fn: () => {} }, { fn: () => {} }]; const queueableFns = [{ fn: () => {} }, { fn: () => {} }];
const cleanupFns = [{ fn: () => {} }];
new jasmineUnderTest.QueueRunner({ new jasmineUnderTest.QueueRunner({
queueableFns, queueableFns,
cleanupFns,
SkipPolicy SkipPolicy
}); });
expect(SkipPolicy).toHaveBeenCalledWith( expect(SkipPolicy).toHaveBeenCalledWith(queueableFns);
[...queueableFns, ...cleanupFns],
2
);
}); });
it('uses the skip policy to determine which fn to run next', function() { it('uses the skip policy to determine which fn to run next', function() {
@@ -723,11 +698,13 @@ describe('QueueRunner', function() {
} }
}, },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') }, nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') }, cleanupFn = {
fn: jasmine.createSpy('cleanup'),
type: 'specCleanup'
},
onComplete = jasmine.createSpy('onComplete'), onComplete = jasmine.createSpy('onComplete'),
queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn], queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
cleanupFns: [cleanupFn],
onComplete: onComplete, onComplete: onComplete,
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}); });
@@ -745,12 +722,15 @@ describe('QueueRunner', function() {
cleanupFn1 = { cleanupFn1 = {
fn: function() { fn: function() {
throw new Error('error'); throw new Error('error');
} },
type: 'afterEach'
},
cleanupFn2 = {
fn: jasmine.createSpy('cleanupFn2'),
type: 'afterEach'
}, },
cleanupFn2 = { fn: jasmine.createSpy('cleanupFn2') },
queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn], queueableFns: [queueableFn, cleanupFn1, cleanupFn2],
cleanupFns: [cleanupFn1, cleanupFn2],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}); });
@@ -775,7 +755,7 @@ describe('QueueRunner', function() {
} }
}, },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') }, nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') }, cleanupFn = { fn: jasmine.createSpy('cleanup'), type: 'specCleanup' },
queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
globalErrors: { globalErrors: {
pushListener: function(f) { pushListener: function(f) {
@@ -785,8 +765,7 @@ describe('QueueRunner', function() {
errorListeners.pop(); errorListeners.pop();
} }
}, },
queueableFns: [queueableFn, nextQueueableFn], queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
cleanupFns: [cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}), }),
queueableFnDone; queueableFnDone;
@@ -806,10 +785,9 @@ describe('QueueRunner', function() {
} }
}, },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') }, nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') }, cleanupFn = { fn: jasmine.createSpy('cleanup'), type: 'specCleanup' },
queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn], queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
cleanupFns: [cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}); });
@@ -826,10 +804,12 @@ describe('QueueRunner', function() {
} }
}, },
nextQueueableFn = { fn: jasmine.createSpy('nextFunction') }, nextQueueableFn = { fn: jasmine.createSpy('nextFunction') },
cleanupFn = { fn: jasmine.createSpy('cleanup') }, cleanupFn = {
fn: jasmine.createSpy('cleanup'),
type: 'specCleanup'
},
queueRunner = new jasmineUnderTest.QueueRunner({ queueRunner = new jasmineUnderTest.QueueRunner({
queueableFns: [queueableFn, nextQueueableFn], queueableFns: [queueableFn, nextQueueableFn, cleanupFn],
cleanupFns: [cleanupFn],
SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy SkipPolicy: jasmineUnderTest.CompleteOnFirstErrorSkipPolicy
}); });

View File

@@ -116,9 +116,13 @@ describe('Spec', function() {
expect(options.queueableFns).toEqual([ expect(options.queueableFns).toEqual([
{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) },
before, before,
queueableFn queueableFn,
after,
{
fn: jasmine.any(Function),
type: 'specCleanup'
}
]); ]);
expect(options.cleanupFns).toEqual([after, { fn: jasmine.any(Function) }]);
}); });
it("tells the queue runner that it's a leaf node", function() { it("tells the queue runner that it's a leaf node", function() {
@@ -171,8 +175,13 @@ describe('Spec', function() {
expect(fakeQueueRunner).toHaveBeenCalledWith( expect(fakeQueueRunner).toHaveBeenCalledWith(
jasmine.objectContaining({ jasmine.objectContaining({
onComplete: jasmine.any(Function), onComplete: jasmine.any(Function),
queueableFns: [{ fn: jasmine.any(Function) }], queueableFns: [
cleanupFns: [{ fn: jasmine.any(Function) }] { fn: jasmine.any(Function) },
{
fn: jasmine.any(Function),
type: 'specCleanup'
}
]
}) })
); );
expect(specBody).not.toHaveBeenCalled(); expect(specBody).not.toHaveBeenCalled();
@@ -180,7 +189,7 @@ describe('Spec', function() {
var args = fakeQueueRunner.calls.mostRecent().args[0]; var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn(); args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled(); expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn(); args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback).toHaveBeenCalled(); expect(resultCallback).toHaveBeenCalled();
expect(spec.result.status).toBe('excluded'); expect(spec.result.status).toBe('excluded');
@@ -212,7 +221,7 @@ describe('Spec', function() {
var args = fakeQueueRunner.calls.mostRecent().args[0]; var args = fakeQueueRunner.calls.mostRecent().args[0];
args.queueableFns[0].fn(); args.queueableFns[0].fn();
expect(startCallback).toHaveBeenCalled(); expect(startCallback).toHaveBeenCalled();
args.cleanupFns[0].fn('things'); args.queueableFns[1].fn('things');
expect(resultCallback).toHaveBeenCalledWith( expect(resultCallback).toHaveBeenCalledWith(
{ {
id: spec.id, id: spec.id,
@@ -284,9 +293,6 @@ describe('Spec', function() {
config.queueableFns.forEach(function(qf) { config.queueableFns.forEach(function(qf) {
qf.fn(); qf.fn();
}); });
config.cleanupFns.forEach(function(qf) {
qf.fn();
});
config.onComplete(); config.onComplete();
}, },
timer: timer timer: timer
@@ -354,7 +360,9 @@ describe('Spec', function() {
spec.execute(); spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn(); const fns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
fns[fns.length - 1].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([ expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
'expectation1' 'expectation1'
]); ]);
@@ -383,7 +391,8 @@ describe('Spec', function() {
spec.execute(); spec.execute();
fakeQueueRunner.calls.mostRecent().args[0].cleanupFns[0].fn(); const fns = fakeQueueRunner.calls.mostRecent().args[0].queueableFns;
fns[fns.length - 1].fn();
expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([ expect(resultCallback.calls.first().args[0].passedExpectations).toEqual([
'passed' 'passed'
]); ]);
@@ -482,7 +491,7 @@ describe('Spec', function() {
spec.execute(); spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0]; var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn(); args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([ expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([
{ {
error: 'foo', error: 'foo',
@@ -510,7 +519,7 @@ describe('Spec', function() {
spec.execute(); spec.execute();
var args = fakeQueueRunner.calls.mostRecent().args[0]; var args = fakeQueueRunner.calls.mostRecent().args[0];
args.cleanupFns[0].fn(); args.queueableFns[args.queueableFns.length - 1].fn();
expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]); expect(resultCallback.calls.first().args[0].failedExpectations).toEqual([]);
}); });
@@ -575,9 +584,9 @@ describe('Spec', function() {
resultCallback: resultCallback, resultCallback: resultCallback,
queueRunnerFactory: function(config) { queueRunnerFactory: function(config) {
spec.trace('msg'); spec.trace('msg');
config.cleanupFns.forEach(function(fn) { for (const fn of config.queueableFns) {
fn.fn(); fn.fn();
}); }
config.onComplete(false); config.onComplete(false);
} }
}); });
@@ -598,9 +607,9 @@ describe('Spec', function() {
resultCallback: resultCallback, resultCallback: resultCallback,
queueRunnerFactory: function(config) { queueRunnerFactory: function(config) {
spec.trace('msg'); spec.trace('msg');
config.cleanupFns.forEach(function(fn) { for (const fn of config.queueableFns) {
fn.fn(); fn.fn();
}); }
config.onComplete(false); config.onComplete(false);
} }
}); });
@@ -623,9 +632,9 @@ describe('Spec', function() {
queueRunnerFactory: function(config) { queueRunnerFactory: function(config) {
spec.trace('msg'); spec.trace('msg');
spec.onException(new Error('nope')); spec.onException(new Error('nope'));
config.cleanupFns.forEach(function(fn) { for (const fn of config.queueableFns) {
fn.fn(); fn.fn();
}); }
config.onComplete(true); config.onComplete(true);
}, },
timer: timer timer: timer

View File

@@ -43,7 +43,7 @@ describe('Suite', function() {
expect(suite.getFullName()).toEqual('I am a parent suite 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() { it('adds beforeEach functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({ var suite = new jasmineUnderTest.Suite({
env: env, env: env,
description: 'I am a suite' description: 'I am a suite'
@@ -60,7 +60,24 @@ describe('Suite', function() {
]); ]);
}); });
it('adds after functions in order of needed execution', function() { it('adds beforeAll functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerBefore = { fn: 'outerBeforeAll' },
innerBefore = { fn: 'insideBeforeAll' };
suite.beforeAll(outerBefore);
suite.beforeAll(innerBefore);
expect(suite.beforeAllFns).toEqual([
{ fn: outerBefore.fn, type: 'beforeAll' },
{ fn: innerBefore.fn, type: 'beforeAll' }
]);
});
it('adds afterEach functions in order of needed execution', function() {
var suite = new jasmineUnderTest.Suite({ var suite = new jasmineUnderTest.Suite({
env: env, env: env,
description: 'I am a suite' description: 'I am a suite'
@@ -72,8 +89,25 @@ describe('Suite', function() {
suite.afterEach(innerAfter); suite.afterEach(innerAfter);
expect(suite.afterFns).toEqual([ expect(suite.afterFns).toEqual([
{ fn: innerAfter.fn, suite }, { fn: innerAfter.fn, suite, type: 'afterEach' },
{ fn: outerAfter.fn, suite } { fn: outerAfter.fn, suite, type: 'afterEach' }
]);
});
it('adds afterAll functions in order of needed execution', function() {
const suite = new jasmineUnderTest.Suite({
env: env,
description: 'I am a suite'
}),
outerAfter = { fn: 'outerAfterAll' },
innerAfter = { fn: 'insideAfterAl' };
suite.afterAll(outerAfter);
suite.afterAll(innerAfter);
expect(suite.afterAllFns).toEqual([
{ fn: innerAfter.fn, type: 'afterAll' },
{ fn: outerAfter.fn, type: 'afterAll' }
]); ]);
}); });

View File

@@ -505,27 +505,28 @@ describe('TreeProcessor', function() {
expect(queueableFns).toEqual([ expect(queueableFns).toEqual([
{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) },
{ type: 'beforeAll', fn: 'beforeAll1', timeout: 1 }, { fn: 'beforeAll1', timeout: 1 },
{ type: 'beforeAll', fn: 'beforeAll2', timeout: 2 }, { fn: 'beforeAll2', timeout: 2 },
{ fn: jasmine.any(Function) } { fn: jasmine.any(Function) }
]); ]);
}); });
it('runs afterAlls for a node with children', function() { it('runs afterAlls for a node with children', function() {
var leaf = new Leaf(), var leaf = new Leaf(),
node = new Node({ afterAllFns = [{ fn: 'afterAll1' }, { fn: 'afterAll2' }];
children: [leaf], (node = new Node({
afterAllFns: [{ fn: 'afterAll1' }, { fn: 'afterAll2' }] children: [leaf],
}), afterAllFns
root = new Node({ children: [node] }), })),
queueRunner = jasmine.createSpy('queueRunner'), (root = new Node({ children: [node] })),
processor = new jasmineUnderTest.TreeProcessor({ (queueRunner = jasmine.createSpy('queueRunner')),
(processor = new jasmineUnderTest.TreeProcessor({
tree: root, tree: root,
runnableIds: [node.id], runnableIds: [node.id],
queueRunnerFactory: queueRunner queueRunnerFactory: queueRunner
}), })),
treeComplete = jasmine.createSpy('treeComplete'), (treeComplete = jasmine.createSpy('treeComplete')),
nodeDone = jasmine.createSpy('nodeDone'); (nodeDone = jasmine.createSpy('nodeDone'));
processor.execute(treeComplete); processor.execute(treeComplete);
var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns; var queueableFns = queueRunner.calls.mostRecent().args[0].queueableFns;
@@ -536,8 +537,8 @@ describe('TreeProcessor', function() {
expect(queueableFns).toEqual([ expect(queueableFns).toEqual([
{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) },
{ fn: jasmine.any(Function) }, { fn: jasmine.any(Function) },
{ type: 'afterAll', fn: 'afterAll1' }, afterAllFns[0],
{ type: 'afterAll', fn: 'afterAll2' } afterAllFns[1]
]); ]);
}); });

View File

@@ -1,7 +1,6 @@
getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) { getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
function CompleteOnFirstErrorSkipPolicy(queueableFns, firstCleanupIx) { function CompleteOnFirstErrorSkipPolicy(queueableFns) {
this.queueableFns_ = queueableFns; this.queueableFns_ = queueableFns;
this.firstCleanupIx_ = firstCleanupIx;
this.erroredFnIx_ = null; this.erroredFnIx_ = null;
} }
@@ -23,16 +22,15 @@ getJasmineRequireObj().CompleteOnFirstErrorSkipPolicy = function(j$) {
return false; return false;
} }
// firstCleanupIx_ isn't correct for suites with afterAll functions. const fn = this.queueableFns_[fnIx];
// Rely on the type for those. const candidateSuite = fn.suite;
if (this.queueableFns_[fnIx].type === 'afterAll') {
return false;
}
const candidateSuite = this.queueableFns_[fnIx].suite;
const errorSuite = this.queueableFns_[this.erroredFnIx_].suite; const errorSuite = this.queueableFns_[this.erroredFnIx_].suite;
const wasCleanupFn =
fn.type === 'afterEach' ||
fn.type === 'afterAll' ||
fn.type === 'specCleanup';
return ( return (
fnIx < this.firstCleanupIx_ || !wasCleanupFn ||
(candidateSuite && isDescendent(candidateSuite, errorSuite)) (candidateSuite && isDescendent(candidateSuite, errorSuite))
); );
}; };

View File

@@ -1,5 +1,5 @@
getJasmineRequireObj().NeverSkipPolicy = function(j$) { getJasmineRequireObj().NeverSkipPolicy = function(j$) {
function NeverSkipPolicy(queueableFns, firstCleanupIx) {} function NeverSkipPolicy(queueableFns) {}
NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx) { NeverSkipPolicy.prototype.skipTo = function(lastRanFnIx) {
return lastRanFnIx + 1; return lastRanFnIx + 1;

View File

@@ -35,9 +35,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
function QueueRunner(attrs) { function QueueRunner(attrs) {
this.id_ = nextid++; this.id_ = nextid++;
var queueableFns = attrs.queueableFns || []; this.queueableFns = attrs.queueableFns || [];
this.queueableFns = queueableFns.concat(attrs.cleanupFns || []);
this.firstCleanupIx = queueableFns.length;
this.onComplete = attrs.onComplete || emptyFn; this.onComplete = attrs.onComplete || emptyFn;
this.clearStack = this.clearStack =
attrs.clearStack || attrs.clearStack ||
@@ -58,7 +56,7 @@ getJasmineRequireObj().QueueRunner = function(j$) {
}; };
const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy; const SkipPolicy = attrs.SkipPolicy || j$.NeverSkipPolicy;
this.skipPolicy_ = new SkipPolicy(this.queueableFns, this.firstCleanupIx); this.skipPolicy_ = new SkipPolicy(this.queueableFns);
this.errored_ = false; this.errored_ = false;
if (typeof this.onComplete !== 'function') { if (typeof this.onComplete !== 'function') {

View File

@@ -1,5 +1,5 @@
getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) { getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {
function SkipAfterBeforeAllErrorPolicy(queueableFns, firstCleanupIx) { function SkipAfterBeforeAllErrorPolicy(queueableFns) {
this.queueableFns_ = queueableFns; this.queueableFns_ = queueableFns;
this.skipping_ = false; this.skipping_ = false;
} }

View File

@@ -137,16 +137,15 @@ getJasmineRequireObj().Spec = function(j$) {
} }
self.resultCallback(self.result, done); self.resultCallback(self.result, done);
} },
type: 'specCleanup'
}; };
var fns = this.beforeAndAfterFns(); var fns = this.beforeAndAfterFns();
var regularFns = fns.befores.concat(this.queueableFn);
var runnerConfig = { var runnerConfig = {
isLeaf: true, isLeaf: true,
queueableFns: regularFns, queueableFns: [...fns.befores, this.queueableFn, ...fns.afters],
cleanupFns: fns.afters,
onException: function() { onException: function() {
self.onException.apply(self, arguments); self.onException.apply(self, arguments);
}, },
@@ -176,11 +175,10 @@ getJasmineRequireObj().Spec = function(j$) {
if (this.markedPending || excluded === true) { if (this.markedPending || excluded === true) {
runnerConfig.queueableFns = []; runnerConfig.queueableFns = [];
runnerConfig.cleanupFns = [];
} }
runnerConfig.queueableFns.unshift(onStart); runnerConfig.queueableFns.unshift(onStart);
runnerConfig.cleanupFns.push(complete); runnerConfig.queueableFns.push(complete);
this.queueRunnerFactory(runnerConfig); this.queueRunnerFactory(runnerConfig);
}; };

View File

@@ -103,15 +103,15 @@ getJasmineRequireObj().Suite = function(j$) {
}; };
Suite.prototype.beforeAll = function(fn) { Suite.prototype.beforeAll = function(fn) {
this.beforeAllFns.push(fn); this.beforeAllFns.push({ ...fn, type: 'beforeAll' });
}; };
Suite.prototype.afterEach = function(fn) { Suite.prototype.afterEach = function(fn) {
this.afterFns.unshift({ ...fn, suite: this }); this.afterFns.unshift({ ...fn, suite: this, type: 'afterEach' });
}; };
Suite.prototype.afterAll = function(fn) { Suite.prototype.afterAll = function(fn) {
this.afterAllFns.unshift(fn); this.afterAllFns.unshift({ ...fn, type: 'afterAll' });
}; };
Suite.prototype.startTimer = function() { Suite.prototype.startTimer = function() {

View File

@@ -253,16 +253,7 @@ getJasmineRequireObj().TreeProcessor = function() {
return result; return result;
} }
return node.beforeAllFns return node.beforeAllFns.concat(result).concat(node.afterAllFns);
.map(function(fn) {
return { type: 'beforeAll', ...fn };
})
.concat(result)
.concat(
node.afterAllFns.map(function(fn) {
return { type: 'afterAll', ...fn };
})
);
} }
} }