feat(fls): write the topology of a .fls, loaded by Java as the original

topologyWriter.ts writes konfiguration.xml from Java's view of a project:
the version line, the node items (label position, device with name,
host label flags, interfaces or ports), the cable items and the
documentation items. What a device's constructor makes is changed through
getters, as XMLEncoder does, and more is added; fewer than it makes set the
list anew. Cable ends name the port objects the getters return (the writer
now names a getter's result, <void id="Port0" property="port"/>), and each
cable carries the nodes the editor draws it between.

Checked by Java against Java: every corpus file, read and written again,
loads in Java FILIUS (the oracle's loading method, --sha256 ties its result
to the written bytes) to the same devices, names, positions, interfaces,
cables and documentation as the original; so does a synthetic topology with
what the corpus never sets. The oracle and the reader now also report a
cable's drawing ends (JCablePanel ziel1/ziel2): in the corpus the nodes it
joins, for all 183 cables. Mutation probes rewrite the files and let Java
load each mutant.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 08:04:21 +00:00
co-authored by Claude Opus 5.5
parent 3795316fae
commit 314f696515
17 changed files with 16251 additions and 204 deletions
+2 -1
View File
@@ -190,6 +190,7 @@ function asJavaView(topology: FlsTopology, javaBounds: (number[] | null)[]) {
cables: topology.links.map((link) => ({
ends: link.ends.map((end) => [end.node, end.port]),
wireless: link.wireless,
panel: link.panel,
})),
documentation: topology.documentation.map((item) => ({
type: item.type,
@@ -305,7 +306,7 @@ describe('readTopology rules', () => {
</object>`);
expect(nodes.map((node) => node.javaClass)).toEqual(['Switch']);
expect(links).toEqual([{ ends: [{ node: 0, port: 0 }, { node: 0, port: 1 }], wireless: false }]);
expect(links).toEqual([{ ends: [{ node: 0, port: 0 }, { node: 0, port: 1 }], wireless: false, panel: [null, null] }]);
expect(warnings).toEqual([
'node 1: unknown device class filius.hardware.knoten.Drucker, left out',
'cable 2: an end is not a port of a device, left out',