test(compartment-mapper): Test compartment map retention
ADD
packages/compartment-mapper/test/fixtures-retained/README.md
+This fixture exists to demonstrate the behavior of `makeArchive` when a package
+exists but no module exists to retain it in the archive's compartment map.

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/app/app.js
+export * from 'mk1';

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/app/package.json
+{
+ "name": "app",
+ "version": "1.0.0",
+ "type": "module",
+ "dependencies": {
+ "mk1": "^1.0.0",
+ "sweep": "^1.0.0"
+ }
+}

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/mk1/package.json
+{
+ "name": "mk1",
+ "version": "1.0.0",
+ "type": "module",
+ "exports": {
+ ".": "mk2"
+ },
+ "dependencies": {
+ "mk2": "^1.0.0"
+ }
+}

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/mk2/mark.js
+export const mark = 42;

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/mk2/package.json
+{
+ "name": "mk2",
+ "version": "1.0.0",
+ "type": "module",
+ "exports": {
+ ".": "./mark.js"
+ }
+}
+

ADD
packages/compartment-mapper/test/fixtures-retained/node_modules/sweep/package.json
+{
+ "name": "sweep",
+ "version": "1.0.0",
+ "type": "module",
+ "exports": {}
+}

ADD
packages/compartment-mapper/test/test-retained.js
+// @ts-check
+import 'ses';
+import test from 'ava';
+import { ZipReader } from '@endo/zip';
+import { makeArchive, parseArchive } from '../index.js';
+import { readPowers } from './scaffold.js';
+
+const fixture = new URL(
+ 'fixtures-retained/node_modules/app/app.js',
+ import.meta.url,
+).toString();
+
+test('archives only contain compartments retained by modules', async t => {
+ const bytes = await makeArchive(readPowers, fixture);
+
+ await t.notThrowsAsync(async () => {
+ const app = await parseArchive(bytes);
+ const {
+ namespace: { mark },
+ } = await app.import();
+ t.is(mark, 42);
+ });
+
+ const reader = new ZipReader(bytes);
+ const compartmentMapBytes = reader.files.get('compartment-map.json').content;
+ const compartmentMapText = new TextDecoder().decode(compartmentMapBytes);
+ const compartmentMap = JSON.parse(compartmentMapText);
+ t.deepEqual(Object.keys(compartmentMap.compartments), [
+ 'app-v1.0.0-n0',
+ 'mk1-v1.0.0-n1',
+ 'mk2-v1.0.0-n2',
+ // Notably absent:
+ // 'sweep-v1.0.0-*',
+ ]);
+});

test(compartment-mapper): Test compartment map retention