feat(editor): F4.5a the device sheet for PCs, notebooks, switches and modems
Measured first: the new oracle SheetRun types 77 texts into FILIUS' own settings panels and records what was marked red, what the device took and what the field showed afterwards. Java's two judgements disagree (red text taken, black text refused, any int as a modem port, a refused text dropped without a word); here one rule decides both (packages/doc fields.ts), a refused text stays marked in the field, and only what Java's model accepts reaches the document. - doc: settings.ts (name, label policy, addresses, IP forwarding, DHCP stopping the own DHCP server, LAN/WLAN with the wireless connection, switch SSID dropping its wireless hosts, retention time, cloud, modem port as its pair), sheet.ts (what the sheet shows) - fls: modemPair/modemPort in one place - editor: DeviceSheet beside the surface or below it on a phone, opened with the selection; every change one undo step - not adopted from Java: the name overwritten by the MAC address, the access point search depending on unrelated devices Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
# Text typed into FILIUS' settings panels (tools/java-oracle SheetRun):
|
||||
# <device> <field> <text>, the text may be empty; \uXXXX for anything but
|
||||
# printable ASCII and for spaces at either end.
|
||||
host name Neuer Name
|
||||
host name
|
||||
host name \u0020\u0020PC 1\u0020\u0020
|
||||
host name \u00c4rger-\u00df
|
||||
host ip 10.0.0.1
|
||||
host ip 010.000.000.001
|
||||
host ip 10..0.0.1
|
||||
host ip .0.0.1
|
||||
host ip +10.0.0.1
|
||||
host ip 256.0.0.1
|
||||
host ip 10.0.0
|
||||
host ip 10.0.0.1.
|
||||
host ip \u002010.0.0.1
|
||||
host ip 10.0.0.1\u0020
|
||||
host ip abc
|
||||
host ip
|
||||
host ip 0.0.0.0
|
||||
host ip 1.2.3.4.5
|
||||
host ip \u0661\u0660.0.0.1
|
||||
host ip 10.0.0.-1
|
||||
host ip -0.0.0.1
|
||||
host ip 255.255.255.255
|
||||
host mask 255.255.0.0
|
||||
host mask 255.0.255.0
|
||||
host mask 0.0.0.0
|
||||
host mask 255.255.255.255
|
||||
host mask 256.0.0.0
|
||||
host mask
|
||||
host mask 255.255.255
|
||||
host mask 0255.255.0.0
|
||||
host mask 1.2.3.4
|
||||
host mask 255..255.0.0
|
||||
host gateway
|
||||
host gateway \u0020\u0020\u0020
|
||||
host gateway 192.168.0.1
|
||||
host gateway 192.168.0.256
|
||||
host gateway abc
|
||||
host gateway \u0020192.168.0.1
|
||||
host gateway 192.168..1.1
|
||||
host gateway 0.0.0.0
|
||||
host dns
|
||||
host dns 8.8.8.8
|
||||
host dns 8.8.8
|
||||
host dns \u0020
|
||||
host dns 08.8.8.8
|
||||
switch name S1
|
||||
switch name
|
||||
switch ssid Schule
|
||||
switch ssid
|
||||
switch ssid \u0020
|
||||
switch ssid a b
|
||||
switch ssid \u00c4
|
||||
switch ssid ~
|
||||
switch ssid \u007f
|
||||
switch ssid \u0020lead
|
||||
switch retention 60
|
||||
switch retention 0
|
||||
switch retention
|
||||
switch retention -5
|
||||
switch retention abc
|
||||
switch retention 1.5
|
||||
switch retention 007
|
||||
switch retention 99999999999999999999
|
||||
switch retention \u0663
|
||||
switch retention \u002060
|
||||
modem name M
|
||||
modem name
|
||||
modem port 12345
|
||||
modem port 0
|
||||
modem port 65535
|
||||
modem port 65536
|
||||
modem port -1
|
||||
modem port abc
|
||||
modem port
|
||||
modem port 080
|
||||
modem port \u002080
|
||||
modem port 80
|
||||
@@ -0,0 +1,703 @@
|
||||
{
|
||||
"cases": [
|
||||
{
|
||||
"device": "host",
|
||||
"field": "name",
|
||||
"input": "Neuer Name",
|
||||
"start": "Rechner",
|
||||
"marked": false,
|
||||
"stored": "Neuer Name",
|
||||
"shown": "Neuer Name"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "name",
|
||||
"input": "",
|
||||
"start": "Rechner",
|
||||
"marked": false,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "name",
|
||||
"input": " PC 1 ",
|
||||
"start": "Rechner",
|
||||
"marked": false,
|
||||
"stored": " PC 1 ",
|
||||
"shown": " PC 1 "
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "name",
|
||||
"input": "Ärger-ß",
|
||||
"start": "Rechner",
|
||||
"marked": false,
|
||||
"stored": "Ärger-ß",
|
||||
"shown": "Ärger-ß"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": false,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "010.000.000.001",
|
||||
"start": "192.168.0.10",
|
||||
"marked": false,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10..0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": ".0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": false,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "+10.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "256.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10.0.0",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10.0.0.1.",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": " 10.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10.0.0.1 ",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "abc",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "0.0.0.0",
|
||||
"start": "192.168.0.10",
|
||||
"marked": false,
|
||||
"stored": "0.0.0.0",
|
||||
"shown": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "1.2.3.4.5",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "١٠.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "10.0.0.1",
|
||||
"shown": "10.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "10.0.0.-1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.10",
|
||||
"shown": "192.168.0.10"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "-0.0.0.1",
|
||||
"start": "192.168.0.10",
|
||||
"marked": true,
|
||||
"stored": "0.0.0.1",
|
||||
"shown": "0.0.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "ip",
|
||||
"input": "255.255.255.255",
|
||||
"start": "192.168.0.10",
|
||||
"marked": false,
|
||||
"stored": "255.255.255.255",
|
||||
"shown": "255.255.255.255"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "255.255.0.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "255.255.0.0",
|
||||
"shown": "255.255.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "255.0.255.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "255.0.255.0",
|
||||
"shown": "255.0.255.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "0.0.0.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "0.0.0.0",
|
||||
"shown": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "255.255.255.255",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "255.255.255.255",
|
||||
"shown": "255.255.255.255"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "256.0.0.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": true,
|
||||
"stored": "255.255.255.0",
|
||||
"shown": "255.255.255.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "",
|
||||
"start": "255.255.255.0",
|
||||
"marked": true,
|
||||
"stored": "255.255.255.0",
|
||||
"shown": "255.255.255.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "255.255.255",
|
||||
"start": "255.255.255.0",
|
||||
"marked": true,
|
||||
"stored": "255.255.255.0",
|
||||
"shown": "255.255.255.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "0255.255.0.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "255.255.0.0",
|
||||
"shown": "255.255.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "1.2.3.4",
|
||||
"start": "255.255.255.0",
|
||||
"marked": false,
|
||||
"stored": "1.2.3.4",
|
||||
"shown": "1.2.3.4"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "mask",
|
||||
"input": "255..255.0.0",
|
||||
"start": "255.255.255.0",
|
||||
"marked": true,
|
||||
"stored": "255.255.0.0",
|
||||
"shown": "255.255.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "",
|
||||
"start": "192.168.0.254",
|
||||
"marked": false,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": " ",
|
||||
"start": "192.168.0.254",
|
||||
"marked": true,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "192.168.0.1",
|
||||
"start": "192.168.0.254",
|
||||
"marked": false,
|
||||
"stored": "192.168.0.1",
|
||||
"shown": "192.168.0.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "192.168.0.256",
|
||||
"start": "192.168.0.254",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.254",
|
||||
"shown": "192.168.0.254"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "abc",
|
||||
"start": "192.168.0.254",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.254",
|
||||
"shown": "192.168.0.254"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": " 192.168.0.1",
|
||||
"start": "192.168.0.254",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.254",
|
||||
"shown": "192.168.0.254"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "192.168..1.1",
|
||||
"start": "192.168.0.254",
|
||||
"marked": true,
|
||||
"stored": "192.168.1.1",
|
||||
"shown": "192.168.1.1"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "gateway",
|
||||
"input": "0.0.0.0",
|
||||
"start": "192.168.0.254",
|
||||
"marked": false,
|
||||
"stored": "0.0.0.0",
|
||||
"shown": "0.0.0.0"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "dns",
|
||||
"input": "",
|
||||
"start": "192.168.0.253",
|
||||
"marked": false,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "dns",
|
||||
"input": "8.8.8.8",
|
||||
"start": "192.168.0.253",
|
||||
"marked": false,
|
||||
"stored": "8.8.8.8",
|
||||
"shown": "8.8.8.8"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "dns",
|
||||
"input": "8.8.8",
|
||||
"start": "192.168.0.253",
|
||||
"marked": true,
|
||||
"stored": "192.168.0.253",
|
||||
"shown": "192.168.0.253"
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "dns",
|
||||
"input": " ",
|
||||
"start": "192.168.0.253",
|
||||
"marked": true,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "host",
|
||||
"field": "dns",
|
||||
"input": "08.8.8.8",
|
||||
"start": "192.168.0.253",
|
||||
"marked": false,
|
||||
"stored": "8.8.8.8",
|
||||
"shown": "8.8.8.8"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "name",
|
||||
"input": "S1",
|
||||
"start": "Switch / WLAN",
|
||||
"marked": false,
|
||||
"stored": "S1",
|
||||
"shown": "S1"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "name",
|
||||
"input": "",
|
||||
"start": "Switch / WLAN",
|
||||
"marked": false,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "Schule",
|
||||
"start": "Start",
|
||||
"marked": false,
|
||||
"stored": "Schule",
|
||||
"shown": "Schule"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "",
|
||||
"start": "Start",
|
||||
"marked": true,
|
||||
"stored": "Start",
|
||||
"shown": "Start"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": " ",
|
||||
"start": "Start",
|
||||
"marked": false,
|
||||
"stored": " ",
|
||||
"shown": " "
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "a b",
|
||||
"start": "Start",
|
||||
"marked": false,
|
||||
"stored": "a b",
|
||||
"shown": "a b"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "Ä",
|
||||
"start": "Start",
|
||||
"marked": true,
|
||||
"stored": "Start",
|
||||
"shown": "Start"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "~",
|
||||
"start": "Start",
|
||||
"marked": false,
|
||||
"stored": "~",
|
||||
"shown": "~"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": "",
|
||||
"start": "Start",
|
||||
"marked": true,
|
||||
"stored": "Start",
|
||||
"shown": "Start"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "ssid",
|
||||
"input": " lead",
|
||||
"start": "Start",
|
||||
"marked": false,
|
||||
"stored": " lead",
|
||||
"shown": " lead"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "60",
|
||||
"start": "300000",
|
||||
"marked": false,
|
||||
"stored": "60000",
|
||||
"shown": "60"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "0",
|
||||
"start": "300000",
|
||||
"marked": false,
|
||||
"stored": "0",
|
||||
"shown": "0"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "",
|
||||
"start": "300000",
|
||||
"marked": false,
|
||||
"stored": "300000",
|
||||
"shown": "300"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "-5",
|
||||
"start": "300000",
|
||||
"marked": true,
|
||||
"stored": "-5000",
|
||||
"shown": "-5"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "abc",
|
||||
"start": "300000",
|
||||
"marked": true,
|
||||
"stored": "300000",
|
||||
"shown": "300"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "1.5",
|
||||
"start": "300000",
|
||||
"marked": true,
|
||||
"stored": "300000",
|
||||
"shown": "300"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "007",
|
||||
"start": "300000",
|
||||
"marked": false,
|
||||
"stored": "7000",
|
||||
"shown": "7"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "99999999999999999999",
|
||||
"start": "300000",
|
||||
"marked": false,
|
||||
"stored": "300000",
|
||||
"shown": "300"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": "٣",
|
||||
"start": "300000",
|
||||
"marked": true,
|
||||
"stored": "3000",
|
||||
"shown": "3"
|
||||
},
|
||||
{
|
||||
"device": "switch",
|
||||
"field": "retention",
|
||||
"input": " 60",
|
||||
"start": "300000",
|
||||
"marked": true,
|
||||
"stored": "300000",
|
||||
"shown": "300"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "name",
|
||||
"input": "M",
|
||||
"start": "Modem",
|
||||
"marked": false,
|
||||
"stored": "M",
|
||||
"shown": "M"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "name",
|
||||
"input": "",
|
||||
"start": "Modem",
|
||||
"marked": false,
|
||||
"stored": "",
|
||||
"shown": ""
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "12345",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "12345",
|
||||
"shown": "12345"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "0",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "0",
|
||||
"shown": "0"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "65535",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "65535",
|
||||
"shown": "65535"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "65536",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "65536",
|
||||
"shown": "65536"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "-1",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "-1",
|
||||
"shown": "-1"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "abc",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "12345",
|
||||
"shown": "12345"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "12345",
|
||||
"shown": "12345"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "080",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "80",
|
||||
"shown": "80"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": " 80",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "12345",
|
||||
"shown": "12345"
|
||||
},
|
||||
{
|
||||
"device": "modem",
|
||||
"field": "port",
|
||||
"input": "80",
|
||||
"start": "12345",
|
||||
"marked": false,
|
||||
"stored": "80",
|
||||
"shown": "80"
|
||||
}
|
||||
],
|
||||
"flows": {
|
||||
"useMacAsNameThenOff": "0E:EE:AA:A5:58:21",
|
||||
"useIpAsNameThenOff": "PC-A",
|
||||
"dhcpClientStopsServer": true,
|
||||
"dhcpClient": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,415 @@
|
||||
// The device sheet: what a field takes, measured against FILIUS' own settings
|
||||
// panels (tools/java-oracle's SheetRun typed the texts of sheet.cases.txt
|
||||
// into them, sheet.java.json), and what its changes do to the document — the
|
||||
// wireless connections moved as Java moves them, each change one step of
|
||||
// the person's undo, and everything kept through a saved file.
|
||||
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import * as Y from 'yjs';
|
||||
import { openProjectArchive, saveProjectArchive } from '@mdg-filius/fls';
|
||||
import {
|
||||
addDevice,
|
||||
checkField,
|
||||
connect,
|
||||
createUndoManager,
|
||||
deviceSheet,
|
||||
readProject,
|
||||
renameDevice,
|
||||
ROOTS,
|
||||
setDhcpClient,
|
||||
setHostAddress,
|
||||
setHostLabels,
|
||||
setHostWireless,
|
||||
setIpForwarding,
|
||||
setModemPort,
|
||||
setSwitchCloud,
|
||||
setSwitchRetention,
|
||||
setSwitchSsid,
|
||||
topologyView,
|
||||
type FieldRule,
|
||||
type HostSheet,
|
||||
type NewDevice,
|
||||
} from '../src/index.js';
|
||||
|
||||
interface JavaCase {
|
||||
readonly device: 'host' | 'switch' | 'modem';
|
||||
readonly field: string;
|
||||
readonly input: string;
|
||||
readonly start: string;
|
||||
readonly marked: boolean;
|
||||
readonly stored: string;
|
||||
readonly shown: string;
|
||||
}
|
||||
|
||||
const java = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), 'sheet.java.json'), 'utf8')) as {
|
||||
readonly cases: readonly JavaCase[];
|
||||
readonly flows: { readonly useMacAsNameThenOff: string; readonly useIpAsNameThenOff: string; readonly dhcpClientStopsServer: boolean; readonly dhcpClient: boolean };
|
||||
};
|
||||
|
||||
const RULES: Readonly<Record<string, FieldRule>> = {
|
||||
'host name': 'name',
|
||||
'host ip': 'ipAddress',
|
||||
'host mask': 'subnetMask',
|
||||
'host gateway': 'ipAddressOrEmpty',
|
||||
'host dns': 'ipAddressOrEmpty',
|
||||
'switch name': 'name',
|
||||
'switch ssid': 'ssid',
|
||||
'switch retention': 'seconds',
|
||||
'modem name': 'name',
|
||||
'modem port': 'port',
|
||||
};
|
||||
|
||||
/** Fields whose text is judged without the spaces around it. */
|
||||
const TRIMMED = new Set(['host ip', 'host mask', 'host gateway', 'host dns', 'switch retention', 'modem port']);
|
||||
|
||||
/** What Java's model holds in the units of the sheet's value: seconds for the retention time. */
|
||||
const javaValue = (each: JavaCase) => (each.field === 'retention' ? String(Number(each.stored) / 1000) : each.stored);
|
||||
|
||||
/** The case Java judged for a text: the trimmed text's own case where spaces are left out. */
|
||||
function judged(each: JavaCase): JavaCase {
|
||||
const key = `${each.device} ${each.field}`;
|
||||
if (!TRIMMED.has(key) || each.input.trim() === each.input) return each;
|
||||
const twin = java.cases.find((other) => other.device === each.device && other.field === each.field && other.input === each.input.trim());
|
||||
if (twin === undefined) throw new Error(`no case for ${JSON.stringify(each.input.trim())} (${key})`);
|
||||
return twin;
|
||||
}
|
||||
|
||||
describe("a field's rule, against FILIUS' settings panels", () => {
|
||||
it('has a case for every field the sheet checks', () => {
|
||||
expect(new Set(java.cases.map((each) => `${each.device} ${each.field}`))).toEqual(new Set(Object.keys(RULES)));
|
||||
expect(java.cases.length).toBeGreaterThan(70);
|
||||
});
|
||||
|
||||
it('takes a text exactly when Java neither marks nor refuses it, as the value Java keeps', () => {
|
||||
for (const each of java.cases) {
|
||||
const key = `${each.device} ${each.field}`;
|
||||
const verdict = judged(each);
|
||||
// Taken: the value changed, or the text was the value already.
|
||||
const took = verdict.stored !== verdict.start || verdict.input === verdict.start;
|
||||
// A name is taken as typed. A modem's port Java never marks: it takes any int; here Java's own rule for ports.
|
||||
const expected = RULES[key] === 'name' ? true : key === 'modem port' ? took && /^([1-9][0-9]{0,4})$/.test(verdict.input) && Number(verdict.input) <= 65_535 : !verdict.marked && took;
|
||||
const checked = checkField(RULES[key]!, each.input);
|
||||
expect('value' in checked, `${key} ${JSON.stringify(each.input)}`).toBe(expected);
|
||||
if ('value' in checked) expect(checked.value, `${key} ${JSON.stringify(each.input)}`).toBe(RULES[key] === 'name' ? each.input : javaValue(verdict));
|
||||
}
|
||||
});
|
||||
|
||||
it("names where Java's two judgements disagree, which here are one", () => {
|
||||
const disagreeing = java.cases.filter((each) => RULES[`${each.device} ${each.field}`] !== 'name' && each.field !== 'port' && each.marked === (each.stored !== each.start));
|
||||
// Marked red, yet taken; or black, yet refused (the gateway's spaces Java trims to empty).
|
||||
expect(disagreeing.map((each) => `${each.field} ${JSON.stringify(each.input)} ${each.marked ? 'marked, taken' : 'refused'}`)).toEqual([
|
||||
'ip "10..0.0.1" marked, taken',
|
||||
'ip ".0.0.1" refused',
|
||||
'ip "+10.0.0.1" marked, taken',
|
||||
'ip "10.0.0.1." marked, taken',
|
||||
'ip "١٠.0.0.1" marked, taken',
|
||||
'ip "-0.0.0.1" marked, taken',
|
||||
'mask "255..255.0.0" marked, taken',
|
||||
'gateway " " marked, taken',
|
||||
'gateway "192.168..1.1" marked, taken',
|
||||
'dns " " marked, taken',
|
||||
'retention "" refused',
|
||||
'retention "-5" marked, taken',
|
||||
'retention "99999999999999999999" refused',
|
||||
'retention "٣" marked, taken',
|
||||
]);
|
||||
const ports = java.cases.filter((each) => each.field === 'port' && each.stored !== each.start);
|
||||
expect(ports.map((each) => each.input)).toEqual(['0', '65535', '65536', '-1', '080', '80']);
|
||||
});
|
||||
|
||||
it("shows what the device holds once a field is left, as Java's field does", () => {
|
||||
for (const each of java.cases) if (each.field !== 'retention') expect(each.shown, each.input).toBe(each.stored);
|
||||
});
|
||||
});
|
||||
|
||||
let ids = 0;
|
||||
const newId = () => `20000000-0000-0000-0000-${(++ids).toString(16).padStart(12, '0')}`;
|
||||
|
||||
function add(doc: Y.Doc, kind: NewDevice['kind'], name: string = kind): string {
|
||||
const id = newId();
|
||||
addDevice(doc, { kind, id, name, x: 100, y: 100, newId }, 'me');
|
||||
return id;
|
||||
}
|
||||
|
||||
const host = (doc: Y.Doc, id: string) => deviceSheet(doc, id) as HostSheet;
|
||||
|
||||
describe("a PC's sheet", () => {
|
||||
it("shows a new PC as Java's panel does", () => {
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc', 'Rechner');
|
||||
const sheet = host(doc, pc);
|
||||
expect({ ...sheet, macAddress: undefined }).toEqual({
|
||||
kind: 'pc',
|
||||
name: 'Rechner',
|
||||
labels: { ipAddress: false, macAddress: false },
|
||||
macAddress: undefined,
|
||||
ipAddress: '192.168.0.10',
|
||||
subnetMask: '255.255.255.0',
|
||||
defaultGateway: '',
|
||||
dnsServer: '',
|
||||
dhcpClient: false,
|
||||
ipForwarding: false,
|
||||
wireless: false,
|
||||
ssid: '',
|
||||
wirelessPossible: true,
|
||||
networks: [],
|
||||
});
|
||||
expect(sheet.macAddress).toMatch(/^([0-9A-F]{2}:){5}[0-9A-F]{2}$/);
|
||||
expect(deviceSheet(doc, 'nobody')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('takes an address as Java keeps it, keeps the old one for a marked text, and says which', () => {
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc');
|
||||
expect(setHostAddress(doc, pc, 'ipAddress', ' 010.000.000.001 ', 'me')).toEqual({ value: '10.0.0.1' });
|
||||
expect(setHostAddress(doc, pc, 'ipAddress', '10.0.0.256', 'me')).toEqual({ invalid: true });
|
||||
expect(setHostAddress(doc, pc, 'subnetMask', '255.0.255.0', 'me')).toEqual({ value: '255.0.255.0' });
|
||||
expect(setHostAddress(doc, pc, 'defaultGateway', '10.0.0.254', 'me')).toEqual({ value: '10.0.0.254' });
|
||||
expect(setHostAddress(doc, pc, 'dnsServer', '8.8.8', 'me')).toEqual({ invalid: true });
|
||||
expect(setHostAddress(doc, pc, 'dnsServer', '8.8.8.8', 'me')).toEqual({ value: '8.8.8.8' });
|
||||
expect(readProject(doc).deviceConfigurations.get(pc)).toEqual({ ipAddress: '10.0.0.1', subnetMask: '255.0.255.0', defaultGateway: '10.0.0.254', dnsServer: '8.8.8.8' });
|
||||
expect(setHostAddress(doc, pc, 'defaultGateway', '', 'me')).toEqual({ value: '' });
|
||||
expect(host(doc, pc).defaultGateway).toBe('');
|
||||
expect(setHostAddress(doc, 'nobody', 'ipAddress', '10.0.0.1', 'me')).toEqual({ value: '10.0.0.1' });
|
||||
});
|
||||
|
||||
it('is renamed, and shows its address, its MAC address or both as its name', () => {
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc');
|
||||
renameDevice(doc, pc, 'PC-A', 'me');
|
||||
setHostLabels(doc, pc, { ipAddress: true, macAddress: false }, 'me');
|
||||
expect(topologyView(doc).nodes[0]!.label).toBe('192.168.0.10');
|
||||
setHostLabels(doc, pc, { ipAddress: false, macAddress: true }, 'me');
|
||||
expect(topologyView(doc).nodes[0]!.label).toBe(host(doc, pc).macAddress);
|
||||
setHostLabels(doc, pc, { ipAddress: true, macAddress: true }, 'me');
|
||||
expect(host(doc, pc).labels).toEqual({ ipAddress: true, macAddress: true });
|
||||
expect(topologyView(doc).nodes[0]!.label).toBe(`192.168.0.10 (${host(doc, pc).macAddress})`);
|
||||
setHostLabels(doc, pc, { ipAddress: false, macAddress: false }, 'me');
|
||||
expect(topologyView(doc).nodes[0]!.label).toBe('PC-A');
|
||||
});
|
||||
|
||||
it("keeps its name while it shows its MAC address and another field is taken (Java's panel overwrites it)", () => {
|
||||
// Java: the name became the MAC address; with the address shown instead, it stayed.
|
||||
expect(java.flows.useMacAsNameThenOff).toMatch(/^([0-9A-F]{2}:){5}[0-9A-F]{2}$/);
|
||||
expect(java.flows.useIpAsNameThenOff).toBe('PC-A');
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc', 'PC-A');
|
||||
setHostLabels(doc, pc, { ipAddress: false, macAddress: true }, 'me');
|
||||
setHostAddress(doc, pc, 'defaultGateway', '192.168.0.1', 'me');
|
||||
setHostLabels(doc, pc, { ipAddress: false, macAddress: false }, 'me');
|
||||
expect(host(doc, pc).name).toBe('PC-A');
|
||||
});
|
||||
|
||||
it("keeps IP forwarding only where it differs from the kind's", () => {
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc');
|
||||
const router = add(doc, 'router');
|
||||
setIpForwarding(doc, pc, true, 'me');
|
||||
setIpForwarding(doc, router, false, 'me');
|
||||
expect(host(doc, pc).ipForwarding).toBe(true);
|
||||
expect(readProject(doc).ipForwardingByNodeId).toEqual(
|
||||
new Map([
|
||||
[pc, true],
|
||||
[router, false],
|
||||
]),
|
||||
);
|
||||
setIpForwarding(doc, pc, false, 'me');
|
||||
setIpForwarding(doc, router, true, 'me');
|
||||
expect(readProject(doc).ipForwardingByNodeId).toEqual(new Map());
|
||||
});
|
||||
|
||||
it("uses DHCP, which stops its own DHCP server, as Java's panel does", () => {
|
||||
expect(java.flows).toMatchObject({ dhcpClient: true, dhcpClientStopsServer: true });
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc');
|
||||
const settings = doc.getMap<Y.Map<unknown>>(ROOTS.nodes).get(pc)!.get('settings') as Y.Map<unknown>;
|
||||
const server = new Y.Map<unknown>();
|
||||
server.set('isActive', true);
|
||||
settings.set('dhcpServer', server);
|
||||
setDhcpClient(doc, pc, true, 'me');
|
||||
expect(host(doc, pc).dhcpClient).toBe(true);
|
||||
expect(readProject(doc).dhcpClientConfigurations.get(pc)).toEqual({ isEnabled: true });
|
||||
expect(server.get('isActive')).toBe(false);
|
||||
setDhcpClient(doc, pc, false, 'me');
|
||||
expect(host(doc, pc).dhcpClient).toBe(false);
|
||||
expect(readProject(doc).dhcpClientConfigurations.has(pc)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('a wireless card', () => {
|
||||
/** Two switches with their SSIDs and a notebook. */
|
||||
function wlan() {
|
||||
const doc = new Y.Doc();
|
||||
const first = add(doc, 'networkSwitch');
|
||||
const second = add(doc, 'networkSwitch');
|
||||
const notebook = add(doc, 'notebook');
|
||||
setSwitchSsid(doc, first, 'Schule', 'me');
|
||||
setSwitchSsid(doc, second, 'Gast', 'me');
|
||||
const ends = () => readProject(doc).graph.links.map((link) => [link.sourceNodeId, link.targetNodeId]);
|
||||
return { doc, first, second, notebook, ends };
|
||||
}
|
||||
|
||||
it('offers the switches’ networks, each once', () => {
|
||||
const { doc, notebook } = wlan();
|
||||
const third = add(doc, 'networkSwitch');
|
||||
setSwitchSsid(doc, third, 'Schule', 'me');
|
||||
expect(host(doc, notebook).networks).toEqual(['Schule', 'Gast']);
|
||||
});
|
||||
|
||||
it('joins the first switch with its SSID, moves with the SSID and leaves on the cable', () => {
|
||||
const { doc, first, second, notebook, ends } = wlan();
|
||||
expect(setHostWireless(doc, notebook, true, 'Schule', 'link-1', 'me')).toEqual({ link: 'link-1' });
|
||||
expect(ends()).toEqual([[notebook, first]]);
|
||||
expect(topologyView(doc).links[0]!.wireless).toBe(true);
|
||||
expect(host(doc, notebook)).toMatchObject({ wireless: true, ssid: 'Schule', wirelessPossible: true });
|
||||
expect(setHostWireless(doc, notebook, true, 'Gast', 'link-2', 'me')).toEqual({ link: 'link-2' });
|
||||
expect(ends()).toEqual([[notebook, second]]);
|
||||
// The same again changes nothing.
|
||||
expect(setHostWireless(doc, notebook, true, 'Gast', 'link-3', 'me')).toEqual({});
|
||||
expect(ends()).toEqual([[notebook, second]]);
|
||||
expect(setHostWireless(doc, notebook, false, 'Gast', 'link-4', 'me')).toEqual({});
|
||||
expect(ends()).toEqual([]);
|
||||
// Java keeps the SSID with the cable.
|
||||
expect(readProject(doc).hostWirelessConfigurations.get(notebook)).toEqual({ isEnabled: false, ssid: 'Gast' });
|
||||
expect(setHostWireless(doc, notebook, false, '', 'link-5', 'me')).toEqual({});
|
||||
expect(readProject(doc).hostWirelessConfigurations.has(notebook)).toBe(false);
|
||||
});
|
||||
|
||||
it('joins the first of two switches with its SSID', () => {
|
||||
const { doc, second, notebook, ends } = wlan();
|
||||
const third = add(doc, 'networkSwitch');
|
||||
setSwitchSsid(doc, third, 'Gast', 'me');
|
||||
expect(setHostWireless(doc, notebook, true, 'Gast', 'link-1', 'me')).toEqual({ link: 'link-1' });
|
||||
expect(ends()).toEqual([[notebook, second]]);
|
||||
});
|
||||
|
||||
it('joins no network without an SSID or without a switch that has it', () => {
|
||||
const { doc, notebook, ends } = wlan();
|
||||
expect(setHostWireless(doc, notebook, true, '', 'link-1', 'me')).toEqual({});
|
||||
expect(setHostWireless(doc, notebook, true, 'Nirgends', 'link-2', 'me')).toEqual({});
|
||||
expect(ends()).toEqual([]);
|
||||
expect(host(doc, notebook)).toMatchObject({ wireless: true, ssid: 'Nirgends' });
|
||||
});
|
||||
|
||||
it('cannot be chosen while its cable is plugged, and says why a full switch refuses it', () => {
|
||||
const { doc, first, notebook } = wlan();
|
||||
const pc = add(doc, 'pc');
|
||||
connect(doc, { node: notebook }, { node: pc }, 'cable', 'me');
|
||||
expect(host(doc, notebook).wirelessPossible).toBe(false);
|
||||
expect(setHostWireless(doc, notebook, true, 'Schule', 'link-1', 'me')).toEqual({ error: 'cablePlugged' });
|
||||
expect(host(doc, notebook).wireless).toBe(false);
|
||||
const other = add(doc, 'notebook');
|
||||
const full = doc.getMap<Y.Map<unknown>>(ROOTS.nodes).get(first)!;
|
||||
(full.get('ports') as Y.Array<Y.Map<unknown>>).delete(1, 23);
|
||||
expect(connect(doc, { node: add(doc, 'pc') }, { node: first }, 'filled', 'me')).toEqual({ link: 'filled' });
|
||||
expect(setHostWireless(doc, other, true, 'Schule', 'link-2', 'me')).toEqual({ error: 'noFreePort' });
|
||||
expect(setHostWireless(doc, 'nobody', true, 'Schule', 'link-3', 'me')).toEqual({ error: 'unknownDevice' });
|
||||
});
|
||||
|
||||
it("is dropped by a switch that changes its SSID, a cable to it staying (Java's panel)", () => {
|
||||
const { doc, first, notebook, ends } = wlan();
|
||||
const pc = add(doc, 'pc');
|
||||
setHostWireless(doc, notebook, true, 'Schule', 'link-1', 'me');
|
||||
connect(doc, { node: pc }, { node: first }, 'cable', 'me');
|
||||
expect(setSwitchSsid(doc, first, 'Schule', 'me')).toEqual({ value: 'Schule' });
|
||||
expect(ends()).toHaveLength(2);
|
||||
expect(setSwitchSsid(doc, first, 'Ä', 'me')).toEqual({ invalid: true });
|
||||
expect(ends()).toHaveLength(2);
|
||||
expect(setSwitchSsid(doc, first, 'Neu', 'me')).toEqual({ value: 'Neu' });
|
||||
expect(ends()).toEqual([[pc, first]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("a switch's and a modem's sheet", () => {
|
||||
it('shows and keeps the SSID, the retention time in seconds and the cloud', () => {
|
||||
const doc = new Y.Doc();
|
||||
const hub = add(doc, 'networkSwitch', 'Switch');
|
||||
expect(deviceSheet(doc, hub)).toEqual({ kind: 'networkSwitch', name: 'Switch', ssid: hub.replaceAll('-', '').slice(0, 6), retentionSeconds: 300, cloud: false });
|
||||
expect(setSwitchRetention(doc, hub, ' 007 ', 'me')).toEqual({ value: '7' });
|
||||
expect(setSwitchRetention(doc, hub, '-5', 'me')).toEqual({ invalid: true });
|
||||
setSwitchCloud(doc, hub, true, 'me');
|
||||
expect(deviceSheet(doc, hub)).toMatchObject({ retentionSeconds: 7, cloud: true });
|
||||
expect(topologyView(doc).nodes[0]!.cloud).toBe(true);
|
||||
expect(readProject(doc).switchConfigurations.get(hub)).toEqual({ ssid: hub.replaceAll('-', '').slice(0, 6), retentionTimeMilliseconds: 7000, showsAsCloud: true });
|
||||
setSwitchCloud(doc, hub, false, 'me');
|
||||
expect(readProject(doc).switchConfigurations.get(hub)).toEqual({ ssid: hub.replaceAll('-', '').slice(0, 6), retentionTimeMilliseconds: 7000 });
|
||||
});
|
||||
|
||||
it('shows whole seconds of a retention time a file brings in milliseconds', () => {
|
||||
const doc = new Y.Doc();
|
||||
const hub = add(doc, 'networkSwitch');
|
||||
(doc.getMap<Y.Map<unknown>>(ROOTS.nodes).get(hub)!.get('settings') as Y.Map<Y.Map<unknown>>).get('switch')!.set('retentionTimeMilliseconds', 1999);
|
||||
expect(deviceSheet(doc, hub)).toMatchObject({ retentionSeconds: 1 });
|
||||
});
|
||||
|
||||
it("pairs a modem by its port, and names the other kinds' sheets", () => {
|
||||
const doc = new Y.Doc();
|
||||
const modem = add(doc, 'remoteLink', 'Modem');
|
||||
expect(deviceSheet(doc, modem)).toEqual({ kind: 'remoteLink', name: 'Modem', port: 12_345 });
|
||||
expect(setModemPort(doc, modem, '65536', 'me')).toEqual({ invalid: true });
|
||||
expect(setModemPort(doc, modem, ' 80', 'me')).toEqual({ value: '80' });
|
||||
expect(readProject(doc).remoteLinkConfigurations.get(modem)).toEqual({ pairIdentifier: 'java-modem-port-80', latencyMilliseconds: 20, isEnabled: true });
|
||||
expect(deviceSheet(doc, modem)).toMatchObject({ port: 80 });
|
||||
const router = add(doc, 'router', 'R1');
|
||||
renameDevice(doc, router, 'R2', 'me');
|
||||
expect(deviceSheet(doc, router)).toEqual({ kind: 'router', name: 'R2' });
|
||||
expect(deviceSheet(doc, add(doc, 'gateway', 'Heim'))).toEqual({ kind: 'gateway', name: 'Heim' });
|
||||
});
|
||||
});
|
||||
|
||||
describe("the sheet's changes", () => {
|
||||
it('are each one step of the person’s undo, the wireless join with its connection', () => {
|
||||
const doc = new Y.Doc();
|
||||
const hub = add(doc, 'networkSwitch');
|
||||
const notebook = add(doc, 'notebook');
|
||||
setSwitchSsid(doc, hub, 'Schule', 'setup');
|
||||
const undo = createUndoManager(doc, 'me');
|
||||
setHostAddress(doc, notebook, 'ipAddress', '10.0.0.1', 'me');
|
||||
undo.stopCapturing();
|
||||
setHostWireless(doc, notebook, true, 'Schule', 'link-1', 'me');
|
||||
undo.stopCapturing();
|
||||
renameDevice(doc, notebook, 'NB', 'me');
|
||||
undo.stopCapturing();
|
||||
undo.undo();
|
||||
expect(host(doc, notebook).name).toBe('notebook');
|
||||
undo.undo();
|
||||
expect(host(doc, notebook).wireless).toBe(false);
|
||||
expect(readProject(doc).graph.links).toEqual([]);
|
||||
undo.undo();
|
||||
expect(host(doc, notebook).ipAddress).toBe('192.168.0.10');
|
||||
undo.redo();
|
||||
undo.redo();
|
||||
expect(host(doc, notebook)).toMatchObject({ ipAddress: '10.0.0.1', wireless: true });
|
||||
expect(readProject(doc).graph.links).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('are kept through a saved file', () => {
|
||||
const doc = new Y.Doc();
|
||||
const pc = add(doc, 'pc', 'PC-A');
|
||||
const hub = add(doc, 'networkSwitch', 'S');
|
||||
const modem = add(doc, 'remoteLink', 'M');
|
||||
setHostAddress(doc, pc, 'ipAddress', '10.1.2.3', 'me');
|
||||
setHostAddress(doc, pc, 'subnetMask', '255.255.0.0', 'me');
|
||||
setHostAddress(doc, pc, 'defaultGateway', '10.1.0.1', 'me');
|
||||
setHostAddress(doc, pc, 'dnsServer', '10.1.0.2', 'me');
|
||||
setHostLabels(doc, pc, { ipAddress: true, macAddress: false }, 'me');
|
||||
setIpForwarding(doc, pc, true, 'me');
|
||||
setDhcpClient(doc, pc, true, 'me');
|
||||
setSwitchSsid(doc, hub, 'Schule', 'me');
|
||||
setSwitchRetention(doc, hub, '42', 'me');
|
||||
setSwitchCloud(doc, hub, true, 'me');
|
||||
setModemPort(doc, modem, '4242', 'me');
|
||||
let counter = 0;
|
||||
const reopened = openProjectArchive(saveProjectArchive(readProject(doc)).archive, () => `30000000-0000-0000-0000-${(++counter).toString(16).padStart(12, '0')}`);
|
||||
const [pcAgain, hubAgain, modemAgain] = reopened.graph.nodes;
|
||||
expect(pcAgain!.hostLabelPolicy).toBe('ipAddress');
|
||||
expect(reopened.deviceConfigurations.get(pcAgain!.id)).toEqual({ ipAddress: '10.1.2.3', subnetMask: '255.255.0.0', defaultGateway: '10.1.0.1', dnsServer: '10.1.0.2' });
|
||||
expect(reopened.ipForwardingByNodeId.get(pcAgain!.id)).toBe(true);
|
||||
expect(reopened.dhcpClientConfigurations.get(pcAgain!.id)).toEqual({ isEnabled: true });
|
||||
expect(reopened.switchConfigurations.get(hubAgain!.id)).toEqual({ ssid: 'Schule', retentionTimeMilliseconds: 42_000, showsAsCloud: true });
|
||||
expect(reopened.remoteLinkConfigurations.get(modemAgain!.id)?.pairIdentifier).toBe('java-modem-port-4242');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user