feat: F4.6g1 the echo server and the generic client windows
Oracle EchoWindowRun uses Java's echo server and client windows as a person does; SaveAfterRunRun echo saves what Java keeps after the run. The room takes setActive with a port, connect/disconnect/send, sends both views and writes the server's port and the client's target back. The editor's windows show Java's buttons, fields and lines; a port that is no port is marked and not handed over (Java's button throws). Core fix: an empty message (one empty segment with the push, as Java's erstelleSegmente makes) counted as a repeat and never arrived. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -45,6 +45,22 @@ const FROM_JAVA: Readonly<Record<string, string>> = {
|
||||
'explorer.notImported': 'sw_fileexplorer_msg1',
|
||||
'explorer.tooLarge': 'sw_fileexplorer_msg3',
|
||||
'viewer.open': 'imageviewer_msg2',
|
||||
'echoServer.port': 'serverbaustein_msg1',
|
||||
'echoServer.stop': 'serverbaustein_msg2',
|
||||
'echoServer.start': 'serverbaustein_msg3',
|
||||
'simpleClient.address': 'clientbaustein_msg1',
|
||||
'simpleClient.port': 'clientbaustein_msg2',
|
||||
'simpleClient.connect': 'clientbaustein_msg3',
|
||||
'simpleClient.message': 'clientbaustein_msg4',
|
||||
'simpleClient.send': 'clientbaustein_msg5',
|
||||
'simpleClient.disconnect': 'clientbaustein_msg6',
|
||||
'simpleClient.connected': 'sw_clientbaustein_msg2',
|
||||
'simpleClient.disconnected': 'sw_clientbaustein_msg3',
|
||||
'simpleClient.notConnected': 'sw_clientbaustein_msg4',
|
||||
'simpleClient.receiveFailed': 'sw_tcpsocket_msg9',
|
||||
'simpleClient.failure.unresolved': 'sw_socket_msg1',
|
||||
'simpleClient.failure.timedOut': 'sw_tcpsocket_msg2',
|
||||
'simpleClient.failure.failed': 'sw_tcpsocket_msg3',
|
||||
'textEditor.new': 'texteditor_msg3',
|
||||
'textEditor.open': 'texteditor_msg4',
|
||||
'textEditor.save': 'texteditor_msg5',
|
||||
@@ -269,6 +285,7 @@ const FROM_JAVA_MENDED: Readonly<Record<string, readonly [string, (java: string)
|
||||
/** Java's words around a value, as its programs join them („Verbindung zu“ + address + „hergestellt“). */
|
||||
const FROM_JAVA_JOINED: Readonly<Record<string, readonly [string, string, string]>> = {
|
||||
'server.connectionAccepted': ['sw_serveranwendung_msg4', '{address}', 'sw_serveranwendung_msg5'],
|
||||
'simpleClient.connectionClosed': ['sw_clientbaustein_msg5', '{address}', 'sw_clientbaustein_msg6'],
|
||||
'server.connectionClosed': ['sw_servermitarbeiter_msg1', '{address}', 'sw_servermitarbeiter_msg2'],
|
||||
'emailServer.created': ['emailserver_msg22', '{name}', 'emailserver_msg23'],
|
||||
'mail.stored': ['sw_smtpmitarbeiter_msg12', '{name}', 'sw_smtpmitarbeiter_msg13'],
|
||||
|
||||
@@ -6,8 +6,8 @@ import { readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import type { ServerLogEntry } from '@mdg-filius/core';
|
||||
import { serverLine } from '../src/desktop/serverLines.js';
|
||||
import type { ServerLogEntry, SimpleClientLogEntry } from '@mdg-filius/core';
|
||||
import { serverLine, simpleClientLine } from '../src/desktop/serverLines.js';
|
||||
import { translate } from '../src/i18n/i18n.js';
|
||||
|
||||
const java = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../sim/test/browserWindow.java.json'), 'utf8')) as { steps: { step: string; log?: string }[] };
|
||||
@@ -39,3 +39,42 @@ describe("a server's lines", () => {
|
||||
expect(serverLine({ kind: 'connectionAccepted', address: '1.2.3.4', port: 5 }, (key, values) => translate('en', key, values))).toBe('Connection to 1.2.3.4:5 established');
|
||||
});
|
||||
});
|
||||
|
||||
// The echo windows' lines against Java's (packages/sim/test/echoWindow.java.json, EchoWindowRun).
|
||||
const echo = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '../../sim/test/echoWindow.java.json'), 'utf8')) as {
|
||||
steps: { step: string; server: { log: string }; client: { output: string } }[];
|
||||
};
|
||||
|
||||
describe("the echo windows' lines", () => {
|
||||
it("are Java's, line by line, the server's and the client's", () => {
|
||||
const last = echo.steps.at(-1)!;
|
||||
const [, port] = /Verbindung zu 192\.168\.0\.20:(\d+) hergestellt/.exec(last.server.log)!;
|
||||
const server: ServerLogEntry[] = [
|
||||
{ kind: 'acceptingStarted' },
|
||||
{ kind: 'connectionAccepted', address: '192.168.0.20', port: Number(port) },
|
||||
{ kind: 'received', text: 'Zeile 1\nZeile 2' },
|
||||
{ kind: 'sent', text: 'Zeile 1\nZeile 2' },
|
||||
{ kind: 'acceptingStopped' },
|
||||
{ kind: 'connectionClosed', address: '192.168.0.20', port: Number(port) },
|
||||
{ kind: 'serverSocketClosed' },
|
||||
];
|
||||
for (const entry of server) expect(last.server.log, entry.kind).toContain(`${serverLine(entry, t)}\n`);
|
||||
const client: SimpleClientLogEntry[] = [
|
||||
{ kind: 'connected' },
|
||||
{ kind: 'sent', text: 'Hallo Echo' },
|
||||
{ kind: 'received', text: 'Hallo Echo' },
|
||||
{ kind: 'connectionClosed', address: '192.168.0.30', port: 55555 },
|
||||
{ kind: 'connectFailed', failure: 'timedOut' },
|
||||
{ kind: 'disconnected' },
|
||||
{ kind: 'connectFailed', failure: 'unresolved' },
|
||||
];
|
||||
for (const entry of client) expect(last.client.output, entry.kind).toContain(`${simpleClientLine(entry, t)}\n`);
|
||||
// Not in this story, in Java's words all the same (sw_clientbaustein_msg4, sw_tcpsocket_msg3, msg9, msg6).
|
||||
expect([
|
||||
simpleClientLine({ kind: 'notConnected' }, t),
|
||||
simpleClientLine({ kind: 'connectFailed', failure: 'failed' }, t),
|
||||
simpleClientLine({ kind: 'receiveFailed' }, t),
|
||||
simpleClientLine({ kind: 'sendFailed', failure: 'notConnected' }, t),
|
||||
]).toEqual(['Fehler beim Verbindungsaufbau', 'Fehler beim Verbindungsaufbau\nAktives Öffnen des Sockets fehlgeschlagen', 'Keine Verbindung hergestellt!', 'Verbindung nicht aufgebaut!']);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user