Deprecate access to non-public Spec properties in spec filters
This commit is contained in:
@@ -66,6 +66,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||
j$.Deprecator = jRequire.Deprecator(j$);
|
||||
j$.Configuration = jRequire.Configuration(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
@@ -1498,7 +1499,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
runQueue,
|
||||
TreeProcessor: j$.TreeProcessor,
|
||||
globalErrors,
|
||||
getConfig: () => config
|
||||
getConfig: () => config,
|
||||
deprecated: this.deprecated
|
||||
});
|
||||
|
||||
this.setParallelLoadingState = function(state) {
|
||||
@@ -3711,6 +3713,43 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
return DelayedFunctionScheduler;
|
||||
};
|
||||
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
|
||||
const allowedMembers = ['id', 'description', 'getFullName', 'getPath'];
|
||||
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
const memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Spec members (in this case `' +
|
||||
memberName +
|
||||
'`) via spec filters is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
|
||||
function deprecatingSpecProxy(spec, deprecated) {
|
||||
return new Proxy(spec, {
|
||||
get(target, prop, receiver) {
|
||||
if (isMember(target, prop) && !allowedMembers.includes(prop)) {
|
||||
deprecated(msg(prop));
|
||||
}
|
||||
|
||||
return target[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deprecatingSpecProxy;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().Deprecator = function(j$) {
|
||||
function Deprecator(topSuite) {
|
||||
this.topSuite_ = topSuite;
|
||||
@@ -9440,6 +9479,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
#globalErrors;
|
||||
#reportDispatcher;
|
||||
#getConfig;
|
||||
#deprecated;
|
||||
#executedBefore;
|
||||
#currentRunableTracker;
|
||||
|
||||
@@ -9453,6 +9493,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
this.#globalErrors = options.globalErrors;
|
||||
this.#reportDispatcher = options.reportDispatcher;
|
||||
this.#getConfig = options.getConfig;
|
||||
this.#deprecated = options.deprecated;
|
||||
this.#executedBefore = false;
|
||||
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
||||
}
|
||||
@@ -9505,8 +9546,9 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
orderChildren: function(node) {
|
||||
return order.sort(node.children);
|
||||
},
|
||||
excludeNode: function(spec) {
|
||||
return !config.specFilter(spec);
|
||||
excludeNode: spec => {
|
||||
const proxy = j$.deprecatingSpecProxy(spec, this.#deprecated);
|
||||
return !config.specFilter(proxy);
|
||||
}
|
||||
});
|
||||
this.#executionTree = treeProcessor.processTree();
|
||||
|
||||
@@ -913,6 +913,7 @@ describe('Env integration', function() {
|
||||
});
|
||||
|
||||
env.configure({
|
||||
random: false,
|
||||
specFilter: function(spec) {
|
||||
return /^first suite/.test(spec.getFullName());
|
||||
}
|
||||
@@ -920,13 +921,44 @@ describe('Env integration', function() {
|
||||
|
||||
await env.execute();
|
||||
|
||||
expect(calls.length).toEqual(2);
|
||||
expect(calls).toEqual(
|
||||
jasmine.arrayContaining(['first spec', 'second spec'])
|
||||
);
|
||||
expect(calls).toEqual(['first spec', 'second spec']);
|
||||
expect(suiteCallback).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('reports a deprecation warning when a spec filter accesses private properties', async function() {
|
||||
env.it('a spec', function() {});
|
||||
|
||||
const reporter = jasmine.createSpyObj('reporter', ['jasmineDone']);
|
||||
env.addReporter(reporter);
|
||||
|
||||
env.configure({
|
||||
random: false,
|
||||
specFilter: function(spec) {
|
||||
spec.result; // deprecated
|
||||
spec.id; // not deprecated
|
||||
spec.description; // not deprecated
|
||||
spec.getPath(); // not deprecated
|
||||
spec.getFullName(); // not deprecated
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
spyOn(console, 'error');
|
||||
await env.execute();
|
||||
|
||||
expect(reporter.jasmineDone).toHaveBeenCalledWith(
|
||||
jasmine.objectContaining({
|
||||
deprecationWarnings: [
|
||||
jasmine.objectContaining({
|
||||
message: jasmine.stringContaining(
|
||||
'Access to private Spec members (in this case `result`)'
|
||||
)
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('Functions can be spied on and have their calls tracked', async function() {
|
||||
let originalFunctionWasCalled = false;
|
||||
const subject = {
|
||||
|
||||
@@ -371,7 +371,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
runQueue,
|
||||
TreeProcessor: j$.TreeProcessor,
|
||||
globalErrors,
|
||||
getConfig: () => config
|
||||
getConfig: () => config,
|
||||
deprecated: this.deprecated
|
||||
});
|
||||
|
||||
this.setParallelLoadingState = function(state) {
|
||||
|
||||
@@ -10,6 +10,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
#globalErrors;
|
||||
#reportDispatcher;
|
||||
#getConfig;
|
||||
#deprecated;
|
||||
#executedBefore;
|
||||
#currentRunableTracker;
|
||||
|
||||
@@ -23,6 +24,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
this.#globalErrors = options.globalErrors;
|
||||
this.#reportDispatcher = options.reportDispatcher;
|
||||
this.#getConfig = options.getConfig;
|
||||
this.#deprecated = options.deprecated;
|
||||
this.#executedBefore = false;
|
||||
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
||||
}
|
||||
@@ -75,8 +77,9 @@ getJasmineRequireObj().Runner = function(j$) {
|
||||
orderChildren: function(node) {
|
||||
return order.sort(node.children);
|
||||
},
|
||||
excludeNode: function(spec) {
|
||||
return !config.specFilter(spec);
|
||||
excludeNode: spec => {
|
||||
const proxy = j$.deprecatingSpecProxy(spec, this.#deprecated);
|
||||
return !config.specFilter(proxy);
|
||||
}
|
||||
});
|
||||
this.#executionTree = treeProcessor.processTree();
|
||||
|
||||
36
src/core/deprecatingSpecProxy.js
Normal file
36
src/core/deprecatingSpecProxy.js
Normal file
@@ -0,0 +1,36 @@
|
||||
// TODO: Remove this in the next major release.
|
||||
getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
|
||||
const allowedMembers = ['id', 'description', 'getFullName', 'getPath'];
|
||||
|
||||
function isMember(target, prop) {
|
||||
return (
|
||||
Object.keys(target).indexOf(prop) !== -1 ||
|
||||
Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
|
||||
);
|
||||
}
|
||||
|
||||
function msg(member) {
|
||||
const memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
|
||||
return (
|
||||
'Access to private Spec members (in this case `' +
|
||||
memberName +
|
||||
'`) via spec filters is not supported and will break in ' +
|
||||
'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
|
||||
'for correct usage.'
|
||||
);
|
||||
}
|
||||
|
||||
function deprecatingSpecProxy(spec, deprecated) {
|
||||
return new Proxy(spec, {
|
||||
get(target, prop, receiver) {
|
||||
if (isMember(target, prop) && !allowedMembers.includes(prop)) {
|
||||
deprecated(msg(prop));
|
||||
}
|
||||
|
||||
return target[prop];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deprecatingSpecProxy;
|
||||
};
|
||||
@@ -42,6 +42,7 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
|
||||
j$.getClearStack = jRequire.clearStack(j$);
|
||||
j$.Clock = jRequire.Clock();
|
||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||
j$.Deprecator = jRequire.Deprecator(j$);
|
||||
j$.Configuration = jRequire.Configuration(j$);
|
||||
j$.Env = jRequire.Env(j$);
|
||||
|
||||
Reference in New Issue
Block a user