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$.getClearStack = jRequire.clearStack(j$);
|
||||||
j$.Clock = jRequire.Clock();
|
j$.Clock = jRequire.Clock();
|
||||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||||
|
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||||
j$.Deprecator = jRequire.Deprecator(j$);
|
j$.Deprecator = jRequire.Deprecator(j$);
|
||||||
j$.Configuration = jRequire.Configuration(j$);
|
j$.Configuration = jRequire.Configuration(j$);
|
||||||
j$.Env = jRequire.Env(j$);
|
j$.Env = jRequire.Env(j$);
|
||||||
@@ -1498,7 +1499,8 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
runQueue,
|
runQueue,
|
||||||
TreeProcessor: j$.TreeProcessor,
|
TreeProcessor: j$.TreeProcessor,
|
||||||
globalErrors,
|
globalErrors,
|
||||||
getConfig: () => config
|
getConfig: () => config,
|
||||||
|
deprecated: this.deprecated
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setParallelLoadingState = function(state) {
|
this.setParallelLoadingState = function(state) {
|
||||||
@@ -3711,6 +3713,43 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
|||||||
return DelayedFunctionScheduler;
|
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$) {
|
getJasmineRequireObj().Deprecator = function(j$) {
|
||||||
function Deprecator(topSuite) {
|
function Deprecator(topSuite) {
|
||||||
this.topSuite_ = topSuite;
|
this.topSuite_ = topSuite;
|
||||||
@@ -9440,6 +9479,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
#globalErrors;
|
#globalErrors;
|
||||||
#reportDispatcher;
|
#reportDispatcher;
|
||||||
#getConfig;
|
#getConfig;
|
||||||
|
#deprecated;
|
||||||
#executedBefore;
|
#executedBefore;
|
||||||
#currentRunableTracker;
|
#currentRunableTracker;
|
||||||
|
|
||||||
@@ -9453,6 +9493,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
this.#globalErrors = options.globalErrors;
|
this.#globalErrors = options.globalErrors;
|
||||||
this.#reportDispatcher = options.reportDispatcher;
|
this.#reportDispatcher = options.reportDispatcher;
|
||||||
this.#getConfig = options.getConfig;
|
this.#getConfig = options.getConfig;
|
||||||
|
this.#deprecated = options.deprecated;
|
||||||
this.#executedBefore = false;
|
this.#executedBefore = false;
|
||||||
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
||||||
}
|
}
|
||||||
@@ -9505,8 +9546,9 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
orderChildren: function(node) {
|
orderChildren: function(node) {
|
||||||
return order.sort(node.children);
|
return order.sort(node.children);
|
||||||
},
|
},
|
||||||
excludeNode: function(spec) {
|
excludeNode: spec => {
|
||||||
return !config.specFilter(spec);
|
const proxy = j$.deprecatingSpecProxy(spec, this.#deprecated);
|
||||||
|
return !config.specFilter(proxy);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.#executionTree = treeProcessor.processTree();
|
this.#executionTree = treeProcessor.processTree();
|
||||||
|
|||||||
@@ -913,6 +913,7 @@ describe('Env integration', function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
env.configure({
|
env.configure({
|
||||||
|
random: false,
|
||||||
specFilter: function(spec) {
|
specFilter: function(spec) {
|
||||||
return /^first suite/.test(spec.getFullName());
|
return /^first suite/.test(spec.getFullName());
|
||||||
}
|
}
|
||||||
@@ -920,13 +921,44 @@ describe('Env integration', function() {
|
|||||||
|
|
||||||
await env.execute();
|
await env.execute();
|
||||||
|
|
||||||
expect(calls.length).toEqual(2);
|
expect(calls).toEqual(['first spec', 'second spec']);
|
||||||
expect(calls).toEqual(
|
|
||||||
jasmine.arrayContaining(['first spec', 'second spec'])
|
|
||||||
);
|
|
||||||
expect(suiteCallback).toHaveBeenCalled();
|
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() {
|
it('Functions can be spied on and have their calls tracked', async function() {
|
||||||
let originalFunctionWasCalled = false;
|
let originalFunctionWasCalled = false;
|
||||||
const subject = {
|
const subject = {
|
||||||
|
|||||||
@@ -371,7 +371,8 @@ getJasmineRequireObj().Env = function(j$) {
|
|||||||
runQueue,
|
runQueue,
|
||||||
TreeProcessor: j$.TreeProcessor,
|
TreeProcessor: j$.TreeProcessor,
|
||||||
globalErrors,
|
globalErrors,
|
||||||
getConfig: () => config
|
getConfig: () => config,
|
||||||
|
deprecated: this.deprecated
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setParallelLoadingState = function(state) {
|
this.setParallelLoadingState = function(state) {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
#globalErrors;
|
#globalErrors;
|
||||||
#reportDispatcher;
|
#reportDispatcher;
|
||||||
#getConfig;
|
#getConfig;
|
||||||
|
#deprecated;
|
||||||
#executedBefore;
|
#executedBefore;
|
||||||
#currentRunableTracker;
|
#currentRunableTracker;
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
this.#globalErrors = options.globalErrors;
|
this.#globalErrors = options.globalErrors;
|
||||||
this.#reportDispatcher = options.reportDispatcher;
|
this.#reportDispatcher = options.reportDispatcher;
|
||||||
this.#getConfig = options.getConfig;
|
this.#getConfig = options.getConfig;
|
||||||
|
this.#deprecated = options.deprecated;
|
||||||
this.#executedBefore = false;
|
this.#executedBefore = false;
|
||||||
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
this.#currentRunableTracker = new j$.CurrentRunableTracker();
|
||||||
}
|
}
|
||||||
@@ -75,8 +77,9 @@ getJasmineRequireObj().Runner = function(j$) {
|
|||||||
orderChildren: function(node) {
|
orderChildren: function(node) {
|
||||||
return order.sort(node.children);
|
return order.sort(node.children);
|
||||||
},
|
},
|
||||||
excludeNode: function(spec) {
|
excludeNode: spec => {
|
||||||
return !config.specFilter(spec);
|
const proxy = j$.deprecatingSpecProxy(spec, this.#deprecated);
|
||||||
|
return !config.specFilter(proxy);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.#executionTree = treeProcessor.processTree();
|
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$.getClearStack = jRequire.clearStack(j$);
|
||||||
j$.Clock = jRequire.Clock();
|
j$.Clock = jRequire.Clock();
|
||||||
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||||
|
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
|
||||||
j$.Deprecator = jRequire.Deprecator(j$);
|
j$.Deprecator = jRequire.Deprecator(j$);
|
||||||
j$.Configuration = jRequire.Configuration(j$);
|
j$.Configuration = jRequire.Configuration(j$);
|
||||||
j$.Env = jRequire.Env(j$);
|
j$.Env = jRequire.Env(j$);
|
||||||
|
|||||||
Reference in New Issue
Block a user