Add more tests to ShadowRealms

Ref #3044
This commit is contained in:
Leo Balter 2021-09-13 15:51:49 -07:00 committed by Rick Waldron
parent 30eca7761b
commit 6a5b818896
6 changed files with 210 additions and 9 deletions

View File

@ -28,3 +28,6 @@ assert.sameValue(
ShadowRealm.prototype,
'[[Prototype]] is set to %ShadowRealm.prototype%'
);
var otherRealm = new ShadowRealm();
assert.notSameValue(realm, otherRealm, 'each instance is different');

View File

@ -0,0 +1,31 @@
// 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: >
ShadowRealm can create a nested ShadowRealm
features: [ShadowRealm]
---*/
globalThis.myValue = 'a';
const realm1 = new ShadowRealm();
realm1.evaluate('globalThis.myValue = "b";');
const realm2Evaluate = realm1.evaluate(`
const realm2 = new ShadowRealm();
(str) => realm2.evaluate(str);
`);
realm2Evaluate('globalThis.myValue = "c";');
assert.sameValue(globalThis.myValue, 'a');
assert.sameValue(realm1.evaluate('globalThis.myValue'), 'b');
assert.sameValue(realm2Evaluate('globalThis.myValue'), 'c');
realm1.evaluate('globalThis.myValue = "d"');
assert.sameValue(globalThis.myValue, 'a', 'no side effects');
assert.sameValue(realm1.evaluate('globalThis.myValue'), 'd', 'no side effects');
assert.sameValue(realm2Evaluate('globalThis.myValue'), 'c', 'no side effects');

View File

@ -14,10 +14,36 @@ assert.sameValue(
);
const r = new ShadowRealm();
const s = r.evaluate('Symbol()');
const s = r.evaluate('Symbol("foobar")');
assert.sameValue(typeof s, 'symbol');
assert.sameValue(s.constructor, Symbol, 'primitive does not expose other ShadowRealm constructor');
assert.sameValue(Object.getPrototypeOf(s), Symbol.prototype);
assert.sameValue(r.evaluate('Symbol.for("x")'), Symbol.for('x'));
assert.sameValue(Symbol.prototype.toString.call(s), 'Symbol()');
const shadowX = r.evaluate('Symbol.for("my symbol name")');
const myX = Symbol.for('my symbol name')
assert.sameValue(
shadowX,
myX,
'The shadow realms observes the symbol global registry used in Symbol.for'
);
assert.sameValue(
Symbol.keyFor(shadowX),
'my symbol name',
'Symbol.keyFor observes the string key name of a symbol originally registered in the shadow realm'
);
assert.sameValue(
Symbol.keyFor(s),
undefined,
'Symbol.keyFor cannot find a key for a regular symbol created in the shadow realm'
);
assert.sameValue(
Symbol.prototype.description.call(s),
'foobar',
'get description for the symbol created in the shadow realm'
);

View File

@ -0,0 +1,50 @@
// 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: >
ShadowRealm can wrap a function to multiple nested realms.
features: [ShadowRealm]
---*/
globalThis.count = 0;
const realm1 = new ShadowRealm();
const r1wrapped = realm1.evaluate(`
globalThis.count = 0;
() => globalThis.count += 1;
`);
const realm2Evaluate = realm1.evaluate(`
const realm2 = new ShadowRealm();
(str) => realm2.evaluate(str);
`);
const r2wrapper = realm2Evaluate(`
globalThis.wrapped = undefined;
globalThis.count = 0; // Bait
(fn) => globalThis.wrapped = fn;
`);
const rewrapped = r2wrapper(r1wrapped);
assert.notSameValue(rewrapped, r1wrapped, 'rewrapped !== r1wrapped');
const r2wrapped = realm2Evaluate('globalThis.wrapped');
assert.notSameValue(r2wrapped, r1wrapped, 'r2wrapped !== r1wrapped');
assert.notSameValue(r2wrapped, rewrapped, 'r2wrapped !== rewrapped');
assert.sameValue(realm1.evaluate('globalThis.count'), 0, `getting wrapped function won't trigger a call`);
assert.sameValue(r2wrapped(), 1, 'call from r2 wrapped (r2wrapped) cycles back to r1');
assert.sameValue(realm1.evaluate('globalThis.count'), 1, 'effects produced in a third realm, #1');
assert.sameValue(rewrapped(), 2, 'call from r2 wrapped (rewrapped) cycles back to r1');
assert.sameValue(realm1.evaluate('globalThis.count'), 2, 'effects produced in a third realm, #2');
assert.sameValue(realm2Evaluate('globalThis.count'), 0, 'no side effects produced in the wrong realm (realm2)');
assert.sameValue(globalThis.count, 0, 'no side effects produced in the wrong realm (main realm)');

