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.
156 lines
4.3 KiB
JavaScript
156 lines
4.3 KiB
JavaScript
describe('The jasmine namespace', function() {
|
|
it('includes all expected properties', function() {
|
|
const actualKeys = new Set(Object.keys(jasmineUnderTest));
|
|
// toEqual doesn't generate diffs for set comparisons. Check this way
|
|
// instead so we get readable failure output.
|
|
expect(setDifference(expectedKeys(), actualKeys)).toEqual(new Set());
|
|
});
|
|
|
|
it('does not include any unexpected properties', function() {
|
|
const actualKeys = new Set(Object.keys(jasmineUnderTest));
|
|
// toEqual doesn't generate diffs for set comparisons. Check this way
|
|
// instead so we get readable failure output.
|
|
expect(setDifference(actualKeys, expectedKeys())).toEqual(new Set());
|
|
});
|
|
|
|
describe('Warning about monkey patching', function() {
|
|
beforeEach(function() {
|
|
spyOn(console, 'error');
|
|
});
|
|
|
|
for (const key of expectedKeys(false)) {
|
|
if (!key.startsWith('MAX_') && key !== 'private' && key !== 'getEnv') {
|
|
describe(`jasmine.${key}`, function() {
|
|
let orig;
|
|
|
|
beforeEach(function() {
|
|
orig = jasmineUnderTest[key];
|
|
});
|
|
|
|
afterEach(function() {
|
|
jasmineUnderTest[key] = orig;
|
|
});
|
|
|
|
it('warns if monkey patched', function() {
|
|
const patch = {};
|
|
jasmineUnderTest[key] = patch;
|
|
|
|
verifyDeprecation();
|
|
expect(jasmineUnderTest[key]).toBe(patch);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
// These specs rely on jasmineRequire being exposed. That only happens
|
|
// in browsers.
|
|
if (typeof document !== 'undefined') {
|
|
const statics = ['addMatchers', 'clock', 'createSpyObj'];
|
|
|
|
for (const name of statics) {
|
|
describe(`jasmine.${name}`, function() {
|
|
let bootedCore, env, orig;
|
|
|
|
beforeEach(function() {
|
|
bootedCore = jasmineRequire.core(jasmineRequire);
|
|
env = bootedCore.getEnv();
|
|
jasmineRequire.interface(bootedCore, env);
|
|
orig = bootedCore[name];
|
|
});
|
|
|
|
afterEach(function() {
|
|
bootedCore[name] = orig;
|
|
env.cleanup_();
|
|
});
|
|
|
|
it(`warns if jasmine.${name} is monkey patched`, function() {
|
|
const patch = {};
|
|
bootedCore[name] = patch;
|
|
|
|
verifyDeprecation();
|
|
expect(bootedCore[name]).toBe(patch);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
});
|
|
|
|
function expectedKeys(includeHtml) {
|
|
if (includeHtml === undefined) {
|
|
includeHtml = typeof window !== 'undefined';
|
|
}
|
|
// Does not include properties added by requireInterface(), since that isn't
|
|
// called by defineJasmineUnderTest.js/nodeDefineJasmineUnderTest.js.
|
|
const result = new Set([
|
|
'MAX_PRETTY_PRINT_ARRAY_LENGTH',
|
|
'MAX_PRETTY_PRINT_CHARS',
|
|
'MAX_PRETTY_PRINT_DEPTH',
|
|
'debugLog',
|
|
'getEnv',
|
|
'isSpy',
|
|
'ParallelReportDispatcher',
|
|
'private',
|
|
'spyOnGlobalErrorsAsync',
|
|
'Timer',
|
|
'version',
|
|
|
|
// Asymmetric equality testers
|
|
'allOf',
|
|
'any',
|
|
'anything',
|
|
'arrayContaining',
|
|
'arrayWithExactContents',
|
|
'empty',
|
|
'falsy',
|
|
'is',
|
|
'mapContaining',
|
|
'notEmpty',
|
|
'objectContaining',
|
|
'setContaining',
|
|
'stringContaining',
|
|
'stringMatching',
|
|
'truthy',
|
|
|
|
// Currently undocumented but used in browser boot files, so it's
|
|
// effectively public
|
|
'getGlobal'
|
|
]);
|
|
|
|
if (includeHtml) {
|
|
// jasmine-html.js
|
|
result.add('HtmlReporter');
|
|
result.add('HtmlReporterV2');
|
|
result.add('HtmlReporterV2Urls');
|
|
result.add('HtmlSpecFilter');
|
|
result.add('QueryString');
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Can't use Set#difference yet because it isn't available in Node <22,
|
|
// Firefox <108, or Safari <17.
|
|
function setDifference(a, b) {
|
|
const result = new Set();
|
|
|
|
for (const v of a) {
|
|
if (!b.has(v)) {
|
|
result.add(v);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
function verifyDeprecation() {
|
|
// eslint-disable-next-line no-console
|
|
expect(console.error).toHaveBeenCalledOnceWith(
|
|
jasmine.stringContaining('DEPRECATION: Monkey patching detected.')
|
|
);
|
|
// eslint-disable-next-line no-console
|
|
expect(console.error).toHaveBeenCalledOnceWith(
|
|
jasmine.stringContaining('jasmineNamespaceSpec.js')
|
|
);
|
|
}
|
|
});
|