Detect monkey patching and emit a deprecation warning.
This isn't comprehensive but it should be broad enough to ensure that most people who would be affected by blocking monkey patching see a warning. Covers the jasmine namespace as well as classes that are monkey patched by zone.js. Replacing globals (describe/it/etc) doesn't trigger a warning because they belong to the user and are expected to be replaced.
This commit is contained in:
@@ -309,12 +309,14 @@ jasmineRequire.HtmlSpecFilter = function(j$) {
|
||||
* @deprecated Use {@link HtmlReporterV2Urls} instead.
|
||||
*/
|
||||
function HtmlSpecFilter(options) {
|
||||
j$.getEnv().deprecated(
|
||||
const env = options?.env ?? j$.getEnv();
|
||||
env.deprecated(
|
||||
'HtmlReporter and HtmlSpecFilter are deprecated. Use HtmlReporterV2 instead.'
|
||||
);
|
||||
|
||||
const filterString =
|
||||
options &&
|
||||
options.filterString &&
|
||||
options.filterString() &&
|
||||
options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
const filterPattern = new RegExp(filterString);
|
||||
|
||||
@@ -44,9 +44,14 @@ var getJasmineRequireObj = (function() {
|
||||
}
|
||||
|
||||
getJasmineRequire().core = function(jRequire) {
|
||||
const j$ = { private: {} };
|
||||
const j$ = {};
|
||||
Object.defineProperty(j$, 'private', {
|
||||
enumerable: true,
|
||||
value: {}
|
||||
});
|
||||
|
||||
jRequire.base(j$, globalThis);
|
||||
j$.private.deprecateMonkeyPatching = jRequire.deprecateMonkeyPatching(j$);
|
||||
j$.private.util = jRequire.util(j$);
|
||||
j$.private.errors = jRequire.errors();
|
||||
j$.private.formatErrorMsg = jRequire.formatErrorMsg(j$);
|
||||
@@ -56,7 +61,7 @@ var getJasmineRequireObj = (function() {
|
||||
j$.private.CallTracker = jRequire.CallTracker(j$);
|
||||
j$.private.MockDate = jRequire.MockDate(j$);
|
||||
j$.private.getStackClearer = jRequire.StackClearer(j$);
|
||||
j$.private.Clock = jRequire.Clock();
|
||||
j$.private.Clock = jRequire.Clock(j$);
|
||||
j$.private.DelayedFunctionScheduler = jRequire.DelayedFunctionScheduler(j$);
|
||||
j$.private.Deprecator = jRequire.Deprecator(j$);
|
||||
j$.private.Configuration = jRequire.Configuration(j$);
|
||||
@@ -122,6 +127,20 @@ var getJasmineRequireObj = (function() {
|
||||
j$.private.loadedAsBrowserEsm =
|
||||
globalThis.document && !globalThis.document.currentScript;
|
||||
|
||||
j$.private.deprecateMonkeyPatching(j$, [
|
||||
// These are meant to be set by users.
|
||||
'DEFAULT_TIMEOUT_INTERVAL',
|
||||
'MAX_PRETTY_PRINT_ARRAY_LENGTH',
|
||||
'MAX_PRETTY_PRINT_CHARS',
|
||||
'MAX_PRETTY_PRINT_DEPTH',
|
||||
|
||||
// These are part of the deprecation warning mechanism. To avoid infinite
|
||||
// recursion, they're separately protected in a way that doesn't emit
|
||||
// deprecation warnings.
|
||||
'private',
|
||||
'getEnv'
|
||||
]);
|
||||
|
||||
return j$;
|
||||
};
|
||||
|
||||
@@ -246,12 +265,15 @@ getJasmineRequireObj().base = function(j$, jasmineGlobal) {
|
||||
* @function
|
||||
* @return {Env}
|
||||
*/
|
||||
j$.getEnv = function(options) {
|
||||
const env = (j$.private.currentEnv_ =
|
||||
j$.private.currentEnv_ || new j$.private.Env(options));
|
||||
//jasmine. singletons in here (setTimeout blah blah).
|
||||
return env;
|
||||
};
|
||||
Object.defineProperty(j$, 'getEnv', {
|
||||
enumerable: true,
|
||||
value: function(options) {
|
||||
const env = (j$.private.currentEnv_ =
|
||||
j$.private.currentEnv_ || new j$.private.Env(options));
|
||||
//jasmine. singletons in here (setTimeout blah blah).
|
||||
return env;
|
||||
}
|
||||
});
|
||||
|
||||
j$.private.isArray = function(value) {
|
||||
return j$.private.isA('Array', value);
|
||||
@@ -1520,10 +1542,13 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
* @param {String|Error} deprecation The deprecation message
|
||||
* @param {Object} [options] Optional extra options, as described above
|
||||
*/
|
||||
this.deprecated = function(deprecation, options) {
|
||||
const runable = runner.currentRunable() || topSuite;
|
||||
deprecator.addDeprecationWarning(runable, deprecation, options);
|
||||
};
|
||||
Object.defineProperty(this, 'deprecated', {
|
||||
enumerable: true,
|
||||
value: function(deprecation, options) {
|
||||
const runable = runner.currentRunable() || topSuite;
|
||||
deprecator.addDeprecationWarning(runable, deprecation, options);
|
||||
}
|
||||
});
|
||||
|
||||
function runQueue(options) {
|
||||
options.clearStack = options.clearStack || stackClearer;
|
||||
@@ -1550,7 +1575,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
runQueue
|
||||
});
|
||||
topSuite = suiteBuilder.topSuite;
|
||||
const deprecator = new j$.private.Deprecator(topSuite);
|
||||
const deprecator =
|
||||
envOptions?.deprecator ?? new j$.private.Deprecator(topSuite);
|
||||
|
||||
/**
|
||||
* Provides the root suite, through which all suites and specs can be
|
||||
@@ -2055,6 +2081,8 @@ getJasmineRequireObj().Env = function(j$) {
|
||||
this.cleanup_ = function() {
|
||||
uninstallGlobalErrors();
|
||||
};
|
||||
|
||||
j$.private.deprecateMonkeyPatching(this, ['deprecated']);
|
||||
}
|
||||
|
||||
function indirectCallerFilename(depth) {
|
||||
@@ -2927,7 +2955,7 @@ getJasmineRequireObj().CallTracker = function(j$) {
|
||||
return CallTracker;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().Clock = function() {
|
||||
getJasmineRequireObj().Clock = function(j$) {
|
||||
'use strict';
|
||||
|
||||
/* global process */
|
||||
@@ -3120,6 +3148,9 @@ callbacks to execute _before_ running the next one.
|
||||
clearTimeout[IsMockClockTimingFn] = true;
|
||||
setInterval[IsMockClockTimingFn] = true;
|
||||
clearInterval[IsMockClockTimingFn] = true;
|
||||
|
||||
j$.private.deprecateMonkeyPatching(this);
|
||||
|
||||
return this;
|
||||
|
||||
// Advances the Clock's time until the mode changes.
|
||||
@@ -3828,6 +3859,29 @@ getJasmineRequireObj().DelayedFunctionScheduler = function(j$) {
|
||||
return DelayedFunctionScheduler;
|
||||
};
|
||||
|
||||
getJasmineRequireObj().deprecateMonkeyPatching = function(j$) {
|
||||
return function deprecateMonkeyPatching(obj, keysToSkip) {
|
||||
for (const key of Object.keys(obj)) {
|
||||
if (!keysToSkip?.includes(key)) {
|
||||
let value = obj[key];
|
||||
|
||||
Object.defineProperty(obj, key, {
|
||||
enumerable: key in obj,
|
||||
get() {
|
||||
return value;
|
||||
},
|
||||
set(newValue) {
|
||||
j$.getEnv().deprecated(
|
||||
'Monkey patching detected. This is not supported and will break in a future jasmine-core release.'
|
||||
);
|
||||
value = newValue;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
getJasmineRequireObj().Deprecator = function(j$) {
|
||||
'use strict';
|
||||
|
||||
@@ -9378,6 +9432,7 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
*/
|
||||
jasmine: jasmine
|
||||
};
|
||||
const existingKeys = Object.keys(jasmine);
|
||||
|
||||
/**
|
||||
* Add a custom equality tester for the current scope of specs.
|
||||
@@ -9544,6 +9599,8 @@ getJasmineRequireObj().interface = function(jasmine, env) {
|
||||
* @namespace asymmetricEqualityTesters
|
||||
*/
|
||||
|
||||
jasmine.private.deprecateMonkeyPatching(jasmine, existingKeys);
|
||||
|
||||
return jasmineInterface;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user