diff --git a/packages/import-bundle/src/compartment-wrapper.js b/packages/import-bundle/src/compartment-wrapper.js index b5bc57da75..3898a20e2f 100644 --- a/packages/import-bundle/src/compartment-wrapper.js +++ b/packages/import-bundle/src/compartment-wrapper.js @@ -42,11 +42,14 @@ export function wrapInescapableCompartment( // there are details to work out. c.globalThis.Compartment = NewCompartment; - for (const prop of Object.keys(inescapableGlobalProperties)) { + // Use Reflect.ownKeys, not Object.keys, because we want both + // string-named and symbol-named properties. Note that + // Reflect.ownKeys also includes non-enumerable keys. + for (const prop of Reflect.ownKeys(inescapableGlobalProperties)) { Object.defineProperty(c.globalThis, prop, { value: inescapableGlobalProperties[prop], writable: true, - enumerable: false, + enumerable: false, // TODO: really? why? configurable: true, }); } diff --git a/packages/import-bundle/test/compartment-wrapper.test.js b/packages/import-bundle/test/compartment-wrapper.test.js index beca267723..af45672a91 100644 --- a/packages/import-bundle/test/compartment-wrapper.test.js +++ b/packages/import-bundle/test/compartment-wrapper.test.js @@ -5,6 +5,10 @@ import { wrapInescapableCompartment } from '../src/compartment-wrapper.js'; const createChild = `() => new Compartment({console})`; +// simulate what pass-style wants to give a liveslots environment +const symbolEndowment = () => 0; +const endowmentSymbol = Symbol.for('endowmentSymbol'); + function check(t, c, n) { t.is(c.evaluate('Compartment.name'), 'Compartment', `${n}.Compartment.name`); @@ -21,11 +25,26 @@ function check(t, c, n) { t.is(c.evaluate('WeakMap'), 'replaced'); t.is(c.evaluate('globalThis.WeakMap'), 'replaced'); + t.is(c.evaluate('globalThis.unenumerable'), 'yep'); + t.is(c.evaluate(`globalThis[Symbol.for('endowmentSymbol')]`), symbolEndowment); } +// match what @endo/pass-style does, but note that import-bundle +// does/should not depend upon on pass-style in any way +// +// alternative: have one of pass-style and import-bundle have a +// devDependencies on the other (avoid a cycle, avoid strong/"normal" +// `dependencies`), to allow a more thorough test, which is currently +// only really exercised by the agoric-sdk/swingset-liveslots test + test('wrap', t => { const inescapableTransforms = []; - const inescapableGlobalProperties = { WeakMap: 'replaced' }; + const inescapableGlobalProperties = { + WeakMap: 'replaced', + [endowmentSymbol]: symbolEndowment, + }; + Object.defineProperty(inescapableGlobalProperties, 'unenumerable', + { value: 'yep', enumerable: false }); const WrappedCompartment = wrapInescapableCompartment( Compartment, inescapableTransforms,