From 8ff255a5ec5d2a5a33f8f070fba497302eeeb9ec Mon Sep 17 00:00:00 2001 From: Leo Balter Date: Tue, 12 Oct 2021 15:02:48 -0700 Subject: [PATCH] Add tests for ShadowRealm globalThis --- .../globalthis-available-properties.js | 105 ++++++++++++++++++ .../globalthis-config-only-properties.js | 98 ++++++++++++++++ .../evaluate/globalthis-orginary-object.js | 66 +++++++++++ 3 files changed, 269 insertions(+) create mode 100644 test/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js create mode 100644 test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js create mode 100644 test/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js diff --git a/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js new file mode 100644 index 0000000000..f6d0fc0f6f --- /dev/null +++ b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-available-properties.js @@ -0,0 +1,105 @@ +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The ShadowRealm global must include ECMAScript global properties +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + SetDefaultGlobalBindings ( realmRec ) + + 1. Let global be realmRec.[[GlobalObject]]. + 2. For each property of the Global Object specified in clause 19, do + a. Let name be the String value of the property name. + b. Let desc be the fully populated data Property Descriptor for the property, containing the specified attributes for the property. For properties listed in 19.2, 19.3, or 19.4 the value of the [[Value]] attribute is the corresponding intrinsic object from realmRec. + c. Perform ? DefinePropertyOrThrow(global, name, desc). + 3. Return global. +features: [ShadowRealm] +includes: [compareArray.js] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const properties = [ + 'globalThis', + 'Infinity', + 'NaN', + 'undefined', + 'eval', + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + 'AggregateError', + 'Array', + 'ArrayBuffer', + 'BigInt', + 'BigInt64Array', + 'BigUint64Array', + 'Boolean', + 'DataView', + 'Date', + 'Error', + 'EvalError', + 'FinalizationRegistry', + 'Float32Array', + 'Float64Array', + 'Function', + 'Int8Array', + 'Int16Array', + 'Int32Array', + 'Map', + 'Number', + 'Object', + 'Promise', + 'Proxy', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'Set', + 'SharedArrayBuffer', + 'String', + 'Symbol', + 'SyntaxError', + 'TypeError', + 'Uint8Array', + 'Uint8ClampedArray', + 'Uint16Array', + 'Uint32Array', + 'URIError', + 'WeakMap', + 'WeakRef', + 'WeakSet', + 'Atomics', + 'JSON', + 'Math', + 'Reflect', +]; + +const available = properties.filter(name => { + // This test is intentionally not using wrapped functions. + // This test should not depend on wrapped functions. + return r.evaluate(`Object.prototype.hasOwnProperty.call(globalThis, '${name}')`); +}); + +// This comparison is intentional to list difference in names if the the assertion fails +assert.compareArray(properties, available); diff --git a/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js new file mode 100644 index 0000000000..c126668e99 --- /dev/null +++ b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-config-only-properties.js @@ -0,0 +1,98 @@ +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + Properties of globalThis must be configurable +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + Runtime Semantics: HostInitializeShadowRealm ( realm ) + + HostInitializeShadowRealm is an implementation-defined abstract operation + used to inform the host of any newly created realms from the ShadowRealm + constructor. Its return value is not used, though it may throw an exception. + The idea of this hook is to initialize host data structures related to the + ShadowRealm, e.g., for module loading. + + The host may use this hook to add properties to the ShadowRealm's global + object. Those properties must be configurable. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +const anyMissed = r.evaluate(` + // These names are the only exception as non configurable values. + // Yet, they don't represent any object value. + const esNonConfigValues = [ + 'undefined', + 'Infinity', + 'NaN' + ]; + + const entries = Object.entries(Object.getOwnPropertyDescriptors(globalThis)); + + const missed = entries + .filter(entry => entry[1].configurable === false) + .map(([name]) => name) + .filter(name => !esNonConfigValues.includes(name)) + .join(', '); + + missed; +`); + +assert.sameValue(anyMissed, '', 'All globalThis properties must be configurable'); + +const result = r.evaluate(` + const ObjectKeys = Object.keys; + const hasOwn = Object.prototype.hasOwnProperty; + const savedGlobal = globalThis; + const names = Object.keys(Object.getOwnPropertyDescriptors(globalThis)); + + // These names are the only exception as non configurable values. + // Yet, they don't represent any object value. + const esNonConfigValues = [ + 'undefined', + 'Infinity', + 'NaN' + ]; + + // Delete every name except globalThis, for now + names.filter(name => { + if (esNonConfigValues.includes(name)) { + return false; + } + + if (name !== 'globalThis') { + delete globalThis[name]; + return hasOwn.call(globalThis, name); + } + }); + + delete globalThis['globalThis']; + + if (hasOwn.call(savedGlobal, 'globalThis')) { + names.push('globalThis'); + } + + const failedDelete = names.join(', '); + + failedDelete; +`); + +assert.sameValue(result, '', 'deleting any globalThis property must be effective'); diff --git a/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js new file mode 100644 index 0000000000..fd71e91026 --- /dev/null +++ b/test/built-ins/ShadowRealm/prototype/evaluate/globalthis-orginary-object.js @@ -0,0 +1,66 @@ +// Copyright (C) 2021 Leo Balter. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-shadowrealm.prototype.evaluate +description: > + The globalThis must be an ordinary object from OrdinaryObjectCreate +info: | + ShadowRealm ( ) + + ... + 3. Let realmRec be CreateRealm(). + 4. Set O.[[ShadowRealm]] to realmRec. + ... + 10. Perform ? SetRealmGlobalObject(realmRec, undefined, undefined). + 11. Perform ? SetDefaultGlobalBindings(O.[[ShadowRealm]]). + 12. Perform ? HostInitializeShadowRealm(O.[[ShadowRealm]]). + + SetRealmGlobalObject ( realmRec, globalObj, thisValue ) + + 1. If globalObj is undefined, then + a. Let intrinsics be realmRec.[[Intrinsics]]. + b. Set globalObj to ! OrdinaryObjectCreate(intrinsics.[[%Object.prototype%]]). + 2. Assert: Type(globalObj) is Object. + 3. If thisValue is undefined, set thisValue to globalObj. + ... + + OrdinaryObjectCreate ( proto [ , additionalInternalSlotsList ] ) + + 1. Let internalSlotsList be « [[Prototype]], [[Extensible]] ». + 2. If additionalInternalSlotsList is present, append each of its elements to internalSlotsList. + 3. Let O be ! MakeBasicObject(internalSlotsList). + 4. Set O.[[Prototype]] to proto. + 5. Return O. + + MakeBasicObject ( internalSlotsList ) + + ... + 5. If internalSlotsList contains [[Extensible]], set obj.[[Extensible]] to true. +features: [ShadowRealm] +---*/ + +assert.sameValue( + typeof ShadowRealm.prototype.evaluate, + 'function', + 'This test must fail if ShadowRealm.prototype.evaluate is not a function' +); + +const r = new ShadowRealm(); + +assert.sameValue( + r.evaluate('Object.getPrototypeOf(globalThis) === Object.prototype'), + true, + 'The [[Prototype]] of globalThis is Object.prototype' +); + +assert.sameValue( + r.evaluate('Object.isExtensible(globalThis)'), + true, + 'globalThis is extensible' +); + +assert.sameValue( + r.evaluate('globalThis.constructor === Object'), + true, + 'globalThis.constructor is Object' +);