feat(fls): keep a .fls's own applications through the editor model
The archive's entries besides the configuration — the project's own Java applications under projekt/anwendungen (.java, .class, EigeneAnwendungen.txt) — now go through the editor model: openProjectArchive reads a whole .fls into the model and keeps them in its archiveEntries, saveProjectArchive writes a whole .fls from the model with them unchanged. They cannot run here, but must not be lost. Checked on every corpus file: each entry comes back byte for byte (7 files carry applications of their own); a probe that drops them is caught. Installing such applications on a host is the next step; Java loads those only through its full loading path, which the oracle is to use first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -51,8 +51,8 @@ Swift-Pfade relativ zu `filius-ipad/ios/FiliusPad/TopologyEditor/` (Stand
|
|||||||
| `test/javaBeansWriter.test.ts`, `test/beans/` | — | neu: 11 Dateien des Schreibers, von Javas `XMLDecoder` gelesen und beschrieben; Erwartungen von Hand |
|
| `test/javaBeansWriter.test.ts`, `test/beans/` | — | neu: 11 Dateien des Schreibers, von Javas `XMLDecoder` gelesen und beschrieben; Erwartungen von Hand |
|
||||||
| `src/topologyWriter.ts` | Java `SzenarioVerwaltung.netzwerkSpeichern`, Konstruktoren von `NetzwerkInterface`, `Port`, `GUIKabelItem` und der Systemsoftware | neu nach Java: `konfiguration.xml` aus Javas Sicht — Geräte, Schnittstellen (vom Konstruktor angelegte über Getter, weitere per `add`), Ports über Getter-Verweise, Kabel samt Zeichen-Enden (`kabelpanel`), Doku-Elemente; Systemsoftware über ihre Setter: SSID, Lernzeit, RIP, manuelle Routen, DHCP-Client und -Server, statische NAT, Modem, Router-Firewall (über das `konfig`-Plug-in des Webservers, wie XMLEncoder sie erreicht); Dateisysteme (an die Wurzel des Konstruktors angehängt wie bei XMLEncoder, beim Router hinter dessen Vorlagen); installierte Programme nach den Dateien (Webserver, Tauschbörse und E-Mail-Server legen ihre Ordner nur an, wo sie fehlen; der DNS-Server liest `/dns/hosts` beim Installieren), je unter ihrem Schlüssel mit der Systemsoftware wie `installApp`, samt Einstellungen und persönlicher Firewall; E-Mail: Domain und Bean-Konten des Servers samt Postfächern, Ordner und Adressbuch des Clients (sein Konto steht in `/konten.txt`, einer Datei); Javas Fehler nicht übernommen: ein Empfänger, den eine ältere Datei als Zeichenkette hält, wird als der `AddressEntry` geschrieben, den Javas `AddressEntry(String)` daraus macht (Java legt die Zeichenkette ungeprüft in die typisierte Liste, sein E-Mail-Fenster scheitert daran), ein `null`-Empfänger fällt weg; Kopf „Filius version: 2.14.0 (mdg-filius)“ |
|
| `src/topologyWriter.ts` | Java `SzenarioVerwaltung.netzwerkSpeichern`, Konstruktoren von `NetzwerkInterface`, `Port`, `GUIKabelItem` und der Systemsoftware | neu nach Java: `konfiguration.xml` aus Javas Sicht — Geräte, Schnittstellen (vom Konstruktor angelegte über Getter, weitere per `add`), Ports über Getter-Verweise, Kabel samt Zeichen-Enden (`kabelpanel`), Doku-Elemente; Systemsoftware über ihre Setter: SSID, Lernzeit, RIP, manuelle Routen, DHCP-Client und -Server, statische NAT, Modem, Router-Firewall (über das `konfig`-Plug-in des Webservers, wie XMLEncoder sie erreicht); Dateisysteme (an die Wurzel des Konstruktors angehängt wie bei XMLEncoder, beim Router hinter dessen Vorlagen); installierte Programme nach den Dateien (Webserver, Tauschbörse und E-Mail-Server legen ihre Ordner nur an, wo sie fehlen; der DNS-Server liest `/dns/hosts` beim Installieren), je unter ihrem Schlüssel mit der Systemsoftware wie `installApp`, samt Einstellungen und persönlicher Firewall; E-Mail: Domain und Bean-Konten des Servers samt Postfächern, Ordner und Adressbuch des Clients (sein Konto steht in `/konten.txt`, einer Datei); Javas Fehler nicht übernommen: ein Empfänger, den eine ältere Datei als Zeichenkette hält, wird als der `AddressEntry` geschrieben, den Javas `AddressEntry(String)` daraus macht (Java legt die Zeichenkette ungeprüft in die typisierte Liste, sein E-Mail-Fenster scheitert daran), ein `null`-Empfänger fällt weg; Kopf „Filius version: 2.14.0 (mdg-filius)“ |
|
||||||
| `test/topologyWriter.test.ts`, `test/written.java.json` | — | neu: alle 23 Korpus-Dateien gelesen und neu geschrieben, von Java geladen — Topologie, Systemsoftware, Dateisysteme und Programme samt E-Mail wie beim Original (bis auf die benannte Abweichung bei Empfängern als Zeichenkette, nur in `man-in-the-middle.fls`) (Java gegen Java); dazu eine künstliche Topologie mit dem, was der Korpus nicht hat (u. a. eingeschaltete Router-Firewall mit Regeln jedes Protokolls, alle Firewall-Schalter abseits der Vorgabe, Modem mit eigenem Port und Ziel, verschachtelter Dateibaum mit umbenannter Wurzel, namenlosem Ordner, Datei ohne Typ und Inhalt mit CR/CRLF und Zeichen jenseits der BMP, Heimrouter mit eigener Wurzel, jedes Filius-Programm mit Einstellungen abseits der Vorgabe samt persönlicher Firewall, von Java angelegte Ordner `/peer2peer` und `/mailserver`, E-Mail-Server und -Client mit Konto, Postfach, drei Ordnern, Adressbuch und Empfängern aller Formen) |
|
| `test/topologyWriter.test.ts`, `test/written.java.json` | — | neu: alle 23 Korpus-Dateien gelesen und neu geschrieben, von Java geladen — Topologie, Systemsoftware, Dateisysteme und Programme samt E-Mail wie beim Original (bis auf die benannte Abweichung bei Empfängern als Zeichenkette, nur in `man-in-the-middle.fls`) (Java gegen Java); dazu eine künstliche Topologie mit dem, was der Korpus nicht hat (u. a. eingeschaltete Router-Firewall mit Regeln jedes Protokolls, alle Firewall-Schalter abseits der Vorgabe, Modem mit eigenem Port und Ziel, verschachtelter Dateibaum mit umbenannter Wurzel, namenlosem Ordner, Datei ohne Typ und Inhalt mit CR/CRLF und Zeichen jenseits der BMP, Heimrouter mit eigener Wurzel, jedes Filius-Programm mit Einstellungen abseits der Vorgabe samt persönlicher Firewall, von Java angelegte Ordner `/peer2peer` und `/mailserver`, E-Mail-Server und -Client mit Konto, Postfach, drei Ordnern, Adressbuch und Empfängern aller Formen) |
|
||||||
| `src/exportProject.ts` | Gegenstück zu `importProject.ts`; Java `JHostKonfiguration.updateWifiConnection`, `InternetKnotenBetriebssystem.getStandardGateway`/`setStandardGateway` | neu: Editor-Modell → Javas Sicht für den Schreiber, Schritt X1 Topologie — Geräte, Schnittstellen (MAC wie in der Simulation: aus der Datei oder aus der Port-ID abgeleitet), Kabel samt Funk (Karte drahtlos und Switch, wie Java verbindet), Gateway und DNS an allen Schnittstellen wie Javas eigene Setter, Doku-Elemente; X2 Systemsoftware — SSIDs, Lernzeit, Routen, RIP, DHCP-Client und -Server, Portweiterleitung, Firewall (Namen des Kerns als Javas Zahlen), Modems aus den Paaren des Modells (Port aus dem Paarnamen, der erste eines Paars dient, Ziel `localhost`); X3 Dateien von Rechner und Notebook — Typ aus der Inhaltsart (Text nach Endung, sonst `text`; Bild und Binärdaten nach Medientyp), Bilder und Binärdaten in Base64 wie Filius' `Base64.encodeBytes` (Umbruch nach 76 Zeichen, an 19 Längen mit Java gemessen); X4a Programme — je Programm die Filius-Klasse unter ihrem Namen als Schlüssel, eingeschaltete Server, Ports, virtuelle Hosts, DNS-Rekursion, Ziel des Clients (leer als `null` wie Javas Konstruktor), Teilnehmerzahl, persönliche Firewall; X4b E-Mail — Beans des Servers (Domain, Konten, Postfächer) und des Clients (drei Ordner, Adressbuch), `/konten.txt` und `/mailserver/konten.txt` aus den Konten des Modells neu geschrieben im Format von Filius 2.14 (`EmailKonto.toString`, `listeBenutzerkontenZuString`), ohne Javas Fehler (leere Felder statt "null"); ein Zeichen, das ein Feld im Format nicht tragen kann, wird dort zum Leerzeichen, mit Warnung |
|
| `src/exportProject.ts` | Gegenstück zu `importProject.ts`; `saveProjectArchive` schreibt eine ganze `.fls` samt der übrigen Archiveinträge (Gegenstück: `openProjectArchive` in `importProject.ts`, das sie in `archiveEntries` des Modells legt); Java `JHostKonfiguration.updateWifiConnection`, `InternetKnotenBetriebssystem.getStandardGateway`/`setStandardGateway` | neu: Editor-Modell → Javas Sicht für den Schreiber, Schritt X1 Topologie — Geräte, Schnittstellen (MAC wie in der Simulation: aus der Datei oder aus der Port-ID abgeleitet), Kabel samt Funk (Karte drahtlos und Switch, wie Java verbindet), Gateway und DNS an allen Schnittstellen wie Javas eigene Setter, Doku-Elemente; X2 Systemsoftware — SSIDs, Lernzeit, Routen, RIP, DHCP-Client und -Server, Portweiterleitung, Firewall (Namen des Kerns als Javas Zahlen), Modems aus den Paaren des Modells (Port aus dem Paarnamen, der erste eines Paars dient, Ziel `localhost`); X3 Dateien von Rechner und Notebook — Typ aus der Inhaltsart (Text nach Endung, sonst `text`; Bild und Binärdaten nach Medientyp), Bilder und Binärdaten in Base64 wie Filius' `Base64.encodeBytes` (Umbruch nach 76 Zeichen, an 19 Längen mit Java gemessen); X4a Programme — je Programm die Filius-Klasse unter ihrem Namen als Schlüssel, eingeschaltete Server, Ports, virtuelle Hosts, DNS-Rekursion, Ziel des Clients (leer als `null` wie Javas Konstruktor), Teilnehmerzahl, persönliche Firewall; X4b E-Mail — Beans des Servers (Domain, Konten, Postfächer) und des Clients (drei Ordner, Adressbuch), `/konten.txt` und `/mailserver/konten.txt` aus den Konten des Modells neu geschrieben im Format von Filius 2.14 (`EmailKonto.toString`, `listeBenutzerkontenZuString`), ohne Javas Fehler (leere Felder statt "null"); ein Zeichen, das ein Feld im Format nicht tragen kann, wird dort zum Leerzeichen, mit Warnung |
|
||||||
| `test/exportProject.test.ts`, `test/exported.java.json` | — | neu: alle 23 Korpus-Dateien importiert, exportiert, geschrieben und von Java geladen — Topologie wie beim Original bis auf benannte Abweichungen (abgeleiteter MAC und abgeleitete Switch-SSID statt gewürfelter, Modem-Rollen nach Reihenfolge im Paar, Doku in Zeichenreihenfolge mit Text, Schrift und Mindestgröße des Modells, Dateien in der Ordnung und mit dem Typ des Modells, keine eigenen Dateien von Routern, Empfänger als Zeichenkette gelesen, Nachrichten des Gesendet-Ordners versendet, Konto-Dateien neu geschrieben wie Filius 2.14); dazu ein künstliches Modell, das Java ebenfalls lädt |
|
| `test/exportProject.test.ts`, `test/exported.java.json` | — | neu: alle 23 Korpus-Dateien importiert, exportiert, geschrieben und von Java geladen — Topologie wie beim Original bis auf benannte Abweichungen (abgeleiteter MAC und abgeleitete Switch-SSID statt gewürfelter, Modem-Rollen nach Reihenfolge im Paar, Doku in Zeichenreihenfolge mit Text, Schrift und Mindestgröße des Modells, Dateien in der Ordnung und mit dem Typ des Modells, keine eigenen Dateien von Routern, Empfänger als Zeichenkette gelesen, Nachrichten des Gesendet-Ordners versendet, Konto-Dateien neu geschrieben wie Filius 2.14); die übrigen Archiveinträge (eigene Anwendungen unter `projekt/anwendungen`) kommen byte-gleich zurück; dazu ein künstliches Modell, das Java ebenfalls lädt |
|
||||||
| `src/importEmail.ts` | `Persistence/TopologyProjectStore.swift` (`registerJavaEmailConfigurations`, `assignedJavaEmailMessages`) | übertragen, Eingabe ist Javas Sicht: Server-Konten aus `/mailserver/konten.txt`, ohne Datei aus der Bean-Liste (Java verlöre sie); Client-Konto aus `/konten.txt`, ohne Datei aus der älteren `kontoListe` (Filius 2.14 liest sie nicht mehr); Konten und Nachrichten bleiben, wo Swift verwirft, was seine Prüfung nicht besteht; Vor- und Nachname getrennt; Empfangszeit nur aus der Datei (Swift nummeriert); gegen Swifts Modell geprüft |
|
| `src/importEmail.ts` | `Persistence/TopologyProjectStore.swift` (`registerJavaEmailConfigurations`, `assignedJavaEmailMessages`) | übertragen, Eingabe ist Javas Sicht: Server-Konten aus `/mailserver/konten.txt`, ohne Datei aus der Bean-Liste (Java verlöre sie); Client-Konto aus `/konten.txt`, ohne Datei aus der älteren `kontoListe` (Filius 2.14 liest sie nicht mehr); Konten und Nachrichten bleiben, wo Swift verwirft, was seine Prüfung nicht besteht; Vor- und Nachname getrennt; Empfangszeit nur aus der Datei (Swift nummeriert); gegen Swifts Modell geprüft |
|
||||||
| `test/importEmail.test.ts`, `test/email-*.swift.json` | `State/TopologyEmail.swift` (`decodeJavaServer`, `decodeJavaClient`) als Vergleich | neu: dieselben 43 Kontodateien mit Swifts Leser; wie Swift bis auf benannte Fälle, in denen Swift prüft und die ganze Datei verwirft, wo Java liest |
|
| `test/importEmail.test.ts`, `test/email-*.swift.json` | `State/TopologyEmail.swift` (`decodeJavaServer`, `decodeJavaClient`) als Vergleich | neu: dieselben 43 Kontodateien mit Swifts Leser; wie Swift bis auf benannte Fälle, in denen Swift prüft und die ganze Datei verwirft, wo Java liest |
|
||||||
| `src/javaFileSystem.ts`, `src/javaString.ts` | Java `Dateisystem.holeDatei`, `String.trim`/`split`/`equalsIgnoreCase` | neu nach Java; die Groß-/Kleinschreibung gegenüber ASCII am JDK über die ganze BMP gemessen |
|
| `src/javaFileSystem.ts`, `src/javaString.ts` | Java `Dateisystem.holeDatei`, `String.trim`/`split`/`equalsIgnoreCase` | neu nach Java; die Groß-/Kleinschreibung gegenüber ASCII am JDK über die ganze BMP gemessen |
|
||||||
|
|||||||
@@ -111,11 +111,12 @@ import {
|
|||||||
type TopologyNode,
|
type TopologyNode,
|
||||||
type VirtualFileSystem,
|
type VirtualFileSystem,
|
||||||
} from '@mdg-filius/core';
|
} from '@mdg-filius/core';
|
||||||
|
import { writeFlsArchive } from './archive.js';
|
||||||
import { EMAIL_CLIENT_FILE, EMAIL_SERVER_FILE, type JavaAddressEntry, type JavaContact, type JavaEmail } from './javaEmail.js';
|
import { EMAIL_CLIENT_FILE, EMAIL_SERVER_FILE, type JavaAddressEntry, type JavaContact, type JavaEmail } from './javaEmail.js';
|
||||||
import { PROGRAM_OF_CLASS } from './importProject.js';
|
import { PROGRAM_OF_CLASS } from './importProject.js';
|
||||||
import type { FlsApplicationClass, FlsDhcpServer, FlsFileTree, FlsFirewall } from './systemSoftware.js';
|
import type { FlsApplicationClass, FlsDhcpServer, FlsFileTree, FlsFirewall } from './systemSoftware.js';
|
||||||
import type { FlsDocumentationItem, FlsInterface, FlsLink, FlsNodeClass } from './topology.js';
|
import type { FlsDocumentationItem, FlsInterface, FlsLink, FlsNodeClass } from './topology.js';
|
||||||
import type { ApplicationToWrite, NodeToWrite, SystemToWrite, TopologyToWrite } from './topologyWriter.js';
|
import { writeTopologyXml, type ApplicationToWrite, type NodeToWrite, type SystemToWrite, type TopologyToWrite } from './topologyWriter.js';
|
||||||
|
|
||||||
/** The parts of the editor model the topology is made of. */
|
/** The parts of the editor model the topology is made of. */
|
||||||
export interface ProjectToExport {
|
export interface ProjectToExport {
|
||||||
@@ -142,6 +143,8 @@ export interface ProjectToExport {
|
|||||||
readonly emailClientConfigurations: ReadonlyMap<Id, EmailClientConfiguration>;
|
readonly emailClientConfigurations: ReadonlyMap<Id, EmailClientConfiguration>;
|
||||||
readonly emailServerConfigurations: ReadonlyMap<Id, EmailServerConfiguration>;
|
readonly emailServerConfigurations: ReadonlyMap<Id, EmailServerConfiguration>;
|
||||||
readonly documentationItems: readonly DocumentationItem[];
|
readonly documentationItems: readonly DocumentationItem[];
|
||||||
|
/** The archive's other entries (the project's own applications), written unchanged. */
|
||||||
|
readonly archiveEntries?: ReadonlyMap<string, Uint8Array>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ExportedTopology {
|
export interface ExportedTopology {
|
||||||
@@ -195,6 +198,13 @@ export function exportProject(project: ProjectToExport): ExportedTopology {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A whole .fls: the model's configuration, as Java's view written, and the archive's other entries unchanged. */
|
||||||
|
export function saveProjectArchive(project: ProjectToExport): { readonly archive: Uint8Array; readonly warnings: string[] } {
|
||||||
|
const { topology, warnings } = exportProject(project);
|
||||||
|
const configuration = new TextEncoder().encode(writeTopologyXml(topology));
|
||||||
|
return { archive: writeFlsArchive(configuration, project.archiveEntries ?? new Map()), warnings };
|
||||||
|
}
|
||||||
|
|
||||||
function exportNode(node: TopologyNode, project: ProjectToExport, servingModems: ReadonlySet<Id>, warnings: string[]): NodeToWrite {
|
function exportNode(node: TopologyNode, project: ProjectToExport, servingModems: ReadonlySet<Id>, warnings: string[]): NodeToWrite {
|
||||||
const javaClass = CLASS_OF_KIND[node.kind as Exclude<NodeKind, 'unsupported'>];
|
const javaClass = CLASS_OF_KIND[node.kind as Exclude<NodeKind, 'unsupported'>];
|
||||||
const interfaces = exportInterfaces(node, project);
|
const interfaces = exportInterfaces(node, project);
|
||||||
|
|||||||
@@ -97,10 +97,12 @@ import {
|
|||||||
type TopologyNode,
|
type TopologyNode,
|
||||||
type VirtualFileContent,
|
type VirtualFileContent,
|
||||||
} from '@mdg-filius/core';
|
} from '@mdg-filius/core';
|
||||||
|
import { readFlsArchive } from './archive.js';
|
||||||
import { dnsRecordsOf, javaHostsFileContent, readDnsHosts } from './dnsHosts.js';
|
import { dnsRecordsOf, javaHostsFileContent, readDnsHosts } from './dnsHosts.js';
|
||||||
|
import { decodeJavaBeans } from './javabeans.js';
|
||||||
import { emailClientConfiguration, emailServerConfiguration } from './importEmail.js';
|
import { emailClientConfiguration, emailServerConfiguration } from './importEmail.js';
|
||||||
import type { FlsApplicationClass, FlsFileTree, FlsFirewall } from './systemSoftware.js';
|
import type { FlsApplicationClass, FlsFileTree, FlsFirewall } from './systemSoftware.js';
|
||||||
import type { FlsDocumentationItem, FlsInterface, FlsNode, FlsNodeClass, FlsTopology } from './topology.js';
|
import { readTopology, type FlsDocumentationItem, type FlsInterface, type FlsNode, type FlsNodeClass, type FlsTopology } from './topology.js';
|
||||||
|
|
||||||
export interface ImportedProject {
|
export interface ImportedProject {
|
||||||
versionLine: string | null;
|
versionLine: string | null;
|
||||||
@@ -132,6 +134,12 @@ export interface ImportedProject {
|
|||||||
simpleClientConfigurations: Map<Id, SimpleClientConfiguration>;
|
simpleClientConfigurations: Map<Id, SimpleClientConfiguration>;
|
||||||
/** In render order: rectangles below text, then by order. */
|
/** In render order: rectangles below text, then by order. */
|
||||||
documentationItems: DocumentationItem[];
|
documentationItems: DocumentationItem[];
|
||||||
|
/**
|
||||||
|
* The archive's entries besides the configuration — the project's own Java
|
||||||
|
* applications (projekt/anwendungen) — carried unchanged to the next save:
|
||||||
|
* they cannot run here, but must not be lost.
|
||||||
|
*/
|
||||||
|
archiveEntries: ReadonlyMap<string, Uint8Array>;
|
||||||
/** The topology's warnings, then this step's. */
|
/** The topology's warnings, then this step's. */
|
||||||
warnings: string[];
|
warnings: string[];
|
||||||
}
|
}
|
||||||
@@ -150,7 +158,11 @@ export const NODE_KIND_OF_CLASS: Readonly<Record<FlsNodeClass, NodeKind>> = {
|
|||||||
* (Swift uses random UUIDs; tests pass a counter). Documentation ids are
|
* (Swift uses random UUIDs; tests pass a counter). Documentation ids are
|
||||||
* derived from the item, as in Swift.
|
* derived from the item, as in Swift.
|
||||||
*/
|
*/
|
||||||
export function importProject(topology: FlsTopology, newId: () => Id): ImportedProject {
|
export function importProject(
|
||||||
|
topology: FlsTopology,
|
||||||
|
newId: () => Id,
|
||||||
|
archiveEntries: ReadonlyMap<string, Uint8Array> = new Map(),
|
||||||
|
): ImportedProject {
|
||||||
const warnings = [...topology.warnings];
|
const warnings = [...topology.warnings];
|
||||||
const deviceConfigurations = new Map<Id, DeviceConfiguration>();
|
const deviceConfigurations = new Map<Id, DeviceConfiguration>();
|
||||||
const interfaceConfigurations = new Map<InterfaceKey, InterfaceConfiguration>();
|
const interfaceConfigurations = new Map<InterfaceKey, InterfaceConfiguration>();
|
||||||
@@ -236,10 +248,17 @@ export function importProject(topology: FlsTopology, newId: () => Id): ImportedP
|
|||||||
interfaceConfigurations,
|
interfaceConfigurations,
|
||||||
...system,
|
...system,
|
||||||
documentationItems: inDeterministicRenderOrder(documentationItems),
|
documentationItems: inDeterministicRenderOrder(documentationItems),
|
||||||
|
archiveEntries,
|
||||||
warnings,
|
warnings,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A whole .fls: its archive, Java's view of its configuration, the editor model with the archive's other entries. */
|
||||||
|
export function openProjectArchive(archive: Uint8Array, newId: () => Id): ImportedProject {
|
||||||
|
const contents = readFlsArchive(archive);
|
||||||
|
return importProject(readTopology(decodeJavaBeans(contents.configurationXml)), newId, contents.supplementalEntries);
|
||||||
|
}
|
||||||
|
|
||||||
function hostLabelPolicy(node: FlsNode): HostLabelPolicy {
|
function hostLabelPolicy(node: FlsNode): HostLabelPolicy {
|
||||||
if (node.useIpAsName && node.useMacAsName) return 'ipAndMAC';
|
if (node.useIpAsName && node.useMacAsName) return 'ipAndMAC';
|
||||||
if (node.useIpAsName) return 'ipAddress';
|
if (node.useIpAsName) return 'ipAddress';
|
||||||
|
|||||||
@@ -30,7 +30,9 @@ import {
|
|||||||
exportProject,
|
exportProject,
|
||||||
importProject,
|
importProject,
|
||||||
javaBase64,
|
javaBase64,
|
||||||
|
openProjectArchive,
|
||||||
readFlsArchive,
|
readFlsArchive,
|
||||||
|
saveProjectArchive,
|
||||||
readTopology,
|
readTopology,
|
||||||
writeFlsArchive,
|
writeFlsArchive,
|
||||||
type FlsFileTree,
|
type FlsFileTree,
|
||||||
@@ -324,10 +326,13 @@ describe('the editor model exported, as Java loads it', () => {
|
|||||||
for (const file of flsFiles(corpusRoot)) {
|
for (const file of flsFiles(corpusRoot)) {
|
||||||
const name = relative(corpusRoot, file);
|
const name = relative(corpusRoot, file);
|
||||||
it(name, () => {
|
it(name, () => {
|
||||||
const topology = readTopology(decodeJavaBeans(readFlsArchive(new Uint8Array(readFileSync(file))).configurationXml));
|
const bytes = new Uint8Array(readFileSync(file));
|
||||||
const project = importProject(topology, counter());
|
const topology = readTopology(decodeJavaBeans(readFlsArchive(bytes).configurationXml));
|
||||||
|
const project = openProjectArchive(bytes, counter());
|
||||||
const { topology: toWrite } = exportProject(project);
|
const { topology: toWrite } = exportProject(project);
|
||||||
const archive = writeFlsArchive(new TextEncoder().encode(writeTopologyXml(toWrite)));
|
const { archive } = saveProjectArchive(project);
|
||||||
|
// The project's own applications, and every other entry, byte for byte.
|
||||||
|
expect(readFlsArchive(archive).supplementalEntries).toEqual(readFlsArchive(bytes).supplementalEntries);
|
||||||
if (process.env.UPDATE_EXPORTED === '1') {
|
if (process.env.UPDATE_EXPORTED === '1') {
|
||||||
mkdirSync(dirname(join(exportedRoot, name)), { recursive: true });
|
mkdirSync(dirname(join(exportedRoot, name)), { recursive: true });
|
||||||
writeFileSync(join(exportedRoot, name), archive);
|
writeFileSync(join(exportedRoot, name), archive);
|
||||||
|
|||||||
@@ -8230,7 +8230,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "e0f906a2f02c2fdb9b309a6fc0c5625113270ffa95a7a1ce8be11f93e146bd2c"
|
"sha256": "955edc9322d1de6bae59ce05221b94ab18983c46193db034cf37fd18f0146a48"
|
||||||
},
|
},
|
||||||
"java-examples/dhcp_test_scenario.fls": {
|
"java-examples/dhcp_test_scenario.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -8650,7 +8650,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "76d8317e6d352e8686663957f0bbc74f1945b0c419a80ac94992e40590e75e8c"
|
"sha256": "24841ef8e02136eef19247c1a53850c4644232d97a016815bd2338e8190bd357"
|
||||||
},
|
},
|
||||||
"java-examples/dns_server.fls": {
|
"java-examples/dns_server.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -10024,7 +10024,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "ebd1aad2945a178470cc22ce327460d09c456814dbcd155eacced456f242661b"
|
"sha256": "bc7b13a0ada9522a211583371d9b838c4731642032efa1d49d8c217903e4b989"
|
||||||
},
|
},
|
||||||
"java-examples/email_komplett.fls": {
|
"java-examples/email_komplett.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -13451,7 +13451,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "35e84042bc6b04062cb943127a85900ebbc947d5148e9fbf4978bb128a013ff3"
|
"sha256": "b860d1bdf773a92b90f63ff6c7c76e9d0ee2c9b342e6042c3e39f61acf6697e3"
|
||||||
},
|
},
|
||||||
"java-examples/nat.fls": {
|
"java-examples/nat.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -17079,7 +17079,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "f9f829093450eda122c1a5c01d66b1492fd426769652d1f138791a56641d1fea"
|
"sha256": "ff743751be0d5ecdd84d1db935a332c248e39d1f6f7d3882efdb108c419a0a38"
|
||||||
},
|
},
|
||||||
"java-examples/zwei_rechnernetze_komplett.fls": {
|
"java-examples/zwei_rechnernetze_komplett.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
@@ -18359,14 +18359,14 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "ebd1aad2945a178470cc22ce327460d09c456814dbcd155eacced456f242661b"
|
"sha256": "bc7b13a0ada9522a211583371d9b838c4731642032efa1d49d8c217903e4b989"
|
||||||
},
|
},
|
||||||
"java-tests/empty.fls": {
|
"java-tests/empty.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
"nodes": [],
|
"nodes": [],
|
||||||
"cables": [],
|
"cables": [],
|
||||||
"documentation": [],
|
"documentation": [],
|
||||||
"sha256": "49855a61d8576af64e50c211807e658d69daa924a411ced654a3452070b1722c"
|
"sha256": "aec202d78dc3a05cd83471744050a102cb2cf448b273b053df6b4c640f1ac6e9"
|
||||||
},
|
},
|
||||||
"synthetic/model.fls": {
|
"synthetic/model.fls": {
|
||||||
"success": true,
|
"success": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user