Files
stack/agents/darkwing/work/queue-81-review/r1/mutants.sh
T

55 lines
3.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Darkwing row 81 review mutants: single-site edits to the candidate in WORKTREE,
# at sites Dewey's 17 don't name. Each backs up one file, edits one site with
# queue-59-review/r1/mut.mjs (exactly one match, else BAD-SITE), runs the named
# test files and restores the backup.
# Usage: mutants.sh WORKTREE (TMPDIR must be set; outputs go there)
set -u
WT="$1"
MUT="$(cd "$(dirname "$0")/../../queue-59-review/r1" && pwd)/mut.mjs"
cd "$WT" || exit 1
BR=packages/bus/src/broker.mjs SV=packages/webui/src/serve.mjs PG=packages/webui/src/public/bus.js
BT="tests/replies.test.mjs" WT1="tests/bus.test.mjs" WB="tests/send-browser.test.mjs"
m() { # name file pkg tests from to
local name="$1" file="$2" pkg="$3" tests="$4" from="$5" to="$6"
cp -- "$file" "$TMPDIR/mut.bak"
if ! node "$MUT" "$file" "$from" "$to"; then echo "$name BAD-SITE"; cp -- "$TMPDIR/mut.bak" "$file"; return; fi
if (cd "packages/$pkg" && node --test $tests > "$TMPDIR/$name.out" 2>&1); then
echo "$name SURVIVED"
else
echo "$name killed: $(grep -E '^✖ ' "$TMPDIR/$name.out" | grep -v 'failing tests' | sort -u | sed 's/ ([0-9.]*ms)$//' | tr '\n' ';')"
fi
cp -- "$TMPDIR/mut.bak" "$file"
}
# The broker.
m exists-any-business $BR bus $BT "'SELECT id FROM messages WHERE id=? AND business=?', a.id, s.business))" "'SELECT id FROM messages WHERE id=?', a.id))"
m replies-to-human $BR bus $BT "WHERE business=? AND in_reply_to=? ORDER BY seq LIMIT \${REPLIES}\`,
s.business,
a.id," "WHERE business=? AND to_role=? ORDER BY seq LIMIT \${REPLIES}\`,
s.business,
'human',"
m no-identifier $BR bus $BT " keys(a, ['id'], ['id']);
identifier(a.id);" " keys(a, ['id'], ['id']);"
m human-only $BR bus $BT "if (!s.human && !s.reader) fail('human-required');
keys(a, ['id'], ['id']);" "if (!s.human) fail('human-required');
keys(a, ['id'], ['id']);"
# The server.
m id-check-after-bus $SV webui $WT1 " if (verb === 'replies') {
arg = new URLSearchParams(search).get('id');
if (!subjectOk(arg)) return json(res, 400, { error: 'invalid-request', message: 'id must be a message id' });
}
if (!bus) return json(res, 503, { error: 'not-configured', message: 'the Console has no bus configured' });" " if (!bus) return json(res, 503, { error: 'not-configured', message: 'the Console has no bus configured' });
if (verb === 'replies') {
arg = new URLSearchParams(search).get('id');
if (!subjectOk(arg)) return json(res, 400, { error: 'invalid-request', message: 'id must be a message id' });
}"
# The page.
m shows-to-role $PG webui $WB '${txt(m.from_role)} ${when(m.at)}' '${txt(m.to_role)} ${when(m.at)}'
m link-to-send $PG webui $WB '<a href="#/trail/message/${enc(m.id)}">trail</a>' '<a href="#/trail/message/${enc(receipt.id)}">trail</a>'
m any-receipt-reads $PG webui $WB " if (receipt?.kind === 'sent') {
const r = receipt;" " if (receipt) {
const r = receipt;"
m failure-keeps-old $PG webui $WB "if (receipt === r) replies = Array.isArray(rows) ? rows : null;" "if (receipt === r && Array.isArray(rows)) replies = rows;"