Deprecate access to non-public Suite and Spec members via Env#topSuite

The deprecation warning relies on Proxy, and won't work in environments
that don't have it. Among Jasmine's supported environments, that's Safari 9,
Safari 8, and all versions of IE.
This commit is contained in:
Steve Gravrock
2021-05-22 14:13:58 -07:00
parent 6a2a30d540
commit 00c1e3d608
6 changed files with 478 additions and 4 deletions

View File

@@ -734,7 +734,7 @@ getJasmineRequireObj().Env = function(j$) {
* @return {Suite} the root suite
*/
this.topSuite = function() {
return topSuite;
return j$.deprecatingSuiteProxy(topSuite, null, this);
};
/**

View File

@@ -0,0 +1,70 @@
/* eslint-disable compat/compat */
// TODO: Remove this in the next major release.
getJasmineRequireObj().deprecatingSpecProxy = function(j$) {
function isMember(target, prop) {
return (
Object.keys(target).indexOf(prop) !== -1 ||
Object.keys(j$.Spec.prototype).indexOf(prop) !== -1
);
}
function isAllowedMember(prop) {
return prop === 'description' || prop === 'getFullName';
}
function msg(member) {
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
return (
'Access to private Spec members (in this case `' +
memberName +
'`) via Env#topSuite is not supported and will break in ' +
'a future release. See <https://jasmine.github.io/api/edge/Spec.html> ' +
'for correct usage.'
);
}
try {
new Proxy({}, {});
} catch (e) {
// Environment does not support Poxy.
return function(spec) {
return spec;
};
}
function DeprecatingSpecProxyHandler(env) {
this._env = env;
}
DeprecatingSpecProxyHandler.prototype.get = function(target, prop, receiver) {
this._maybeDeprecate(target, prop);
if (prop === 'getFullName') {
// getFullName calls a private method. Re-bind 'this' to avoid a bogus
// deprecation warning.
return target.getFullName.bind(target);
} else {
return target[prop];
}
};
DeprecatingSpecProxyHandler.prototype.set = function(target, prop, value) {
this._maybeDeprecate(target, prop);
return (target[prop] = value);
};
DeprecatingSpecProxyHandler.prototype._maybeDeprecate = function(
target,
prop
) {
if (isMember(target, prop) && !isAllowedMember(prop)) {
this._env.deprecated(msg(prop));
}
};
function deprecatingSpecProxy(spec, env) {
return new Proxy(spec, new DeprecatingSpecProxyHandler(env));
}
return deprecatingSpecProxy;
};

View File

@@ -0,0 +1,98 @@
/* eslint-disable compat/compat */
// TODO: Remove this in the next major release.
getJasmineRequireObj().deprecatingSuiteProxy = function(j$) {
var allowedMembers = [
'children',
'description',
'parentSuite',
'getFullName'
];
function isMember(target, prop) {
return (
Object.keys(target).indexOf(prop) !== -1 ||
Object.keys(j$.Suite.prototype).indexOf(prop) !== -1
);
}
function isAllowedMember(prop) {
return allowedMembers.indexOf(prop) !== -1;
}
function msg(member) {
var memberName = member.toString().replace(/^Symbol\((.+)\)$/, '$1');
return (
'Access to private Suite members (in this case `' +
memberName +
'`) via Env#topSuite is not supported and will break in ' +
'a future release. See <https://jasmine.github.io/api/edge/Suite.html> ' +
'for correct usage.'
);
}
try {
new Proxy({}, {});
} catch (e) {
// Environment does not support Poxy.
return function(suite) {
return suite;
};
}
function DeprecatingSuiteProxyHandler(parentSuite, env) {
this._parentSuite = parentSuite;
this._env = env;
}
DeprecatingSuiteProxyHandler.prototype.get = function(
target,
prop,
receiver
) {
if (prop === 'children') {
if (!this._children) {
this._children = target.children.map(
this._proxyForChild.bind(this, receiver)
);
}
return this._children;
} else if (prop === 'parentSuite') {
return this._parentSuite;
} else {
this._maybeDeprecate(target, prop);
return target[prop];
}
};
DeprecatingSuiteProxyHandler.prototype.set = function(target, prop, value) {
debugger;
this._maybeDeprecate(target, prop);
return (target[prop] = value);
};
DeprecatingSuiteProxyHandler.prototype._maybeDeprecate = function(
target,
prop
) {
if (isMember(target, prop) && !isAllowedMember(prop)) {
this._env.deprecated(msg(prop));
}
};
DeprecatingSuiteProxyHandler.prototype._proxyForChild = function(
ownProxy,
child
) {
if (child.children) {
return deprecatingSuiteProxy(child, ownProxy, this._env);
} else {
return j$.deprecatingSpecProxy(child, this._env);
}
};
function deprecatingSuiteProxy(suite, parentSuite, env) {
return new Proxy(suite, new DeprecatingSuiteProxyHandler(parentSuite, env));
}
return deprecatingSuiteProxy;
};

View File

@@ -45,6 +45,8 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.Deprecator = jRequire.Deprecator(j$);
j$.Env = jRequire.Env(j$);
j$.deprecatingThisProxy = jRequire.deprecatingThisProxy(j$);
j$.deprecatingSuiteProxy = jRequire.deprecatingSuiteProxy(j$);
j$.deprecatingSpecProxy = jRequire.deprecatingSpecProxy(j$);
j$.StackTrace = jRequire.StackTrace(j$);
j$.ExceptionFormatter = jRequire.ExceptionFormatter(j$);
j$.ExpectationFilterChain = jRequire.ExpectationFilterChain();