277 lines
8.7 KiB
JavaScript
277 lines
8.7 KiB
JavaScript
describe('Runner', function() {
|
|
describe('TreeProcessor nodeComplete callback', function() {
|
|
it('throws if the wrong suite is passed to nodeComplete', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {}
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
|
|
expect(function() {
|
|
const someOtherSuite = {};
|
|
treeProcessorOpts.nodeComplete(someOtherSuite, {}, () => {});
|
|
}).toThrowError('Tried to complete the wrong suite');
|
|
});
|
|
|
|
it("ends the suite's timer", async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [suiteToRun, {}]);
|
|
|
|
expect(suiteToRun.endTimer).toHaveBeenCalled();
|
|
});
|
|
|
|
it('sets hasFailures to true when the suite fails', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [
|
|
suiteToRun,
|
|
{ status: 'failed' }
|
|
]);
|
|
|
|
expect(subject.hasFailures).toBe(true);
|
|
});
|
|
|
|
it('does not set hasFailures to true when the suite passes', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [
|
|
suiteToRun,
|
|
{ status: 'passed' }
|
|
]);
|
|
|
|
expect(subject.hasFailures).toBe(false);
|
|
});
|
|
|
|
it('does not set hasFailures to false when the suite passes', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
subject.hasFailures = true;
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [
|
|
suiteToRun,
|
|
{ status: 'passed' }
|
|
]);
|
|
|
|
expect(subject.hasFailures).toBe(true);
|
|
});
|
|
|
|
describe('reporting', function() {
|
|
it('reports the suiteDone event', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const reportDispatcher = spyReporter();
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor,
|
|
reportDispatcher
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [
|
|
suiteToRun,
|
|
{ status: 'passed' }
|
|
]);
|
|
|
|
expect(reportDispatcher.suiteDone).toHaveBeenCalled();
|
|
});
|
|
|
|
describe('when the suite had a beforeAll failure', function() {
|
|
it('reports children before the suiteDone event', async function() {
|
|
const TreeProcessor = spyTreeProcessorCtor();
|
|
const reportDispatcher = spyReporter();
|
|
const reportSpecDone = jasmine
|
|
.createSpy('reportSpecDone')
|
|
.and.callFake(function(child, result, next) {
|
|
next();
|
|
});
|
|
const subject = new jasmineUnderTest.Runner({
|
|
...defaultCtorOptions(),
|
|
TreeProcessor,
|
|
reportDispatcher,
|
|
reportSpecDone
|
|
});
|
|
|
|
const promise = subject.execute();
|
|
expect(TreeProcessor).toHaveBeenCalled();
|
|
await checkImmediateRejection(promise);
|
|
|
|
const treeProcessorOpts = TreeProcessor.calls.argsFor(0)[0];
|
|
const suiteToRun = {
|
|
parentSuite: stubSuite(),
|
|
children: [
|
|
{
|
|
result: { description: 'a spec' },
|
|
addExpectationResult: jasmine.createSpy('addExpectationResult')
|
|
}
|
|
],
|
|
startTimer: () => {},
|
|
endTimer: jasmine.createSpy('suiteToRun.endTimer')
|
|
};
|
|
await callWithNext(treeProcessorOpts.nodeStart, [suiteToRun]);
|
|
|
|
suiteToRun.hadBeforeAllFailure = true;
|
|
await callWithNext(treeProcessorOpts.nodeComplete, [
|
|
suiteToRun,
|
|
{ status: 'passed' }
|
|
]);
|
|
|
|
expect(
|
|
suiteToRun.children[0].addExpectationResult
|
|
).toHaveBeenCalledWith(
|
|
false,
|
|
{
|
|
passed: false,
|
|
message:
|
|
'Not run because a beforeAll function failed. The beforeAll failure will be reported on the suite that caused it.'
|
|
},
|
|
true
|
|
);
|
|
expect(
|
|
suiteToRun.children[0].addExpectationResult
|
|
).toHaveBeenCalledBefore(reportSpecDone);
|
|
expect(reportSpecDone).toHaveBeenCalledBefore(
|
|
reportDispatcher.suiteDone
|
|
);
|
|
expect(reportDispatcher.specStarted).toHaveBeenCalledBefore(
|
|
reportSpecDone
|
|
);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
async function callWithNext(fn, args) {
|
|
let next;
|
|
const nextPromise = new Promise(function(resolve) {
|
|
next = resolve;
|
|
});
|
|
fn.apply(null, [...args, next]);
|
|
await nextPromise;
|
|
}
|
|
|
|
// Check whether promise has already been rejected
|
|
async function checkImmediateRejection(promise) {
|
|
await Promise.race([promise, Promise.resolve()]);
|
|
}
|
|
|
|
function spyTreeProcessorCtor() {
|
|
return jasmine.createSpy('TreeProcessor ctor').and.returnValue({
|
|
execute: () => {},
|
|
processTree: () => ({ valid: true })
|
|
});
|
|
}
|
|
|
|
function spyReporter() {
|
|
return jasmine.createSpyObj('reportDispatcher', {
|
|
jasmineStarted: Promise.resolve(),
|
|
jasmineDone: Promise.resolve(),
|
|
suiteStarted: Promise.resolve(),
|
|
suiteDone: Promise.resolve(),
|
|
specStarted: Promise.resolve(),
|
|
specDone: Promise.resolve()
|
|
});
|
|
}
|
|
|
|
function defaultCtorOptions() {
|
|
return {
|
|
topSuite: stubSuite(),
|
|
runableResources: {
|
|
initForRunable: () => {},
|
|
clearForRunable: () => {}
|
|
},
|
|
reportDispatcher: spyReporter(),
|
|
focusedRunables: () => [],
|
|
getConfig: () => ({}),
|
|
totalSpecsDefined: () => 1
|
|
};
|
|
}
|
|
|
|
function stubSuite() {
|
|
return {
|
|
result: {
|
|
failedExpectations: []
|
|
}
|
|
};
|
|
}
|
|
});
|