feat(fls): Java's view of the e-mail programs

The Java view now reads what FILIUS 2.14 keeps for its e-mail programs:
the server's domain, switch and bean accounts with their mailboxes, and the
accounts of /mailserver/konten.txt, which Java reads at every simulation
start and which so win over the bean list; the client's three folders and
address book, and its account from /konten.txt (no bean holds it).

javaEmail.ts ports the bean setters and both file readers
(stringZuListeBenutzerkonten, EmailKonto(String)); javaString.ts Java's
trim, split and StringTokenizer; javaFileSystem.ts the file lookup, now
shared with the DNS server, with the four non-ASCII units Java's
equalsIgnoreCase also takes for an ASCII letter (measured over the BMP).

Checked against Java on the corpus (the oracle dumps the e-mail state) and
on 43 account files read by EmailServer.kontenLaden and
EmailAnwendung.laden (EmailFileCases). Found: older files keep recipients
as strings in the typed lists; a getter copy of the sender is filled and
set back; one short server line makes Java throw for the whole file; a
message with an empty text is lost on reading; a broken last client line
empties the account.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-30 07:06:55 +00:00
co-authored by Claude Opus 5.5
parent c80d212c90
commit ec5523d7c7
22 changed files with 2900 additions and 94 deletions
+1 -23
View File
@@ -8,8 +8,7 @@ import { readFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import type { FlsFileTree } from '../src/index.js';
import { dnsRecordsOf, javaHostsFileContent, readJavaDnsHosts } from '../src/dnsHosts.js';
import { dnsRecordsOf, readJavaDnsHosts } from '../src/dnsHosts.js';
const here = dirname(fileURLToPath(import.meta.url));
type Row = [string, string, number, string];
@@ -186,24 +185,3 @@ describe('the records Java answers', () => {
expect(warnings).toEqual(["DNS record 'www.filius.de A .1.2.3' has no usable IPv4 address, left out (it stays in /dns/hosts)"]);
});
});
describe('javaHostsFileContent', () => {
const file = (name: string, content: string | null): FlsFileTree => ({ kind: 'file', name, type: 'text', content, children: [] });
const directory = (name: string, ...children: FlsFileTree[]): FlsFileTree => ({ kind: 'directory', name, children });
it('finds /dns/hosts ignoring case, as Java does', () => {
expect(javaHostsFileContent(directory('root', directory('DNS', file('Hosts', 'x'))))).toBe('x');
expect(javaHostsFileContent(directory('root', directory('dns', file('ho\u017Fts', 'long s'))))).toBe('long s');
});
it('takes the first match in preorder, and nothing when that is a directory', () => {
expect(javaHostsFileContent(directory('root', directory('dns', file('hosts', 'first')), directory('DNS', file('hosts', 'second'))))).toBe('first');
expect(javaHostsFileContent(directory('root', directory('dns', directory('hosts'), file('HOSTS', 'later'))))).toBeUndefined();
});
it('is undefined without the file, and empty for a file without content', () => {
expect(javaHostsFileContent(undefined)).toBeUndefined();
expect(javaHostsFileContent(directory('root', file('hosts', 'x')))).toBeUndefined();
expect(javaHostsFileContent(directory('root', directory('dns', file('hosts', null))))).toBe('');
});
});