View File

@ -0,0 +1,48 @@
// 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: >
ShadowRealm can wrap a function to multiple realms.
features: [ShadowRealm]
---*/
const realm1 = new ShadowRealm();
const realm2 = new ShadowRealm();
globalThis.count = 0;
asserts.notSameValue(realm1, realm2);
const r1wrapped = realm1.evaluate(`
globalThis.count = 0;
() => globalThis.count += 1;
`);
const r2wrapper = realm2.evaluate(`
globalThis.wrapped = undefined;
globalThis.count = 0; // Bait
(fn) => globalThis.wrapped = fn;
`);
const rewrapped = r2wrapper(r1wrapped);
assert.notSameValue(rewrapped, r1wrapped, 'rewrapped !== r1wrapped');
const r2wrapped = realm2.evaluate('globalThis.wrapped');
assert.notSameValue(r2wrapped, r1wrapped, 'r2wrapped !== r1wrapped');
assert.notSameValue(r2wrapped, rewrapped, 'r2wrapped !== rewrapped');
assert.sameValue(realm1.evaluate('globalThis.count'), 0, `getting wrapped function won't trigger a call`);
assert.sameValue(r2wrapped(), 1, 'call from r2 wrapped (r2wrapped) cycles back to r1');
assert.sameValue(realm1.evaluate('globalThis.count'), 1, 'effects produced in a third realm, #1');
assert.sameValue(rewrapped(), 2, 'call from r2 wrapped (rewrapped) cycles back to r1');
assert.sameValue(realm1.evaluate('globalThis.count'), 2, 'effects produced in a third realm, #2');
assert.sameValue(realm2.evaluate('globalThis.count'), 0, 'no side effects produced in the wrong realm (realm2)');
assert.sameValue(globalThis.count, 0, 'no side effects produced in the wrong realm (main realm)');

View File

@ -16,15 +16,58 @@ assert.sameValue(
const r = new ShadowRealm();
let count = 0;
const specifier = {
toString() {
count += 1;
throw new Test262Error();
}
const specifier = Object.create(null);
// A - valueOF
specifier.valueOf = function() {
count += 1;
throw new Test262Error();
};
assert.throws(Test262Error, () => {
r.importValue(specifier);
});
}, 'ToString(specifier) returns abrupt from valueOf');
assert.sameValue(count, 1);
assert.sameValue(count, 1, 'ToString calls the valueOf method');
// B - toString
count = 0;
specifier.valueOf = function() {
count += 1000;
throw new Error('valueOf is not reached if toString is present');
};
specifier.toString = function() {
count += 1;
throw new Test262Error();
};
assert.throws(Test262Error, () => {
r.importValue(specifier);
}, 'ToString(specifier) returns abrupt from toString');
assert.sameValue(count, 1, 'ToString calls the toString method');
// C - @@toPrimitive
count = 0;
specifier[Symbol.toPrimitive] = function() {
count += 1;
throw new Test262Error();
};
specifier.toString = function() {
count += 1000;
throw new Error('toString is not reached if @@toPrimitive is present');
};
assert.throws(Test262Error, () => {
r.importValue(specifier);
}, 'ToString(specifier) returns abrupt from @@toPrimitive');
assert.sameValue(count, 1, 'ToString calls the @@toPrimitive method');