Workers P2: eventToSteps verwirft Schritte ohne Ziel bei fehlender workerId
fx() setzt 'to' jetzt immer, sobald ein drittes Argument übergeben wird; stepIsValid prüft 'to' per Object.hasOwn. Ereignis 'eingang' ohne workerId liefert keinen Umschlag ohne Ziel mehr. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3386e91916
commit
66fe0f38ef
2 files changed
+30
-2
No files matched your search
@@ -186,7 +186,9 @@ const task = (who, text) => ({ op: 'task', who, text })
|
||||
const say = (who, text) => ({ op: 'say', who, text: cutBubble(text) })
|
||||
const pose = (who, p) => ({ op: 'pose', who, pose: p })
|
||||
const give = (from, to) => ({ op: 'give', from, to })
|
||||
const fx = (name, at, to) => (to === undefined ? { op: 'fx', fx: name, at } : { op: 'fx', fx: name, at, to })
|
||||
// `to` wird gesetzt, sobald ein drittes Argument übergeben wird, auch wenn es undefined ist (z. B. fehlende workerId);
|
||||
// so bleibt ein Schritt mit unbekanntem Ziel erkennbar und wird verworfen, statt ohne Ziel zu bleiben
|
||||
const fx = (name, at, ...rest) => (rest.length ? { op: 'fx', fx: name, at, to: rest[0] } : { op: 'fx', fx: name, at })
|
||||
|
||||
// Schritte der Tabelle (Übersicht §7) für ein Ereignis, noch ungeprüft gegen Roster und Plätze
|
||||
function rawSteps(e) {
|
||||
@@ -271,7 +273,7 @@ function stepIsValid(s) {
|
||||
case 'give':
|
||||
return isWorker(s.from) && isWorker(s.to)
|
||||
case 'fx':
|
||||
return isPlace(s.at) && (s.to === undefined || isPlace(s.to))
|
||||
return isPlace(s.at) && (!Object.hasOwn(s, 'to') || isPlace(s.to))
|
||||
default:
|
||||
return isWorker(s.who)
|
||||
}
|
||||
|
||||
@@ -219,6 +219,32 @@ test('eventToSteps: jede Art liefert gültige Schritte, Blasen ≤ 20 Zeichen, U
|
||||
assert.deepEqual(E.eventToSteps(ev('uebergabe', 'rita', { to: 'zed' })), [{ op: 'task', who: 'rita', text: 'Text' }])
|
||||
})
|
||||
|
||||
test('eventToSteps: fehlende oder fremde workerId erzeugt nirgends einen Schritt ohne Ziel (Review Focus 4)', () => {
|
||||
const ids = new Set(ROLES.map((r) => r.workerId))
|
||||
const known = (v) => ids.has(v) || E.SPOTS.includes(v)
|
||||
// eingang ohne workerId: weder der Umschlag ohne Ziel noch andere Schritte bleiben übrig
|
||||
assert.deepEqual(E.eventToSteps({ kind: 'eingang', ts: TS, text: 'Text' }), [])
|
||||
assert.deepEqual(E.eventToSteps({ kind: 'eingang', ts: TS, text: 'Text', workerId: null }), [])
|
||||
assert.deepEqual(E.eventToSteps(ev('eingang', 'zed')), [])
|
||||
assert.deepEqual(E.eventToSteps(ev('eingang', 'max')).map((s) => s.op), ['task', 'fx', 'say'])
|
||||
// jede Art mit fehlender, leerer, falsch getypter und fremder workerId: jeder vorhandene Verweis (auch ein ausdrücklich undefinierter) muss bekannt sein
|
||||
for (const kind of E.EVENT_KINDS) {
|
||||
for (const w of [undefined, null, '', 7, {}, 'zed', 'system']) {
|
||||
const e = { id: `${kind}-x`, ts: TS, kind, text: 'Text', meta: { count: 3, score: 4, round: 2 } }
|
||||
if (w !== undefined) e.workerId = w
|
||||
for (const s of E.eventToSteps(e)) {
|
||||
const label = `${kind}/${String(w)}: ${JSON.stringify(s)}`
|
||||
if (s.op === 'fx') {
|
||||
assert.ok(known(s.at), label)
|
||||
if ('to' in s) assert.ok(known(s.to), label)
|
||||
} else {
|
||||
for (const k of ['who', 'from', 'to']) if (k in s) assert.ok(ids.has(s[k]), label)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('eventToSteps: kaputte Ereignisse werfen nicht, Text wird gekürzt statt verworfen', () => {
|
||||
for (const bad of [null, undefined, 7, 'x', [], {}]) assert.deepEqual(E.eventToSteps(bad), [])
|
||||
assert.deepEqual(E.eventToSteps({ kind: 'gelesen', workerId: 'kim' }), [{ op: 'pose', who: 'kim', pose: 'type' }, { op: 'task', who: 'kim', text: '' }, { op: 'say', who: 'kim', text: 'Gelesen' }])
|
||||
|
||||
Reference in new issue
Block a user