Merge branch '3.99' into 4.0

This commit is contained in:
Steve Gravrock
2021-05-29 18:42:31 -07:00
20 changed files with 1695 additions and 240 deletions

90
src/core/Deprecator.js Normal file
View File

@@ -0,0 +1,90 @@
getJasmineRequireObj().Deprecator = function(j$) {
function Deprecator(topSuite) {
this.topSuite_ = topSuite;
this.verbose_ = false;
this.toSuppress_ = [];
}
var verboseNote =
'Note: This message will be shown only once. ' +
'Set config.verboseDeprecations to true to see every occurrence.';
Deprecator.prototype.verboseDeprecations = function(enabled) {
this.verbose_ = enabled;
};
// runnable is a spec or a suite.
// deprecation is a string or an Error.
// See Env#deprecated for a description of the options argument.
Deprecator.prototype.addDeprecationWarning = function(
runnable,
deprecation,
options
) {
options = options || {};
if (!this.verbose_ && !j$.isError_(deprecation)) {
if (this.toSuppress_.indexOf(deprecation) !== -1) {
return;
}
this.toSuppress_.push(deprecation);
}
this.log_(runnable, deprecation, options);
this.report_(runnable, deprecation, options);
};
Deprecator.prototype.log_ = function(runnable, deprecation, options) {
var context;
if (j$.isError_(deprecation)) {
console.error(deprecation);
return;
}
if (runnable === this.topSuite_ || options.ignoreRunnable) {
context = '';
} else if (runnable.children) {
context = ' (in suite: ' + runnable.getFullName() + ')';
} else {
context = ' (in spec: ' + runnable.getFullName() + ')';
}
if (!options.omitStackTrace) {
context += '\n' + this.stackTrace_();
}
if (!this.verbose_) {
context += '\n' + verboseNote;
}
console.error('DEPRECATION: ' + deprecation + context);
};
Deprecator.prototype.stackTrace_ = function() {
var formatter = new j$.ExceptionFormatter();
return formatter.stack(j$.util.errorWithStack()).replace(/^Error\n/m, '');
};
Deprecator.prototype.report_ = function(runnable, deprecation, options) {
if (options.ignoreRunnable) {
runnable = this.topSuite_;
}
if (j$.isError_(deprecation)) {
runnable.addDeprecationWarning(deprecation);
return;
}
if (!this.verbose_) {
deprecation += '\n' + verboseNote;
}
runnable.addDeprecationWarning({
message: deprecation,
omitStackTrace: options.omitStackTrace || false
});
};
return Deprecator;
};

View File

@@ -32,7 +32,6 @@ getJasmineRequireObj().Env = function(j$) {
var currentlyExecutingSuites = [];
var currentDeclarationSuite = null;
var hasFailures = false;
var deprecationsToSuppress = [];
/**
* This represents the available options to configure Jasmine.
@@ -228,6 +227,7 @@ getJasmineRequireObj().Env = function(j$) {
if (configuration.hasOwnProperty('verboseDeprecations')) {
config.verboseDeprecations = configuration.verboseDeprecations;
deprecator.verboseDeprecations(config.verboseDeprecations);
}
};
@@ -482,48 +482,31 @@ getJasmineRequireObj().Env = function(j$) {
return buildExpectationResult(attrs);
};
this.deprecated = function(deprecation) {
/**
* Causes a deprecation warning to be logged to the console and reported to
* reporters.
*
* The optional second parameter is an object that can have either of the
* following properties:
*
* omitStackTrace: Whether to omit the stack trace. Optional. Defaults to
* false. This option is ignored if the deprecation is an Error. Set this
* when the stack trace will not contain anything that helps the user find
* the source of the deprecation.
*
* ignoreRunnable: Whether to log the deprecation on the root suite, ignoring
* the spec or suite that's running when it happens. Optional. Defaults to
* false.
*
* @name Env#deprecated
* @since 2.99
* @function
* @param {String|Error} deprecation The deprecation message
* @param {Object} [options] Optional extra options, as described above
*/
this.deprecated = function(deprecation, options) {
var runnable = currentRunnable() || topSuite;
var context;
if (runnable === topSuite) {
context = '';
} else if (runnable === currentSuite()) {
context = ' (in suite: ' + runnable.getFullName() + ')';
} else {
context = ' (in spec: ' + runnable.getFullName() + ')';
}
runnable.addDeprecationWarning(deprecation);
if (
typeof console !== 'undefined' &&
typeof console.error === 'function'
) {
console.error('DEPRECATION: ' + deprecation + context);
}
};
this.deprecatedOnceWithStack = function(deprecation) {
var formatter = new j$.ExceptionFormatter(),
stackTrace = formatter
.stack(j$.util.errorWithStack())
.replace(/^Error\n/m, '');
if (config.verboseDeprecations) {
this.deprecated(deprecation + '\n' + stackTrace);
} else {
if (deprecationsToSuppress.indexOf(deprecation) === -1) {
this.deprecated(
deprecation +
'\n' +
'Note: This message will be shown only once. ' +
'Set config.verboseDeprecations to true to see every occurrence.\n' +
stackTrace
);
}
deprecationsToSuppress.push(deprecation);
}
deprecator.addDeprecationWarning(runnable, deprecation, options);
};
var queueRunnerFactory = function(options, args) {
@@ -559,6 +542,7 @@ getJasmineRequireObj().Env = function(j$) {
asyncExpectationFactory: suiteAsyncExpectationFactory,
expectationResultFactory: expectationResultFactory
});
var deprecator = new j$.Deprecator(topSuite);
defaultResourcesForRunnable(topSuite.id);
currentDeclarationSuite = topSuite;
@@ -570,7 +554,7 @@ getJasmineRequireObj().Env = function(j$) {
* @return {Suite} the root suite
*/
this.topSuite = function() {
return topSuite;
return j$.deprecatingSuiteProxy(topSuite, null, this);
};
/**

View File

@@ -16,7 +16,7 @@ getJasmineRequireObj().buildExpectationResult = function(j$) {
var result = {
matcherName: options.matcherName,
message: message(),
stack: stack(),
stack: options.omitStackTrace ? '' : stack(),
passed: options.passed
};

View File

@@ -215,8 +215,12 @@ getJasmineRequireObj().QueueRunner = function(j$) {
};
QueueRunner.prototype.diagnoseConflictingAsync_ = function(fn, retval) {
var msg;
if (retval && j$.isFunction_(retval.then)) {
// Issue a warning that matches the user's code
// Issue a warning that matches the user's code.
// Omit the stack trace because there's almost certainly no user code
// on the stack at this point.
if (j$.isAsyncFunction_(fn)) {
this.onException(
'An asynchronous before/it/after ' +
@@ -232,6 +236,8 @@ getJasmineRequireObj().QueueRunner = function(j$) {
'function to not return a promise.'
);
}
this.deprecated(msg, { omitStackTrace: true });
}
};

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

@@ -42,7 +42,10 @@ var getJasmineRequireObj = (function(jasmineGlobal) {
j$.getClearStack = jRequire.clearStack(j$);
j$.Clock = jRequire.Clock();
j$.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
j$.Deprecator = jRequire.Deprecator(j$);
j$.Env = jRequire.Env(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();