63ac7da082
This doesn't affect globals (describe, it, expect, etc). Those belong to the user and Jasmine doesn't depend on them.
68 lines
1.8 KiB
JavaScript
68 lines
1.8 KiB
JavaScript
globalThis.isNonMonkeyPatchableClass = function(ctor, makeInstance) {
|
|
describe('Monkey patching prevention', function() {
|
|
it(`prevents overwriting ${ctor.name}.prototype`, function() {
|
|
const existing = ctor.prototype;
|
|
|
|
try {
|
|
ctor.prototype = {};
|
|
expect(ctor.prototype).toBe(existing);
|
|
} finally {
|
|
// This will be a no-op if the test passed, but will prevent state
|
|
// leakage if it failed.
|
|
ctor.prototype = existing;
|
|
}
|
|
});
|
|
|
|
it("prevents overwriting an instance's prototype", function() {
|
|
const instance = makeInstance();
|
|
let thrown;
|
|
|
|
// The message varies from browser to browser, so we can't rely on it
|
|
try {
|
|
instance.__proto__ = {};
|
|
} catch (e) {
|
|
thrown = e;
|
|
}
|
|
|
|
expect(thrown).toBeInstanceOf(TypeError);
|
|
});
|
|
|
|
it('prevents overwriting prototype properties', function() {
|
|
let any = false;
|
|
|
|
for (const k of Object.getOwnPropertyNames(ctor.prototype)) {
|
|
any = true;
|
|
const existingValue = ctor.prototype[k];
|
|
|
|
try {
|
|
ctor.prototype[k] = {};
|
|
expect(ctor.prototype[k])
|
|
.withContext(k)
|
|
.toBe(existingValue);
|
|
} finally {
|
|
// This will be a no-op if the test passed, but will prevent state
|
|
// leakage if it failed.
|
|
ctor.prototype[k] = existingValue;
|
|
}
|
|
}
|
|
|
|
expect(any).toBe(true);
|
|
});
|
|
|
|
it('prevents overriding prototype properties', function() {
|
|
const instance = makeInstance();
|
|
let any = false;
|
|
|
|
for (const k of Object.getOwnPropertyNames(ctor.prototype)) {
|
|
any = true;
|
|
instance[k] = {};
|
|
expect(instance[k])
|
|
.withContext(k)
|
|
.toBe(ctor.prototype[k]);
|
|
}
|
|
|
|
expect(any).toBe(true);
|
|
});
|
|
});
|
|
};
|