feat(editor): the simulation's properties in a sheet of their own, with a restart for everyone
Who started the simulation, "Pakete verwerfen" and the dropped packets move from the toolbar into a properties sheet beside the surface. New in it: restart the simulation, after asking. The room learns a restart message: stopped as by stop, every capture, dropped frame and program window emptied, started anew and named after who restarted; refused for readers and frozen projects, logged, and waiting for asked blobs like a start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -116,11 +116,19 @@ describe('a simulation room on F', () => {
|
||||
mia.send({ kind: 'input', node: notebook, app: 'terminal', action: 'enter', args: { line: 'ping 141.99.5.10' }, reqId: 'r1' });
|
||||
await until(() => mia.got.some((message) => message.kind === 'ack' && message.reqId === 'r1'));
|
||||
await until(() => appLines(ben).some((line) => /4 Paket\(e\) gesendet, 4 Paket\(e\) empfangen/.test(line.text ?? '')), 20_000);
|
||||
// Started anew by Ben: named him, the command line as at the start.
|
||||
const sent = ben.got.length;
|
||||
ben.send({ kind: 'restart' });
|
||||
await until(() => mia.state()?.startedBy === 'Ben');
|
||||
await until(() => ben.got.slice(sent).some((message) => message.kind === 'app' && message.from === 0));
|
||||
const anew = ben.got.slice(sent).filter((message): message is Extract<HostMessage, { kind: 'app' }> => message.kind === 'app' && message.from === 0).at(-1)!;
|
||||
expect((anew.lines as { text?: string }[]).some((line) => /Paket/.test(line.text ?? ''))).toBe(false);
|
||||
ben.send({ kind: 'stop' });
|
||||
await until(() => mia.state()?.mode === 'design');
|
||||
expect(mia.state()).not.toHaveProperty('startedBy');
|
||||
expect(server.log.lines.filter((line) => ['sim.start', 'sim.stop'].includes(line.event as string)).map(({ event, user }) => [event, user])).toEqual([
|
||||
expect(server.log.lines.filter((line) => ['sim.start', 'sim.stop', 'sim.restart'].includes(line.event as string)).map(({ event, user }) => [event, user])).toEqual([
|
||||
['sim.start', 'mia'],
|
||||
['sim.restart', 'ben'],
|
||||
['sim.stop', 'ben'],
|
||||
]);
|
||||
expect(server.sims.stats()).toEqual({ rooms: 1, people: 2, threads: [1] });
|
||||
@@ -255,6 +263,11 @@ describe('a simulation room on F', () => {
|
||||
mia.send({ kind: 'start', reqId: 'x' });
|
||||
await until(() => mia.got.some((message) => message.kind === 'error'));
|
||||
expect(mia.got.filter((message) => message.kind === 'error')).toEqual([{ v: 1, kind: 'error', code: 'frozen', reqId: 'x' }]);
|
||||
// Nor anew.
|
||||
mia.send({ kind: 'restart', reqId: 'y' });
|
||||
await until(() => mia.got.filter((message) => message.kind === 'error').length === 2);
|
||||
expect(mia.got.filter((message) => message.kind === 'error').at(-1)).toEqual({ v: 1, kind: 'error', code: 'frozen', reqId: 'y' });
|
||||
expect(mia.state()).toMatchObject({ mode: 'design' });
|
||||
// A reader is told it reads, not that it is frozen.
|
||||
const late = await person(server, project, 'Ben');
|
||||
late.send({ kind: 'start' });
|
||||
|
||||
Reference in New Issue
Block a user