blob: 01700bac88ccfdadec0ad9b9af767f48c2f4d5cf [file] [log] [blame]
"use strict";
const testValue = Object.freeze({});
function assert(x, key) {
if (!x)
throw new Error(`Key: "${key}". Bad assertion!`);
}
function shouldThrow(func, errorMessage, key) {
let errorThrown = false;
try {
func();
} catch (error) {
errorThrown = true;
if (String(error) !== errorMessage)
throw new Error(`Key: "${key}". Bad error: ${error}`);
}
if (!errorThrown)
throw new Error(`Key: "${key}". Didn't throw!`);
}
function* testCases() {
// hasSetterOrReadonlyProperties: false
for (const key of ["isFinite", "eval", "globalThis", "parseInt", "EvalError", "JSON", "Uint8ClampedArray", "WeakMap"])
yield [$vm.createGlobalObject(), key];
for (const key of ["seal", "is", "values", "fromEntries", "defineProperty", "setPrototypeOf"])
yield [$vm.createGlobalObject().Object, key];
for (const key of ["apply", "construct", "has", "preventExtensions", "getPrototypeOf"])
yield [$vm.createGlobalObject().Reflect, key];
for (const key of ["toDateString", "toLocaleString", "getUTCMonth", "getDay", "setUTCMinutes", "setMonth"])
yield [$vm.createGlobalObject().Date.prototype, key];
for (const key of ["concat", "match", "padStart", "bold", "fixed", "small", "sub"])
yield [$vm.createGlobalObject().String.prototype, key];
// hasSetterOrReadonlyProperties: true
for (const key of ["getUint16", "setInt8", "getFloat32", "setBigUint64"])
yield [$vm.createGlobalObject().DataView.prototype, key];
for (const key of ["toString", "valueOf"])
yield [$vm.createGlobalObject().Symbol.prototype, key];
for (const key of ["formatRange", "formatToParts", "resolvedOptions"])
yield [$vm.createGlobalObject().Intl.DateTimeFormat.prototype, key];
for (const key of ["formatToParts", "resolvedOptions"])
yield [$vm.createGlobalObject().Intl.NumberFormat.prototype, key];
for (const key of ["maximize", "minimize", "toString"])
yield [$vm.createGlobalObject().Intl.Locale.prototype, key];
yield [$vm.createStaticCustomValue(), "testStaticValueNoSetter"];
}
for (const [object, key] of testCases()) {
object[key] = testValue;
const desc = Object.getOwnPropertyDescriptor(object, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(!desc.enumerable, key);
assert(desc.configurable, key);
}
for (const [object, key] of testCases()) {
Object.preventExtensions(object);
object[key] = testValue;
const desc = Object.getOwnPropertyDescriptor(object, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(!desc.enumerable, key);
assert(desc.configurable, key);
}
for (const [object, key] of testCases()) {
Object.defineProperty(object, key, { enumerable: true, configurable: false });
object[key] = testValue;
const desc = Object.getOwnPropertyDescriptor(object, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(desc.enumerable, key);
assert(!desc.configurable, key);
}
for (const [object, key] of testCases()) {
Object.defineProperty(object, key, { writable: false });
shouldThrow(() => { object[key] = testValue; }, "TypeError: Attempted to assign to readonly property.", key);
const desc = Object.getOwnPropertyDescriptor(object, key);
assert(desc.value !== testValue, key);
assert(!desc.writable, key);
assert(!desc.enumerable, key);
assert(desc.configurable, key);
}
for (const [object, key] of testCases()) {
const heir = Object.create(object);
heir[key] = testValue;
const desc = Object.getOwnPropertyDescriptor(heir, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(desc.enumerable, key);
assert(desc.configurable, key);
assert(object[key] !== testValue, key);
}
for (const [object, key] of testCases()) {
const prototype = Object.getPrototypeOf(object);
if (prototype !== null) {
Object.defineProperty(prototype, key, {
set() { throw new Error(`"${key}" setter should be unreachable!`); },
});
}
const heir = Object.create(object);
heir[key] = testValue;
const desc = Object.getOwnPropertyDescriptor(heir, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(desc.enumerable, key);
assert(desc.configurable, key);
assert(object[key] !== testValue, key);
}
for (const [object, key] of testCases()) {
const heir = Object.create(object);
Object.preventExtensions(heir);
shouldThrow(() => { heir[key] = testValue; }, "TypeError: Attempting to define property on object that is not extensible.", key);
assert(heir[key] !== testValue, key);
assert(object[key] !== testValue, key);
}
for (const [object, key] of testCases()) {
const target = {};
assert(Reflect.set(target, key, testValue, object), key);
assert(!target.hasOwnProperty(key), key);
const desc = Object.getOwnPropertyDescriptor(object, key);
assert(desc.value === testValue, key);
assert(desc.writable, key);
assert(!desc.enumerable, key);
assert(desc.configurable, key);
}