Parallel: forbid beforeAll/afterAll at the top level

Either running these once total or running them once per process
would be the wrong choice for a significant chunk of users, so do
neither. Later we'll add a new API for exactly-once setup and teardown
in parallel mode.
This commit is contained in:
Steve Gravrock
2022-10-11 19:43:25 -07:00
parent 89e0b35c53
commit e14d9c4be3
3 changed files with 107 additions and 8 deletions

View File

@@ -1188,7 +1188,7 @@ getJasmineRequireObj().Env = function(j$) {
let reporter;
let topSuite;
let runner;
let parallelLodingState = null; // 'specs', 'helpers', or null for non-parallel
let parallelLoadingState = null; // 'specs', 'helpers', or null for non-parallel
/**
* This represents the available options to configure Jasmine.
@@ -1636,7 +1636,7 @@ getJasmineRequireObj().Env = function(j$) {
});
this.setParallelLoadingState = function(state) {
parallelLodingState = state;
parallelLoadingState = state;
};
this.parallelReset = function() {
@@ -1807,13 +1807,21 @@ getJasmineRequireObj().Env = function(j$) {
}
function ensureNonParallel(method) {
if (parallelLodingState) {
if (parallelLoadingState) {
throw new Error(`'${method}' is not available in parallel mode`);
}
}
function ensureNonParallelOrInDescribe(method) {
if (parallelLoadingState && !suiteBuilder.inDescribe()) {
throw new Error(
`In parallel mode, '${method}' must be in a describe block`
);
}
}
function ensureNonParallelOrInHelperOrInDescribe(method) {
if (parallelLodingState === 'specs' && !suiteBuilder.inDescribe()) {
if (parallelLoadingState === 'specs' && !suiteBuilder.inDescribe()) {
throw new Error(
'In parallel mode, ' +
method +
@@ -1951,6 +1959,7 @@ getJasmineRequireObj().Env = function(j$) {
this.beforeAll = function(beforeAllFunction, timeout) {
ensureIsNotNested('beforeAll');
ensureNonParallelOrInDescribe('beforeAll');
suiteBuilder.beforeAll(beforeAllFunction, timeout);
};
@@ -1962,6 +1971,7 @@ getJasmineRequireObj().Env = function(j$) {
this.afterAll = function(afterAllFunction, timeout) {
ensureIsNotNested('afterAll');
ensureNonParallelOrInDescribe('afterAll');
suiteBuilder.afterAll(afterAllFunction, timeout);
};

View File

@@ -1,5 +1,6 @@
// TODO: Fix these unit tests!
describe('Env', function() {
beforeAll(function() {});
let env;
beforeEach(function() {
env = new jasmineUnderTest.Env();
@@ -454,6 +455,45 @@ describe('Env', function() {
env.beforeAll(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
describe('in parallel mode', function() {
it('throws an error when called at the top level', function() {
env.setParallelLoadingState('helpers');
check();
env.setParallelLoadingState('specs');
check();
function check() {
expect(function() {
env.beforeAll(function() {});
}).toThrowError(
"In parallel mode, 'beforeAll' must be in a describe block"
);
}
});
it('does not throw an error when called in a describe', function() {
env.setParallelLoadingState('helpers');
check();
env.setParallelLoadingState('specs');
check();
function check() {
let done = false;
env.describe('a suite', function() {
expect(function() {
env.it('a spec');
env.beforeAll(function() {});
}).not.toThrow();
done = true;
});
expect(done).toBeTrue();
}
});
});
});
describe('#afterEach', function() {
@@ -520,6 +560,45 @@ describe('Env', function() {
env.afterAll(function() {}, 2147483648);
}).toThrowError('Timeout value cannot be greater than 2147483647');
});
describe('in parallel mode', function() {
it('throws an error when called at the top level', function() {
env.setParallelLoadingState('helpers');
check();
env.setParallelLoadingState('specs');
check();
function check() {
expect(function() {
env.afterAll(function() {});
}).toThrowError(
"In parallel mode, 'afterAll' must be in a describe block"
);
}
});
it('does not throw an error when called in a describe', function() {
env.setParallelLoadingState('helpers');
check();
env.setParallelLoadingState('specs');
check();
function check() {
let done = false;
env.describe('a suite', function() {
expect(function() {
env.it('a spec');
env.afterAll(function() {});
}).not.toThrow();
done = true;
});
expect(done).toBeTrue();
}
});
});
});
describe('when not constructed with suppressLoadErrors: true', function() {

View File

@@ -46,7 +46,7 @@ getJasmineRequireObj().Env = function(j$) {
let reporter;
let topSuite;
let runner;
let parallelLodingState = null; // 'specs', 'helpers', or null for non-parallel
let parallelLoadingState = null; // 'specs', 'helpers', or null for non-parallel
/**
* This represents the available options to configure Jasmine.
@@ -494,7 +494,7 @@ getJasmineRequireObj().Env = function(j$) {
});
this.setParallelLoadingState = function(state) {
parallelLodingState = state;
parallelLoadingState = state;
};
this.parallelReset = function() {
@@ -665,13 +665,21 @@ getJasmineRequireObj().Env = function(j$) {
}
function ensureNonParallel(method) {
if (parallelLodingState) {
if (parallelLoadingState) {
throw new Error(`'${method}' is not available in parallel mode`);
}
}
function ensureNonParallelOrInDescribe(method) {
if (parallelLoadingState && !suiteBuilder.inDescribe()) {
throw new Error(
`In parallel mode, '${method}' must be in a describe block`
);
}
}
function ensureNonParallelOrInHelperOrInDescribe(method) {
if (parallelLodingState === 'specs' && !suiteBuilder.inDescribe()) {
if (parallelLoadingState === 'specs' && !suiteBuilder.inDescribe()) {
throw new Error(
'In parallel mode, ' +
method +
@@ -809,6 +817,7 @@ getJasmineRequireObj().Env = function(j$) {
this.beforeAll = function(beforeAllFunction, timeout) {
ensureIsNotNested('beforeAll');
ensureNonParallelOrInDescribe('beforeAll');
suiteBuilder.beforeAll(beforeAllFunction, timeout);
};
@@ -820,6 +829,7 @@ getJasmineRequireObj().Env = function(j$) {
this.afterAll = function(afterAllFunction, timeout) {
ensureIsNotNested('afterAll');
ensureNonParallelOrInDescribe('afterAll');
suiteBuilder.afterAll(afterAllFunction, timeout);
};