Extracted runnable resource management out of Env
This commit is contained in:
@@ -90,6 +90,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$
|
||||
);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.RunnableResources = jRequire.RunnableResources(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.Spy = jRequire.Spy(j$);
|
||||
j$.SpyFactory = jRequire.SpyFactory(j$);
|
||||
@@ -1112,7 +1113,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
new j$.MockDate(global)
|
||||
);
|
||||
|
||||
const runnableResources = {};
|
||||
const runnableResources = new j$.RunnableResources(function() {
|
||||
const r = currentRunnable();
|
||||
return r ? r.id : null;
|
||||
});
|
||||
|
||||
let topSuite;
|
||||
let currentSpec = null;
|
||||
@@ -1122,7 +1126,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
let hasFailures = false;
|
||||
let deprecator;
|
||||
let reporter;
|
||||
let spyRegistry;
|
||||
|
||||
/**
|
||||
* This represents the available options to configure Jasmine.
|
||||
@@ -1316,74 +1319,27 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.setDefaultSpyStrategy = function(defaultStrategyFn) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Default spy strategy must be set in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[
|
||||
currentRunnable().id
|
||||
].defaultStrategyFn = defaultStrategyFn;
|
||||
runnableResources.setDefaultSpyStrategy(defaultStrategyFn);
|
||||
};
|
||||
|
||||
this.addSpyStrategy = function(name, fn) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom spy strategies must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[currentRunnable().id].customSpyStrategies[name] = fn;
|
||||
runnableResources.customSpyStrategies()[name] = fn;
|
||||
};
|
||||
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom Equalities must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(
|
||||
tester
|
||||
);
|
||||
runnableResources.customEqualityTesters().push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Matchers must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
const customMatchers =
|
||||
runnableResources[currentRunnable().id].customMatchers;
|
||||
|
||||
for (const matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
runnableResources.addCustomMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.addAsyncMatchers = function(matchersToAdd) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Async Matchers must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
const customAsyncMatchers =
|
||||
runnableResources[currentRunnable().id].customAsyncMatchers;
|
||||
|
||||
for (const matcherName in matchersToAdd) {
|
||||
customAsyncMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
runnableResources.addCustomAsyncMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.addCustomObjectFormatter = function(formatter) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom object formatters must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
|
||||
runnableResources[currentRunnable().id].customObjectFormatters.push(
|
||||
formatter
|
||||
);
|
||||
runnableResources.customObjectFormatters().push(formatter);
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
@@ -1401,31 +1357,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return 'suite' + nextSuiteId++;
|
||||
}
|
||||
|
||||
function makePrettyPrinter() {
|
||||
const customObjectFormatters =
|
||||
runnableResources[currentRunnable().id].customObjectFormatters;
|
||||
return j$.makePrettyPrinter(customObjectFormatters);
|
||||
}
|
||||
|
||||
function makeMatchersUtil() {
|
||||
const cr = currentRunnable();
|
||||
|
||||
if (cr) {
|
||||
const customEqualityTesters =
|
||||
runnableResources[cr.id].customEqualityTesters;
|
||||
return new j$.MatchersUtil({
|
||||
customTesters: customEqualityTesters,
|
||||
pp: makePrettyPrinter()
|
||||
});
|
||||
} else {
|
||||
return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
|
||||
}
|
||||
}
|
||||
|
||||
const expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.factory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
matchersUtil: runnableResources.makeMatchersUtil(),
|
||||
customMatchers: runnableResources.customMatchers(),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -1502,8 +1437,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
const asyncExpectationFactory = function(actual, spec, runableType) {
|
||||
return j$.Expectation.asyncFactory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,
|
||||
matchersUtil: runnableResources.makeMatchersUtil(),
|
||||
customAsyncMatchers: runnableResources.customAsyncMatchers(),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -1523,45 +1458,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return asyncExpectationFactory(actual, suite, 'Spec');
|
||||
};
|
||||
|
||||
function defaultResourcesForRunnable(id, parentRunnableId) {
|
||||
const resources = {
|
||||
spies: [],
|
||||
customEqualityTesters: [],
|
||||
customMatchers: {},
|
||||
customAsyncMatchers: {},
|
||||
customSpyStrategies: {},
|
||||
defaultStrategyFn: undefined,
|
||||
customObjectFormatters: []
|
||||
};
|
||||
|
||||
if (runnableResources[parentRunnableId]) {
|
||||
resources.customEqualityTesters = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customEqualityTesters
|
||||
);
|
||||
resources.customMatchers = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customMatchers
|
||||
);
|
||||
resources.customAsyncMatchers = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customAsyncMatchers
|
||||
);
|
||||
resources.customObjectFormatters = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customObjectFormatters
|
||||
);
|
||||
resources.customSpyStrategies = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customSpyStrategies
|
||||
);
|
||||
resources.defaultStrategyFn =
|
||||
runnableResources[parentRunnableId].defaultStrategyFn;
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
}
|
||||
|
||||
function clearResourcesForRunnable(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
}
|
||||
|
||||
function beforeAndAfterFns(targetSuite) {
|
||||
return function() {
|
||||
let befores = [],
|
||||
@@ -1787,7 +1683,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
topSuite.reset();
|
||||
}
|
||||
this._executedBefore = true;
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
runnableResources.initForRunnable(topSuite.id);
|
||||
installGlobalErrors();
|
||||
|
||||
if (!runnablesToRun) {
|
||||
@@ -1810,7 +1706,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
failSpecWithNoExpectations: config.failSpecWithNoExpectations,
|
||||
nodeStart: function(suite, next) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
runnableResources.initForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result, next);
|
||||
suite.startTimer();
|
||||
},
|
||||
@@ -1819,7 +1715,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
throw new Error('Tried to complete the wrong suite');
|
||||
}
|
||||
|
||||
clearResourcesForRunnable(suite.id);
|
||||
runnableResources.clearForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
|
||||
if (result.status === 'failed') {
|
||||
@@ -1884,7 +1780,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
await reportChildrenOfBeforeAllFailure(topSuite);
|
||||
}
|
||||
|
||||
clearResourcesForRunnable(topSuite.id);
|
||||
runnableResources.clearForRunnable(topSuite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
let overallStatus, incompleteReason;
|
||||
|
||||
@@ -2008,42 +1904,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
reporter.clearReporters();
|
||||
};
|
||||
|
||||
const spyFactory = new j$.SpyFactory(
|
||||
function getCustomStrategies() {
|
||||
const runnable = currentRunnable();
|
||||
|
||||
if (runnable) {
|
||||
return runnableResources[runnable.id].customSpyStrategies;
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
function getDefaultStrategyFn() {
|
||||
const runnable = currentRunnable();
|
||||
|
||||
if (runnable) {
|
||||
return runnableResources[runnable.id].defaultStrategyFn;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
makeMatchersUtil
|
||||
);
|
||||
|
||||
spyRegistry = new j$.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Spies must be created in a before function or a spec'
|
||||
);
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
},
|
||||
createSpy: function(name, originalFn) {
|
||||
return self.createSpy(name, originalFn);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Configures whether Jasmine should allow the same function to be spied on
|
||||
* more than once during the execution of a spec. By default, spying on
|
||||
@@ -2054,32 +1914,40 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @param {boolean} allow Whether to allow respying
|
||||
*/
|
||||
this.allowRespy = function(allow) {
|
||||
spyRegistry.allowRespy(allow);
|
||||
runnableResources.spyRegistry.allowRespy(allow);
|
||||
};
|
||||
|
||||
this.spyOn = function() {
|
||||
return spyRegistry.spyOn.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOn.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.spyOnProperty = function() {
|
||||
return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOnProperty.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.spyOnAllFunctions = function() {
|
||||
return spyRegistry.spyOnAllFunctions.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOnAllFunctions.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.createSpy = function(name, originalFn) {
|
||||
if (arguments.length === 1 && j$.isFunction_(name)) {
|
||||
originalFn = name;
|
||||
name = originalFn.name;
|
||||
}
|
||||
|
||||
return spyFactory.createSpy(name, originalFn);
|
||||
return runnableResources.spyFactory.createSpy(name, originalFn);
|
||||
};
|
||||
|
||||
this.createSpyObj = function(baseName, methodNames, propertyNames) {
|
||||
return spyFactory.createSpyObj(baseName, methodNames, propertyNames);
|
||||
return runnableResources.spyFactory.createSpyObj(
|
||||
baseName,
|
||||
methodNames,
|
||||
propertyNames
|
||||
);
|
||||
};
|
||||
|
||||
function ensureIsFunction(fn, caller) {
|
||||
@@ -2234,7 +2102,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result, next) {
|
||||
clearResourcesForRunnable(spec.id);
|
||||
runnableResources.clearForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
|
||||
if (result.status === 'failed') {
|
||||
@@ -2246,7 +2114,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
function specStarted(spec, next) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
runnableResources.initForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result, next);
|
||||
}
|
||||
};
|
||||
@@ -2468,7 +2336,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
message += error;
|
||||
} else {
|
||||
// pretty print all kind of objects. This includes arrays.
|
||||
message += makePrettyPrinter()(error);
|
||||
const pp = runnableResources.makePrettyPrinter();
|
||||
message += pp(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8664,6 +8533,161 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
return jasmineInterface;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().RunnableResources = function(j$) {
|
||||
class RunnableResources {
|
||||
constructor(getCurrentRunnableId) {
|
||||
this.byRunnableId_ = {};
|
||||
this.getCurrentRunnableId_ = getCurrentRunnableId;
|
||||
|
||||
this.spyFactory = new j$.SpyFactory(
|
||||
() => {
|
||||
if (this.getCurrentRunnableId_()) {
|
||||
return this.customSpyStrategies();
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
() => this.defaultSpyStrategy(),
|
||||
() => this.makeMatchersUtil()
|
||||
);
|
||||
|
||||
this.spyRegistry = new j$.SpyRegistry({
|
||||
currentSpies: () => this.spies(),
|
||||
createSpy: (name, originalFn) =>
|
||||
this.spyFactory.createSpy(name, originalFn)
|
||||
});
|
||||
}
|
||||
|
||||
initForRunnable(runnableId, parentId) {
|
||||
const newRes = (this.byRunnableId_[runnableId] = {
|
||||
customEqualityTesters: [],
|
||||
customMatchers: {},
|
||||
customAsyncMatchers: {},
|
||||
customSpyStrategies: {},
|
||||
customObjectFormatters: [],
|
||||
defaultSpyStrategy: undefined,
|
||||
spies: []
|
||||
});
|
||||
|
||||
const parentRes = this.byRunnableId_[parentId];
|
||||
|
||||
if (parentRes) {
|
||||
newRes.defaultSpyStrategy = parentRes.defaultSpyStrategy;
|
||||
const toClone = [
|
||||
'customEqualityTesters',
|
||||
'customMatchers',
|
||||
'customAsyncMatchers',
|
||||
'customObjectFormatters',
|
||||
'customSpyStrategies'
|
||||
];
|
||||
|
||||
for (const k of toClone) {
|
||||
newRes[k] = j$.util.clone(parentRes[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearForRunnable(runnableId) {
|
||||
this.spyRegistry.clearSpies();
|
||||
delete this.byRunnableId_[runnableId];
|
||||
}
|
||||
|
||||
spies() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Spies must be created in a before function or a spec'
|
||||
).spies;
|
||||
}
|
||||
|
||||
defaultSpyStrategy() {
|
||||
if (!this.getCurrentRunnableId_()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.byRunnableId_[this.getCurrentRunnableId_()]
|
||||
.defaultSpyStrategy;
|
||||
}
|
||||
|
||||
setDefaultSpyStrategy(fn) {
|
||||
this.forCurrentRunnable_(
|
||||
'Default spy strategy must be set in a before function or a spec'
|
||||
).defaultSpyStrategy = fn;
|
||||
}
|
||||
|
||||
customSpyStrategies() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom spy strategies must be added in a before function or a spec'
|
||||
).customSpyStrategies;
|
||||
}
|
||||
|
||||
customEqualityTesters() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom Equalities must be added in a before function or a spec'
|
||||
).customEqualityTesters;
|
||||
}
|
||||
|
||||
customMatchers() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Matchers must be added in a before function or a spec'
|
||||
).customMatchers;
|
||||
}
|
||||
|
||||
addCustomMatchers(matchersToAdd) {
|
||||
const matchers = this.customMatchers();
|
||||
|
||||
for (const name in matchersToAdd) {
|
||||
matchers[name] = matchersToAdd[name];
|
||||
}
|
||||
}
|
||||
|
||||
customAsyncMatchers() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Async Matchers must be added in a before function or a spec'
|
||||
).customAsyncMatchers;
|
||||
}
|
||||
|
||||
addCustomAsyncMatchers(matchersToAdd) {
|
||||
const matchers = this.customAsyncMatchers();
|
||||
|
||||
for (const name in matchersToAdd) {
|
||||
matchers[name] = matchersToAdd[name];
|
||||
}
|
||||
}
|
||||
|
||||
customObjectFormatters() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom object formatters must be added in a before function or a spec'
|
||||
).customObjectFormatters;
|
||||
}
|
||||
|
||||
makePrettyPrinter() {
|
||||
return j$.makePrettyPrinter(this.customObjectFormatters());
|
||||
}
|
||||
|
||||
makeMatchersUtil() {
|
||||
if (this.getCurrentRunnableId_()) {
|
||||
return new j$.MatchersUtil({
|
||||
customTesters: this.customEqualityTesters(),
|
||||
pp: this.makePrettyPrinter()
|
||||
});
|
||||
} else {
|
||||
return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
|
||||
}
|
||||
}
|
||||
|
||||
forCurrentRunnable_(errorMsg) {
|
||||
const resources = this.byRunnableId_[this.getCurrentRunnableId_()];
|
||||
|
||||
if (!resources && errorMsg) {
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
return RunnableResources;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().SkipAfterBeforeAllErrorPolicy = function(j$) {
|
||||
function SkipAfterBeforeAllErrorPolicy(queueableFns) {
|
||||
this.queueableFns_ = queueableFns;
|
||||
@@ -8923,6 +8947,11 @@ getJasmineRequireObj().SpyFactory = function(j$) {
|
||||
getMatchersUtil
|
||||
) {
|
||||
this.createSpy = function(name, originalFn) {
|
||||
if (j$.isFunction_(name) && originalFn === undefined) {
|
||||
originalFn = name;
|
||||
name = originalFn.name;
|
||||
}
|
||||
|
||||
return j$.Spy(name, getMatchersUtil(), {
|
||||
originalFn,
|
||||
customStrategies: getCustomStrategies(),
|
||||
|
||||
503
spec/core/RunnableResourcesSpec.js
Normal file
503
spec/core/RunnableResourcesSpec.js
Normal file
@@ -0,0 +1,503 @@
|
||||
describe('RunnableResources', function() {
|
||||
describe('#spies', function() {
|
||||
behavesLikeAPerRunnableMutableArray(
|
||||
'spies',
|
||||
'Spies must be created in a before function or a spec',
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
describe('#customSpyStrategies', function() {
|
||||
behavesLikeAPerRunnableMutableObject(
|
||||
'customSpyStrategies',
|
||||
'Custom spy strategies must be added in a before function or a spec'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#customEqualityTesters', function() {
|
||||
behavesLikeAPerRunnableMutableArray(
|
||||
'customEqualityTesters',
|
||||
'Custom Equalities must be added in a before function or a spec'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#customObjectFormatters', function() {
|
||||
behavesLikeAPerRunnableMutableArray(
|
||||
'customObjectFormatters',
|
||||
'Custom object formatters must be added in a before function or a spec'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#customMatchers', function() {
|
||||
behavesLikeAPerRunnableMutableObject(
|
||||
'customMatchers',
|
||||
'Matchers must be added in a before function or a spec'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#addCustomMatchers', function() {
|
||||
it("adds all properties to the current runnable's matchers", function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
|
||||
function toBeFoo() {}
|
||||
function toBeBar() {}
|
||||
function toBeBaz() {}
|
||||
|
||||
runnableResources.addCustomMatchers({ toBeFoo });
|
||||
expect(runnableResources.customMatchers()).toEqual({ toBeFoo });
|
||||
|
||||
runnableResources.addCustomMatchers({ toBeBar, toBeBaz });
|
||||
expect(runnableResources.customMatchers()).toEqual({
|
||||
toBeFoo,
|
||||
toBeBar,
|
||||
toBeBaz
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#customAsyncMatchers', function() {
|
||||
behavesLikeAPerRunnableMutableObject(
|
||||
'customAsyncMatchers',
|
||||
'Async Matchers must be added in a before function or a spec'
|
||||
);
|
||||
});
|
||||
|
||||
describe('#addCustomAsyncMatchers', function() {
|
||||
it("adds all properties to the current runnable's matchers", function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
|
||||
function toBeFoo() {}
|
||||
function toBeBar() {}
|
||||
function toBeBaz() {}
|
||||
|
||||
runnableResources.addCustomAsyncMatchers({ toBeFoo });
|
||||
expect(runnableResources.customAsyncMatchers()).toEqual({ toBeFoo });
|
||||
|
||||
runnableResources.addCustomAsyncMatchers({ toBeBar, toBeBaz });
|
||||
expect(runnableResources.customAsyncMatchers()).toEqual({
|
||||
toBeFoo,
|
||||
toBeBar,
|
||||
toBeBaz
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('#defaultSpyStrategy', function() {
|
||||
it('returns undefined for a newly initialized resource', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
|
||||
expect(runnableResources.defaultSpyStrategy()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns the value previously set by #setDefaultSpyStrategy', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
const fn = () => {};
|
||||
runnableResources.setDefaultSpyStrategy(fn);
|
||||
|
||||
expect(runnableResources.defaultSpyStrategy()).toBe(fn);
|
||||
});
|
||||
|
||||
it('is per-runnable', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
runnableResources.setDefaultSpyStrategy(() => {});
|
||||
currentRunnableId = 2;
|
||||
runnableResources.initForRunnable(2);
|
||||
|
||||
expect(runnableResources.defaultSpyStrategy()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('does not require a current runnable', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
expect(runnableResources.defaultSpyStrategy()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("inherits the parent runnable's value", function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
const fn = () => {};
|
||||
runnableResources.setDefaultSpyStrategy(fn);
|
||||
currentRunnableId = 2;
|
||||
runnableResources.initForRunnable(2, 1);
|
||||
|
||||
expect(runnableResources.defaultSpyStrategy()).toBe(fn);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#setDefaultSpyStrategy', function() {
|
||||
it('throws a user-facing error when there is no current runnable', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
expect(function() {
|
||||
runnableResources.setDefaultSpyStrategy();
|
||||
}).toThrowError(
|
||||
'Default spy strategy must be set in a before function or a spec'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#makePrettyPrinter', function() {
|
||||
it('returns a pretty printer configured with the current customObjectFormatters', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(() => 1);
|
||||
runnableResources.initForRunnable(1);
|
||||
function cof() {}
|
||||
runnableResources.customObjectFormatters().push(cof);
|
||||
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.callThrough();
|
||||
const pp = runnableResources.makePrettyPrinter();
|
||||
|
||||
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledOnceWith([
|
||||
cof
|
||||
]);
|
||||
expect(pp).toBe(
|
||||
jasmineUnderTest.makePrettyPrinter.calls.first().returnValue
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#makeMatchersUtil', function() {
|
||||
describe('When there is a current runnable', function() {
|
||||
it('returns a MatchersUtil configured with the current resources', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => 1
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function cof() {}
|
||||
runnableResources.customObjectFormatters().push(cof);
|
||||
function ceq() {}
|
||||
runnableResources.customEqualityTesters().push(ceq);
|
||||
const expectedPP = {};
|
||||
const expectedMatchersUtil = {};
|
||||
spyOn(jasmineUnderTest, 'makePrettyPrinter').and.returnValue(
|
||||
expectedPP
|
||||
);
|
||||
spyOn(jasmineUnderTest, 'MatchersUtil').and.returnValue(
|
||||
expectedMatchersUtil
|
||||
);
|
||||
|
||||
const matchersUtil = runnableResources.makeMatchersUtil();
|
||||
|
||||
expect(matchersUtil).toBe(expectedMatchersUtil);
|
||||
expect(jasmineUnderTest.makePrettyPrinter).toHaveBeenCalledOnceWith([
|
||||
cof
|
||||
]);
|
||||
// We need === equality on the pp passed to MatchersUtil
|
||||
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledOnceWith(
|
||||
jasmine.objectContaining({
|
||||
customTesters: [ceq]
|
||||
})
|
||||
);
|
||||
expect(jasmineUnderTest.MatchersUtil.calls.argsFor(0)[0].pp).toBe(
|
||||
expectedPP
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When there is no current runnable', function() {
|
||||
it('returns a MatchersUtil configured with defaults', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
const expectedMatchersUtil = {};
|
||||
spyOn(jasmineUnderTest, 'MatchersUtil').and.returnValue(
|
||||
expectedMatchersUtil
|
||||
);
|
||||
|
||||
const matchersUtil = runnableResources.makeMatchersUtil();
|
||||
|
||||
expect(matchersUtil).toBe(expectedMatchersUtil);
|
||||
// We need === equality on the pp passed to MatchersUtil
|
||||
expect(jasmineUnderTest.MatchersUtil).toHaveBeenCalledTimes(1);
|
||||
expect(jasmineUnderTest.MatchersUtil.calls.argsFor(0)[0].pp).toBe(
|
||||
jasmineUnderTest.basicPrettyPrinter_
|
||||
);
|
||||
expect(
|
||||
jasmineUnderTest.MatchersUtil.calls.argsFor(0)[0].customTesters
|
||||
).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('.spyFactory', function() {
|
||||
describe('When there is no current runnable', function() {
|
||||
it('is configured with default strategies and matchersUtil', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
spyOn(jasmineUnderTest, 'Spy');
|
||||
const matchersUtil = {};
|
||||
spyOn(runnableResources, 'makeMatchersUtil').and.returnValue(
|
||||
matchersUtil
|
||||
);
|
||||
|
||||
runnableResources.spyFactory.createSpy('foo');
|
||||
|
||||
expect(jasmineUnderTest.Spy).toHaveBeenCalledWith(
|
||||
'foo',
|
||||
is(matchersUtil),
|
||||
jasmine.objectContaining({
|
||||
customStrategies: {},
|
||||
defaultStrategyFn: undefined
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When there is a current runnable', function() {
|
||||
it("is configured with the current runnable's strategies and matchersUtil", function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => 1
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function customStrategy() {}
|
||||
function defaultStrategy() {}
|
||||
runnableResources.customSpyStrategies().foo = customStrategy;
|
||||
runnableResources.setDefaultSpyStrategy(defaultStrategy);
|
||||
spyOn(jasmineUnderTest, 'Spy');
|
||||
const matchersUtil = {};
|
||||
spyOn(runnableResources, 'makeMatchersUtil').and.returnValue(
|
||||
matchersUtil
|
||||
);
|
||||
|
||||
runnableResources.spyFactory.createSpy('foo');
|
||||
|
||||
expect(jasmineUnderTest.Spy).toHaveBeenCalledWith(
|
||||
'foo',
|
||||
is(matchersUtil),
|
||||
jasmine.objectContaining({
|
||||
customStrategies: { foo: customStrategy },
|
||||
defaultStrategyFn: defaultStrategy
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
function is(expected) {
|
||||
return {
|
||||
asymmetricMatch: function(actual) {
|
||||
return actual === expected;
|
||||
},
|
||||
jasmineToString: function(pp) {
|
||||
return '<same instance as ' + pp(expected) + '>';
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
describe('.spyRegistry', function() {
|
||||
it("writes to the current runnable's spies", function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(() => 1);
|
||||
runnableResources.initForRunnable(1);
|
||||
function foo() {}
|
||||
const spyObj = { foo };
|
||||
runnableResources.spyRegistry.spyOn(spyObj, 'foo');
|
||||
|
||||
expect(runnableResources.spies()).toEqual([
|
||||
jasmine.objectContaining({
|
||||
restoreObjectToOriginalState: jasmine.any(Function)
|
||||
})
|
||||
]);
|
||||
expect(jasmineUnderTest.isSpy(spyObj.foo)).toBeTrue();
|
||||
|
||||
runnableResources.spyRegistry.clearSpies();
|
||||
expect(spyObj.foo).toBe(foo);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#clearForRunnable', function() {
|
||||
it('removes resources for the specified runnable', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(() => 1);
|
||||
runnableResources.initForRunnable(1);
|
||||
expect(function() {
|
||||
runnableResources.spies();
|
||||
}).not.toThrow();
|
||||
runnableResources.clearForRunnable(1);
|
||||
expect(function() {
|
||||
runnableResources.spies();
|
||||
}).toThrowError('Spies must be created in a before function or a spec');
|
||||
});
|
||||
|
||||
it('clears spies', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(() => 1);
|
||||
runnableResources.initForRunnable(1);
|
||||
function foo() {}
|
||||
const spyObj = { foo };
|
||||
runnableResources.spyRegistry.spyOn(spyObj, 'foo');
|
||||
expect(spyObj.foo).not.toBe(foo);
|
||||
|
||||
runnableResources.clearForRunnable(1);
|
||||
expect(spyObj.foo).toBe(foo);
|
||||
});
|
||||
|
||||
it('does not remove resources for other runnables', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(() => 1);
|
||||
runnableResources.initForRunnable(1);
|
||||
function cof() {}
|
||||
runnableResources.customObjectFormatters().push(cof);
|
||||
runnableResources.clearForRunnable(2);
|
||||
expect(runnableResources.customObjectFormatters()).toEqual([cof]);
|
||||
});
|
||||
});
|
||||
|
||||
function behavesLikeAPerRunnableMutableArray(
|
||||
methodName,
|
||||
errorMsg,
|
||||
inherits = true
|
||||
) {
|
||||
it('is initially empty', function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
|
||||
expect(runnableResources[methodName]()).toEqual([]);
|
||||
});
|
||||
|
||||
it('is mutable', function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function newItem() {}
|
||||
runnableResources[methodName]().push(newItem);
|
||||
expect(runnableResources[methodName]()).toEqual([newItem]);
|
||||
});
|
||||
|
||||
it('is per-runnable', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
runnableResources[methodName]().push(() => {});
|
||||
runnableResources.initForRunnable(2);
|
||||
currentRunnableId = 2;
|
||||
expect(runnableResources[methodName]()).toEqual([]);
|
||||
});
|
||||
|
||||
it('throws a user-facing error when there is no current runnable', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
expect(function() {
|
||||
runnableResources[methodName]();
|
||||
}).toThrowError(errorMsg);
|
||||
});
|
||||
|
||||
if (inherits) {
|
||||
it('inherits from the parent runnable', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function parentItem() {}
|
||||
runnableResources[methodName]().push(parentItem);
|
||||
runnableResources.initForRunnable(2, 1);
|
||||
currentRunnableId = 2;
|
||||
function childItem() {}
|
||||
runnableResources[methodName]().push(childItem);
|
||||
expect(runnableResources[methodName]()).toEqual([
|
||||
parentItem,
|
||||
childItem
|
||||
]);
|
||||
|
||||
currentRunnableId = 1;
|
||||
expect(runnableResources[methodName]()).toEqual([parentItem]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function behavesLikeAPerRunnableMutableObject(methodName, errorMsg) {
|
||||
it('is initially empty', function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
|
||||
expect(runnableResources[methodName]()).toEqual({});
|
||||
});
|
||||
|
||||
it('is mutable', function() {
|
||||
const currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function newItem() {}
|
||||
runnableResources[methodName]().foo = newItem;
|
||||
expect(runnableResources[methodName]()).toEqual({ foo: newItem });
|
||||
});
|
||||
|
||||
it('is per-runnable', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
runnableResources[methodName]().foo = function() {};
|
||||
runnableResources.initForRunnable(2);
|
||||
currentRunnableId = 2;
|
||||
expect(runnableResources[methodName]()).toEqual({});
|
||||
});
|
||||
|
||||
it('throws a user-facing error when there is no current runnable', function() {
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => null
|
||||
);
|
||||
expect(function() {
|
||||
runnableResources[methodName]();
|
||||
}).toThrowError(errorMsg);
|
||||
});
|
||||
|
||||
it('inherits from the parent runnable', function() {
|
||||
let currentRunnableId = 1;
|
||||
const runnableResources = new jasmineUnderTest.RunnableResources(
|
||||
() => currentRunnableId
|
||||
);
|
||||
runnableResources.initForRunnable(1);
|
||||
function parentItem() {}
|
||||
runnableResources[methodName]().parentName = parentItem;
|
||||
runnableResources.initForRunnable(2, 1);
|
||||
currentRunnableId = 2;
|
||||
function childItem() {}
|
||||
runnableResources[methodName]().childName = childItem;
|
||||
expect(runnableResources[methodName]()).toEqual({
|
||||
parentName: parentItem,
|
||||
childName: childItem
|
||||
});
|
||||
|
||||
currentRunnableId = 1;
|
||||
expect(runnableResources[methodName]()).toEqual({
|
||||
parentName: parentItem
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1354,6 +1354,7 @@ describe('Env integration', function() {
|
||||
env.it('spec 1', secondSpec);
|
||||
});
|
||||
|
||||
env.configure({ random: false });
|
||||
await env.execute();
|
||||
|
||||
expect(firstSpec).toHaveBeenCalled();
|
||||
|
||||
214
src/core/Env.js
214
src/core/Env.js
@@ -26,7 +26,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
new j$.MockDate(global)
|
||||
);
|
||||
|
||||
const runnableResources = {};
|
||||
const runnableResources = new j$.RunnableResources(function() {
|
||||
const r = currentRunnable();
|
||||
return r ? r.id : null;
|
||||
});
|
||||
|
||||
let topSuite;
|
||||
let currentSpec = null;
|
||||
@@ -36,7 +39,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
let hasFailures = false;
|
||||
let deprecator;
|
||||
let reporter;
|
||||
let spyRegistry;
|
||||
|
||||
/**
|
||||
* This represents the available options to configure Jasmine.
|
||||
@@ -230,74 +232,27 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
};
|
||||
|
||||
this.setDefaultSpyStrategy = function(defaultStrategyFn) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Default spy strategy must be set in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[
|
||||
currentRunnable().id
|
||||
].defaultStrategyFn = defaultStrategyFn;
|
||||
runnableResources.setDefaultSpyStrategy(defaultStrategyFn);
|
||||
};
|
||||
|
||||
this.addSpyStrategy = function(name, fn) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom spy strategies must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[currentRunnable().id].customSpyStrategies[name] = fn;
|
||||
runnableResources.customSpyStrategies()[name] = fn;
|
||||
};
|
||||
|
||||
this.addCustomEqualityTester = function(tester) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom Equalities must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
runnableResources[currentRunnable().id].customEqualityTesters.push(
|
||||
tester
|
||||
);
|
||||
runnableResources.customEqualityTesters().push(tester);
|
||||
};
|
||||
|
||||
this.addMatchers = function(matchersToAdd) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Matchers must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
const customMatchers =
|
||||
runnableResources[currentRunnable().id].customMatchers;
|
||||
|
||||
for (const matcherName in matchersToAdd) {
|
||||
customMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
runnableResources.addCustomMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.addAsyncMatchers = function(matchersToAdd) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Async Matchers must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
const customAsyncMatchers =
|
||||
runnableResources[currentRunnable().id].customAsyncMatchers;
|
||||
|
||||
for (const matcherName in matchersToAdd) {
|
||||
customAsyncMatchers[matcherName] = matchersToAdd[matcherName];
|
||||
}
|
||||
runnableResources.addCustomAsyncMatchers(matchersToAdd);
|
||||
};
|
||||
|
||||
this.addCustomObjectFormatter = function(formatter) {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Custom object formatters must be added in a before function or a spec'
|
||||
);
|
||||
}
|
||||
|
||||
runnableResources[currentRunnable().id].customObjectFormatters.push(
|
||||
formatter
|
||||
);
|
||||
runnableResources.customObjectFormatters().push(formatter);
|
||||
};
|
||||
|
||||
j$.Expectation.addCoreMatchers(j$.matchers);
|
||||
@@ -315,31 +270,10 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return 'suite' + nextSuiteId++;
|
||||
}
|
||||
|
||||
function makePrettyPrinter() {
|
||||
const customObjectFormatters =
|
||||
runnableResources[currentRunnable().id].customObjectFormatters;
|
||||
return j$.makePrettyPrinter(customObjectFormatters);
|
||||
}
|
||||
|
||||
function makeMatchersUtil() {
|
||||
const cr = currentRunnable();
|
||||
|
||||
if (cr) {
|
||||
const customEqualityTesters =
|
||||
runnableResources[cr.id].customEqualityTesters;
|
||||
return new j$.MatchersUtil({
|
||||
customTesters: customEqualityTesters,
|
||||
pp: makePrettyPrinter()
|
||||
});
|
||||
} else {
|
||||
return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
|
||||
}
|
||||
}
|
||||
|
||||
const expectationFactory = function(actual, spec) {
|
||||
return j$.Expectation.factory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customMatchers: runnableResources[spec.id].customMatchers,
|
||||
matchersUtil: runnableResources.makeMatchersUtil(),
|
||||
customMatchers: runnableResources.customMatchers(),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -416,8 +350,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
const asyncExpectationFactory = function(actual, spec, runableType) {
|
||||
return j$.Expectation.asyncFactory({
|
||||
matchersUtil: makeMatchersUtil(),
|
||||
customAsyncMatchers: runnableResources[spec.id].customAsyncMatchers,
|
||||
matchersUtil: runnableResources.makeMatchersUtil(),
|
||||
customAsyncMatchers: runnableResources.customAsyncMatchers(),
|
||||
actual: actual,
|
||||
addExpectationResult: addExpectationResult
|
||||
});
|
||||
@@ -437,45 +371,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return asyncExpectationFactory(actual, suite, 'Spec');
|
||||
};
|
||||
|
||||
function defaultResourcesForRunnable(id, parentRunnableId) {
|
||||
const resources = {
|
||||
spies: [],
|
||||
customEqualityTesters: [],
|
||||
customMatchers: {},
|
||||
customAsyncMatchers: {},
|
||||
customSpyStrategies: {},
|
||||
defaultStrategyFn: undefined,
|
||||
customObjectFormatters: []
|
||||
};
|
||||
|
||||
if (runnableResources[parentRunnableId]) {
|
||||
resources.customEqualityTesters = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customEqualityTesters
|
||||
);
|
||||
resources.customMatchers = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customMatchers
|
||||
);
|
||||
resources.customAsyncMatchers = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customAsyncMatchers
|
||||
);
|
||||
resources.customObjectFormatters = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customObjectFormatters
|
||||
);
|
||||
resources.customSpyStrategies = j$.util.clone(
|
||||
runnableResources[parentRunnableId].customSpyStrategies
|
||||
);
|
||||
resources.defaultStrategyFn =
|
||||
runnableResources[parentRunnableId].defaultStrategyFn;
|
||||
}
|
||||
|
||||
runnableResources[id] = resources;
|
||||
}
|
||||
|
||||
function clearResourcesForRunnable(id) {
|
||||
spyRegistry.clearSpies();
|
||||
delete runnableResources[id];
|
||||
}
|
||||
|
||||
function beforeAndAfterFns(targetSuite) {
|
||||
return function() {
|
||||
let befores = [],
|
||||
@@ -701,7 +596,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
topSuite.reset();
|
||||
}
|
||||
this._executedBefore = true;
|
||||
defaultResourcesForRunnable(topSuite.id);
|
||||
runnableResources.initForRunnable(topSuite.id);
|
||||
installGlobalErrors();
|
||||
|
||||
if (!runnablesToRun) {
|
||||
@@ -724,7 +619,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
failSpecWithNoExpectations: config.failSpecWithNoExpectations,
|
||||
nodeStart: function(suite, next) {
|
||||
currentlyExecutingSuites.push(suite);
|
||||
defaultResourcesForRunnable(suite.id, suite.parentSuite.id);
|
||||
runnableResources.initForRunnable(suite.id, suite.parentSuite.id);
|
||||
reporter.suiteStarted(suite.result, next);
|
||||
suite.startTimer();
|
||||
},
|
||||
@@ -733,7 +628,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
throw new Error('Tried to complete the wrong suite');
|
||||
}
|
||||
|
||||
clearResourcesForRunnable(suite.id);
|
||||
runnableResources.clearForRunnable(suite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
|
||||
if (result.status === 'failed') {
|
||||
@@ -798,7 +693,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
await reportChildrenOfBeforeAllFailure(topSuite);
|
||||
}
|
||||
|
||||
clearResourcesForRunnable(topSuite.id);
|
||||
runnableResources.clearForRunnable(topSuite.id);
|
||||
currentlyExecutingSuites.pop();
|
||||
let overallStatus, incompleteReason;
|
||||
|
||||
@@ -922,42 +817,6 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
reporter.clearReporters();
|
||||
};
|
||||
|
||||
const spyFactory = new j$.SpyFactory(
|
||||
function getCustomStrategies() {
|
||||
const runnable = currentRunnable();
|
||||
|
||||
if (runnable) {
|
||||
return runnableResources[runnable.id].customSpyStrategies;
|
||||
}
|
||||
|
||||
return {};
|
||||
},
|
||||
function getDefaultStrategyFn() {
|
||||
const runnable = currentRunnable();
|
||||
|
||||
if (runnable) {
|
||||
return runnableResources[runnable.id].defaultStrategyFn;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
},
|
||||
makeMatchersUtil
|
||||
);
|
||||
|
||||
spyRegistry = new j$.SpyRegistry({
|
||||
currentSpies: function() {
|
||||
if (!currentRunnable()) {
|
||||
throw new Error(
|
||||
'Spies must be created in a before function or a spec'
|
||||
);
|
||||
}
|
||||
return runnableResources[currentRunnable().id].spies;
|
||||
},
|
||||
createSpy: function(name, originalFn) {
|
||||
return self.createSpy(name, originalFn);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Configures whether Jasmine should allow the same function to be spied on
|
||||
* more than once during the execution of a spec. By default, spying on
|
||||
@@ -968,32 +827,40 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @param {boolean} allow Whether to allow respying
|
||||
*/
|
||||
this.allowRespy = function(allow) {
|
||||
spyRegistry.allowRespy(allow);
|
||||
runnableResources.spyRegistry.allowRespy(allow);
|
||||
};
|
||||
|
||||
this.spyOn = function() {
|
||||
return spyRegistry.spyOn.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOn.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.spyOnProperty = function() {
|
||||
return spyRegistry.spyOnProperty.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOnProperty.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.spyOnAllFunctions = function() {
|
||||
return spyRegistry.spyOnAllFunctions.apply(spyRegistry, arguments);
|
||||
return runnableResources.spyRegistry.spyOnAllFunctions.apply(
|
||||
runnableResources.spyRegistry,
|
||||
arguments
|
||||
);
|
||||
};
|
||||
|
||||
this.createSpy = function(name, originalFn) {
|
||||
if (arguments.length === 1 && j$.isFunction_(name)) {
|
||||
originalFn = name;
|
||||
name = originalFn.name;
|
||||
}
|
||||
|
||||
return spyFactory.createSpy(name, originalFn);
|
||||
return runnableResources.spyFactory.createSpy(name, originalFn);
|
||||
};
|
||||
|
||||
this.createSpyObj = function(baseName, methodNames, propertyNames) {
|
||||
return spyFactory.createSpyObj(baseName, methodNames, propertyNames);
|
||||
return runnableResources.spyFactory.createSpyObj(
|
||||
baseName,
|
||||
methodNames,
|
||||
propertyNames
|
||||
);
|
||||
};
|
||||
|
||||
function ensureIsFunction(fn, caller) {
|
||||
@@ -1148,7 +1015,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
return spec;
|
||||
|
||||
function specResultCallback(result, next) {
|
||||
clearResourcesForRunnable(spec.id);
|
||||
runnableResources.clearForRunnable(spec.id);
|
||||
currentSpec = null;
|
||||
|
||||
if (result.status === 'failed') {
|
||||
@@ -1160,7 +1027,7 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
|
||||
function specStarted(spec, next) {
|
||||
currentSpec = spec;
|
||||
defaultResourcesForRunnable(spec.id, suite.id);
|
||||
runnableResources.initForRunnable(spec.id, suite.id);
|
||||
reporter.specStarted(spec.result, next);
|
||||
}
|
||||
};
|
||||
@@ -1382,7 +1249,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
message += error;
|
||||
} else {
|
||||
// pretty print all kind of objects. This includes arrays.
|
||||
message += makePrettyPrinter()(error);
|
||||
const pp = runnableResources.makePrettyPrinter();
|
||||
message += pp(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
154
src/core/RunnableResources.js
Normal file
154
src/core/RunnableResources.js
Normal file
@@ -0,0 +1,154 @@
|
||||
getJasmineRequireObj().RunnableResources = function(j$) {
|
||||
class RunnableResources {
|
||||
constructor(getCurrentRunnableId) {
|
||||
this.byRunnableId_ = {};
|
||||
this.getCurrentRunnableId_ = getCurrentRunnableId;
|
||||
|
||||
this.spyFactory = new j$.SpyFactory(
|
||||
() => {
|
||||
if (this.getCurrentRunnableId_()) {
|
||||
return this.customSpyStrategies();
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
() => this.defaultSpyStrategy(),
|
||||
() => this.makeMatchersUtil()
|
||||
);
|
||||
|
||||
this.spyRegistry = new j$.SpyRegistry({
|
||||
currentSpies: () => this.spies(),
|
||||
createSpy: (name, originalFn) =>
|
||||
this.spyFactory.createSpy(name, originalFn)
|
||||
});
|
||||
}
|
||||
|
||||
initForRunnable(runnableId, parentId) {
|
||||
const newRes = (this.byRunnableId_[runnableId] = {
|
||||
customEqualityTesters: [],
|
||||
customMatchers: {},
|
||||
customAsyncMatchers: {},
|
||||
customSpyStrategies: {},
|
||||
customObjectFormatters: [],
|
||||
defaultSpyStrategy: undefined,
|
||||
spies: []
|
||||
});
|
||||
|
||||
const parentRes = this.byRunnableId_[parentId];
|
||||
|
||||
if (parentRes) {
|
||||
newRes.defaultSpyStrategy = parentRes.defaultSpyStrategy;
|
||||
const toClone = [
|
||||
'customEqualityTesters',
|
||||
'customMatchers',
|
||||
'customAsyncMatchers',
|
||||
'customObjectFormatters',
|
||||
'customSpyStrategies'
|
||||
];
|
||||
|
||||
for (const k of toClone) {
|
||||
newRes[k] = j$.util.clone(parentRes[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearForRunnable(runnableId) {
|
||||
this.spyRegistry.clearSpies();
|
||||
delete this.byRunnableId_[runnableId];
|
||||
}
|
||||
|
||||
spies() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Spies must be created in a before function or a spec'
|
||||
).spies;
|
||||
}
|
||||
|
||||
defaultSpyStrategy() {
|
||||
if (!this.getCurrentRunnableId_()) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return this.byRunnableId_[this.getCurrentRunnableId_()]
|
||||
.defaultSpyStrategy;
|
||||
}
|
||||
|
||||
setDefaultSpyStrategy(fn) {
|
||||
this.forCurrentRunnable_(
|
||||
'Default spy strategy must be set in a before function or a spec'
|
||||
).defaultSpyStrategy = fn;
|
||||
}
|
||||
|
||||
customSpyStrategies() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom spy strategies must be added in a before function or a spec'
|
||||
).customSpyStrategies;
|
||||
}
|
||||
|
||||
customEqualityTesters() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom Equalities must be added in a before function or a spec'
|
||||
).customEqualityTesters;
|
||||
}
|
||||
|
||||
customMatchers() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Matchers must be added in a before function or a spec'
|
||||
).customMatchers;
|
||||
}
|
||||
|
||||
addCustomMatchers(matchersToAdd) {
|
||||
const matchers = this.customMatchers();
|
||||
|
||||
for (const name in matchersToAdd) {
|
||||
matchers[name] = matchersToAdd[name];
|
||||
}
|
||||
}
|
||||
|
||||
customAsyncMatchers() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Async Matchers must be added in a before function or a spec'
|
||||
).customAsyncMatchers;
|
||||
}
|
||||
|
||||
addCustomAsyncMatchers(matchersToAdd) {
|
||||
const matchers = this.customAsyncMatchers();
|
||||
|
||||
for (const name in matchersToAdd) {
|
||||
matchers[name] = matchersToAdd[name];
|
||||
}
|
||||
}
|
||||
|
||||
customObjectFormatters() {
|
||||
return this.forCurrentRunnable_(
|
||||
'Custom object formatters must be added in a before function or a spec'
|
||||
).customObjectFormatters;
|
||||
}
|
||||
|
||||
makePrettyPrinter() {
|
||||
return j$.makePrettyPrinter(this.customObjectFormatters());
|
||||
}
|
||||
|
||||
makeMatchersUtil() {
|
||||
if (this.getCurrentRunnableId_()) {
|
||||
return new j$.MatchersUtil({
|
||||
customTesters: this.customEqualityTesters(),
|
||||
pp: this.makePrettyPrinter()
|
||||
});
|
||||
} else {
|
||||
return new j$.MatchersUtil({ pp: j$.basicPrettyPrinter_ });
|
||||
}
|
||||
}
|
||||
|
||||
forCurrentRunnable_(errorMsg) {
|
||||
const resources = this.byRunnableId_[this.getCurrentRunnableId_()];
|
||||
|
||||
if (!resources && errorMsg) {
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
}
|
||||
|
||||
return RunnableResources;
|
||||
};
|
||||
@@ -5,6 +5,11 @@ getJasmineRequireObj().SpyFactory = function(j$) {
|
||||
getMatchersUtil
|
||||
) {
|
||||
this.createSpy = function(name, originalFn) {
|
||||
if (j$.isFunction_(name) && originalFn === undefined) {
|
||||
originalFn = name;
|
||||
name = originalFn.name;
|
||||
}
|
||||
|
||||
return j$.Spy(name, getMatchersUtil(), {
|
||||
originalFn,
|
||||
customStrategies: getCustomStrategies(),
|
||||
|
||||
@@ -68,6 +68,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$
|
||||
);
|
||||
j$.ReportDispatcher = jRequire.ReportDispatcher(j$);
|
||||
j$.RunnableResources = jRequire.RunnableResources(j$);
|
||||
j$.Spec = jRequire.Spec(j$);
|
||||
j$.Spy = jRequire.Spy(j$);
|
||||
j$.SpyFactory = jRequire.SpyFactory(j$);
|
||||
|
||||
Reference in New Issue
Block a user