mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-11 13:52:19 +00:00
Merge branch 'german/refactor-e11-boundary-catalogs' into german/navara-refactor
# Conflicts: # scripts/package-boundaries.json
This commit is contained in:
commit
50e486ceec
5 files changed
+372
-1478
No files matched your search
@@ -238,7 +238,12 @@ test('the draw modules are registered for formatting and boundary checks', () =>
|
||||
const boundaries = JSON.parse(read('scripts/package-boundaries.json'));
|
||||
const owners = (file) =>
|
||||
Object.entries(boundaries)
|
||||
.filter(([, group]) => group.modules?.includes(file))
|
||||
.filter(([, group]) =>
|
||||
// An entry ending in '/' owns every module in that directory.
|
||||
group.modules?.some((entry) =>
|
||||
entry.endsWith('/') ? file.startsWith(entry) : entry === file,
|
||||
),
|
||||
)
|
||||
.map(([name]) => name);
|
||||
for (const file of [
|
||||
'src/annotations/drawMode.js',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { execFileSync, spawnSync } from 'node:child_process';
|
||||
import {
|
||||
copyFile,
|
||||
mkdtemp,
|
||||
@@ -23,7 +23,9 @@ async function fixture(
|
||||
entry = 'export const value = 1;',
|
||||
extraExports = {},
|
||||
) {
|
||||
const root = await mkdtemp(path.join(repoRoot, 'tmp_package_boundaries_'));
|
||||
const root = await mkdtemp(
|
||||
path.join(repoRoot, 'tmp_e11_package_boundaries_'),
|
||||
);
|
||||
t.after(() => rm(root, { recursive: true, force: true }));
|
||||
await mkdir(path.join(root, 'scripts'));
|
||||
await writeFile(
|
||||
@@ -69,7 +71,7 @@ test('even an unused import of application code violates ownership', async (t) =
|
||||
"import { app } from './startup.js'; export const value = 1;",
|
||||
);
|
||||
await writeFile(path.join(root, 'startup.js'), 'export const app = 2;');
|
||||
await assert.rejects(checkPackageBoundaries(root), /unowned module.*startup/);
|
||||
await assert.rejects(checkPackageBoundaries(root), /\+ startup\.js/);
|
||||
});
|
||||
|
||||
test('Node builtins cannot enter a browser export', async (t) => {
|
||||
@@ -77,7 +79,10 @@ test('Node builtins cannot enter a browser export', async (t) => {
|
||||
t,
|
||||
"import fs from 'node:fs'; export const value = fs;",
|
||||
);
|
||||
await assert.rejects(checkPackageBoundaries(root), /unowned module|browser/);
|
||||
await assert.rejects(
|
||||
checkPackageBoundaries(root),
|
||||
/browser|escapes repository/,
|
||||
);
|
||||
});
|
||||
|
||||
test('dynamic imports obey the same component ownership rule', async (t) => {
|
||||
@@ -86,7 +91,7 @@ test('dynamic imports obey the same component ownership rule', async (t) => {
|
||||
"export const load = () => import('./startup.js');",
|
||||
);
|
||||
await writeFile(path.join(root, 'startup.js'), 'export const app = 2;');
|
||||
await assert.rejects(checkPackageBoundaries(root), /unowned module.*startup/);
|
||||
await assert.rejects(checkPackageBoundaries(root), /\+ startup\.js/);
|
||||
});
|
||||
|
||||
test('a Node build export must be explicitly classified and scoped', async (t) => {
|
||||
@@ -118,7 +123,7 @@ test('a Node build export must be explicitly classified and scoped', async (t) =
|
||||
"import './startup.js'; export const value = 1;",
|
||||
);
|
||||
await writeFile(path.join(root, 'startup.js'), 'export const app = 2;');
|
||||
await assert.rejects(checkPackageBoundaries(root), /unowned module.*startup/);
|
||||
await assert.rejects(checkPackageBoundaries(root), /\+ startup\.js/);
|
||||
});
|
||||
|
||||
test('a lifecycle owner cannot acquire a layer panel even through an unused import', async (t) => {
|
||||
@@ -137,7 +142,7 @@ test('a lifecycle owner cannot acquire a layer panel even through an unused impo
|
||||
},
|
||||
}),
|
||||
);
|
||||
await assert.rejects(checkPackageBoundaries(root), /unowned module.*panel/);
|
||||
await assert.rejects(checkPackageBoundaries(root), /\+ panel\.js/);
|
||||
});
|
||||
|
||||
test('a module entry ending in a slash owns every file under that directory', async (t) => {
|
||||
@@ -151,6 +156,10 @@ test('a module entry ending in a slash owns every file under that directory', as
|
||||
"export { b as a } from './nested/b.js';",
|
||||
);
|
||||
await writeFile(path.join(root, 'shared/nested/b.js'), 'export const b = 1;');
|
||||
await writeFile(
|
||||
path.join(root, 'shared/unreached.js'),
|
||||
'export const c = 2;',
|
||||
);
|
||||
await writeFile(
|
||||
path.join(root, 'scripts/package-boundaries.json'),
|
||||
JSON.stringify({
|
||||
@@ -170,10 +179,7 @@ test('a module entry ending in a slash owns every file under that directory', as
|
||||
"export { c as b } from '../../shared.js';",
|
||||
);
|
||||
await writeFile(path.join(root, 'shared.js'), 'export const c = 1;');
|
||||
await assert.rejects(
|
||||
checkPackageBoundaries(root),
|
||||
/unowned module.*shared\.js/,
|
||||
);
|
||||
await assert.rejects(checkPackageBoundaries(root), /\+ shared\.js/);
|
||||
});
|
||||
|
||||
test('regeneration adds unowned modules, including unused and dynamic imports', async (t) => {
|
||||
@@ -199,16 +205,17 @@ test('regeneration adds unowned modules, including unused and dynamic imports',
|
||||
]);
|
||||
});
|
||||
|
||||
test('regeneration removes unreached files without making the check reject stale entries', async (t) => {
|
||||
test('the check rejects unreached files and regeneration removes them', async (t) => {
|
||||
const root = await fixture(t);
|
||||
const file = path.join(root, 'scripts/package-boundaries.json');
|
||||
const manifest = JSON.parse(await readFile(file, 'utf8'));
|
||||
manifest.feature.modules.push('stale.js');
|
||||
await writeFile(path.join(root, 'stale.js'), 'export const stale = 1;');
|
||||
await writeFile(file, JSON.stringify(manifest));
|
||||
assert.deepEqual(await checkPackageBoundaries(root), [
|
||||
{ name: 'feature', exports: 1, modules: 1 },
|
||||
]);
|
||||
await assert.rejects(
|
||||
checkPackageBoundaries(root),
|
||||
/feature: 0 added, 1 removed\.\n - stale\.js/,
|
||||
);
|
||||
assert.deepEqual(await writePackageBoundaries(root), [
|
||||
{ name: 'feature', added: [], removed: ['stale.js'] },
|
||||
]);
|
||||
@@ -223,6 +230,10 @@ test('regeneration removes deleted entries and adds an unowned export entry', as
|
||||
const manifest = JSON.parse(await readFile(file, 'utf8'));
|
||||
manifest.feature.modules = ['deleted.js', 'deleted/'];
|
||||
await writeFile(file, JSON.stringify(manifest));
|
||||
await assert.rejects(
|
||||
checkPackageBoundaries(root),
|
||||
/feature: 1 added, 2 removed\.\n \+ entry\.js\n - deleted\.js\n - deleted\//,
|
||||
);
|
||||
assert.deepEqual(await writePackageBoundaries(root), [
|
||||
{
|
||||
name: 'feature',
|
||||
@@ -262,6 +273,10 @@ test('regeneration keeps a directory only while it owns a reached module', async
|
||||
path.join(root, 'entry.js'),
|
||||
"export { other } from './shared.js';",
|
||||
);
|
||||
await assert.rejects(
|
||||
checkPackageBoundaries(root),
|
||||
/feature: 0 added, 1 removed\.\n - shared\//,
|
||||
);
|
||||
assert.deepEqual(await writePackageBoundaries(root), [
|
||||
{ name: 'feature', added: [], removed: ['shared/'] },
|
||||
]);
|
||||
@@ -271,6 +286,90 @@ test('regeneration keeps a directory only while it owns a reached module', async
|
||||
]);
|
||||
});
|
||||
|
||||
test('shared globe ownership excludes engine and testing directories', async (t) => {
|
||||
const root = await fixture(
|
||||
t,
|
||||
"export { value } from './src/globe/shared/value.js';",
|
||||
);
|
||||
await mkdir(path.join(root, 'src/globe/shared'), { recursive: true });
|
||||
await writeFile(
|
||||
path.join(root, 'src/globe/shared/value.js'),
|
||||
'export const value = 1;',
|
||||
);
|
||||
const file = path.join(root, 'scripts/package-boundaries.json');
|
||||
const manifest = JSON.parse(await readFile(file, 'utf8'));
|
||||
manifest.feature.modules.push('src/globe/');
|
||||
await writeFile(file, JSON.stringify(manifest));
|
||||
assert.deepEqual(await checkPackageBoundaries(root), [
|
||||
{ name: 'feature', exports: 1, modules: 2 },
|
||||
]);
|
||||
assert.deepEqual(await writePackageBoundaries(root), []);
|
||||
for (const directory of ['cesium', 'navara', 'testing']) {
|
||||
await mkdir(path.join(root, 'src/globe', directory));
|
||||
const module = `src/globe/${directory}/value.js`;
|
||||
await writeFile(path.join(root, module), 'export const value = 2;');
|
||||
await writeFile(
|
||||
path.join(root, 'entry.js'),
|
||||
`export { value } from './src/globe/shared/value.js'; import './${module}';`,
|
||||
);
|
||||
await assert.rejects(checkPackageBoundaries(root), (error) => {
|
||||
assert.ok(
|
||||
error.message.includes(`feature: 1 added, 0 removed.\n + ${module}`),
|
||||
);
|
||||
return true;
|
||||
});
|
||||
assert.deepEqual(await writePackageBoundaries(root), [
|
||||
{ name: 'feature', added: [module], removed: [] },
|
||||
]);
|
||||
assert.deepEqual(JSON.parse(await readFile(file, 'utf8')).feature.modules, [
|
||||
'entry.js',
|
||||
'src/globe/',
|
||||
module,
|
||||
]);
|
||||
assert.deepEqual(await checkPackageBoundaries(root), [
|
||||
{ name: 'feature', exports: 1, modules: 3 },
|
||||
]);
|
||||
await writeFile(file, JSON.stringify(manifest));
|
||||
}
|
||||
});
|
||||
|
||||
test('the check reports additions and removals for every changed group', async (t) => {
|
||||
const root = await fixture(t, "export { value } from './value.js';", {
|
||||
'./other': './other.js',
|
||||
});
|
||||
for (const name of ['value.js', 'stale.js', 'other.js', 'other-stale.js']) {
|
||||
await writeFile(path.join(root, name), 'export const value = 1;');
|
||||
}
|
||||
const file = path.join(root, 'scripts/package-boundaries.json');
|
||||
const manifest = JSON.parse(await readFile(file, 'utf8'));
|
||||
manifest.feature.modules.push('stale.js');
|
||||
manifest.other = {
|
||||
exports: ['./other'],
|
||||
modules: ['other.js', 'other-stale.js'],
|
||||
external: [],
|
||||
};
|
||||
const original = JSON.stringify(manifest);
|
||||
await writeFile(file, original);
|
||||
await assert.rejects(checkPackageBoundaries(root), (error) => {
|
||||
assert.equal(
|
||||
error.message,
|
||||
'Package boundary snapshots differ. Run node scripts/check-package-boundaries.mjs --write and review the diff.\n' +
|
||||
'feature: 1 added, 1 removed.\n + value.js\n - stale.js\n' +
|
||||
'other: 0 added, 1 removed.\n - other-stale.js',
|
||||
);
|
||||
return true;
|
||||
});
|
||||
assert.equal(await readFile(file, 'utf8'), original);
|
||||
assert.deepEqual(await writePackageBoundaries(root), [
|
||||
{ name: 'feature', added: ['value.js'], removed: ['stale.js'] },
|
||||
{ name: 'other', added: [], removed: ['other-stale.js'] },
|
||||
]);
|
||||
assert.deepEqual(await checkPackageBoundaries(root), [
|
||||
{ name: 'feature', exports: 1, modules: 2 },
|
||||
{ name: 'other', exports: 1, modules: 1 },
|
||||
]);
|
||||
});
|
||||
|
||||
test('regeneration preserves kept entry order and all other manifest fields', async (t) => {
|
||||
const root = await fixture(
|
||||
t,
|
||||
@@ -344,6 +443,20 @@ test('the CLI reports changes and a second --write leaves the manifest untouched
|
||||
env: { ...process.env, GOOGLE_MAPS_API_KEY: '', CESIUM_ION_TOKEN: '' },
|
||||
},
|
||||
);
|
||||
const checked = spawnSync(
|
||||
process.execPath,
|
||||
['scripts/check-package-boundaries.mjs'],
|
||||
{
|
||||
cwd: root,
|
||||
encoding: 'utf8',
|
||||
env: { ...process.env, GOOGLE_MAPS_API_KEY: '', CESIUM_ION_TOKEN: '' },
|
||||
},
|
||||
);
|
||||
assert.equal(checked.status, 1);
|
||||
assert.match(
|
||||
checked.stderr,
|
||||
/feature: 1 added, 1 removed\.\n \+ value\.js\n - stale\.js/,
|
||||
);
|
||||
assert.equal(
|
||||
run(['--write']),
|
||||
'Updated feature: 1 added, 1 removed.\n + value.js\n - stale.js\n',
|
||||
|
||||
Reference in new issue
Block a user