test: F3 acceptance — the classroom classics on FILIUS' examples against Java
A web page by its DNS name (internetwork_komplett), an e-mail between two networks through NAT and MX relay (Internet_Komplett_..._DE), a file found and fetched with Gnutella across a router (zwei_rechnernetze_komplett): ExampleRun records frames, tables, program lines and end states; the core plays the same calls and matches card by card. Equal RIP ties take Java's choice, RIP beacons are left out, the search's two connections compared flow by flow. Also: a core test that an equal RIP route from another router neither replaces nor refreshes the route, and nine stale type errors in core tests fixed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
// What the tests of FILIUS' own examples share (examplesJava.test.ts, the
|
||||
// acceptance of F2; classicsJava.test.ts, the acceptance of F3): an example
|
||||
// read with this package's reader, its nodes by the names Java gives them,
|
||||
// and each card Java recorded by its MAC address.
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { stableMacAddress, type Id } from '@mdg-filius/core';
|
||||
import { openProjectArchive, type ImportedProject } from '../src/index.js';
|
||||
import type { CaptureCard } from '../../core/test/javaRun.js';
|
||||
|
||||
const here = dirname(fileURLToPath(import.meta.url));
|
||||
const examples = join(here, '../../../corpus/java-examples');
|
||||
|
||||
/** The recording of a story (examples/<story>.java.json). */
|
||||
export function exampleRecording<T>(story: string): T {
|
||||
return JSON.parse(readFileSync(join(here, 'examples', `${story}.java.json`), 'utf8')) as T;
|
||||
}
|
||||
|
||||
/** An example as this package reads it, its ids numbered as the file's entries come. */
|
||||
export function openExample(file: string): ImportedProject {
|
||||
let counter = 0;
|
||||
return openProjectArchive(new Uint8Array(readFileSync(join(examples, file))), () => `00000000-0000-0000-0000-${(++counter).toString(16).padStart(12, '0')}`);
|
||||
}
|
||||
|
||||
/** Java's names as ScenarioNetwork.fromFile gives them: a repeated name gets #2, #3, … in the file's order. */
|
||||
export function namesInJavaOrder(project: ImportedProject): Map<string, Id> {
|
||||
const names = new Map<string, Id>();
|
||||
for (const node of project.graph.nodes) {
|
||||
let name = node.displayName;
|
||||
for (let count = 2; names.has(name); count += 1) name = `${node.displayName}#${count}`;
|
||||
names.set(name, node.id);
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each card Java recorded, by its node and index (`name/index`). A card the
|
||||
* file has no MAC address for gets one Java rolls at each load, and the
|
||||
* model one derived from its port: Java's stands for the engine's in the
|
||||
* texts (withEngineMacs).
|
||||
*/
|
||||
export function exampleCards(
|
||||
project: ImportedProject,
|
||||
names: ReadonlyMap<string, Id>,
|
||||
javaCards: Record<string, string>,
|
||||
): { readonly cards: CaptureCard[]; readonly withEngineMacs: (text: string) => string } {
|
||||
const engineMacByJavaMac = new Map<string, string>();
|
||||
const cards: CaptureCard[] = Object.entries(javaCards).map(([mac, card]) => {
|
||||
const [nodeName, index] = card.split('/') as [string, string];
|
||||
const node = project.graph.nodes.find((each) => each.id === names.get(nodeName))!;
|
||||
const port = node.ports[Number(index)]!;
|
||||
engineMacByJavaMac.set(mac.toUpperCase(), (port.importedMacAddress ?? stableMacAddress(port.id)).toUpperCase());
|
||||
return { key: mac, portId: port.id };
|
||||
});
|
||||
const withEngineMacs = (text: string) => text.replace(/[0-9A-Fa-f]{2}(:[0-9A-Fa-f]{2}){5}/g, (mac) => engineMacByJavaMac.get(mac.toUpperCase()) ?? mac);
|
||||
return { cards, withEngineMacs };
|
||||
}
|
||||
Reference in New Issue
Block a user