44 lines
3.4 KiB
Bash
44 lines
3.4 KiB
Bash
#!/usr/bin/env bash
|
||
# Row 76 round 2, Darkwing's mutants. Run from the candidate worktree root:
|
||
# bash mutants.sh <mut.mjs>. Round 1's 16 with anchors updated to round 2's lines
|
||
# and every page or Reply mutant pointed at send-browser, then 6 aimed at round 2's
|
||
# changes. Each mutant edits one site, runs one test file, and restores the file
|
||
# from the worktree index.
|
||
set -u
|
||
M=$1
|
||
W=packages/webui
|
||
S=$W/src/serve.mjs B=$W/src/bus.mjs C=$W/src/cli.mjs P=$W/src/public/bus.js A=$W/src/public/app.js
|
||
run() { # name file from to testfile
|
||
local name=$1 f=$2 from=$3 to=$4 t=$5
|
||
echo "== $name"
|
||
if ! node "$M" "$f" "$from" "$to"; then echo "$name: DID NOT APPLY"; return; fi
|
||
node --test "$W/tests/$t.test.mjs" 2>&1 | grep -E '^ℹ (pass|fail)|^✖ ' | grep -v '^✖ failing tests' | sort -u | sed "s/^/$name: /"
|
||
git checkout -q -- "$f"; echo "restored"
|
||
}
|
||
REFUSED='const refused = err.status >= 400 && err.status < 500 && err.status !== 408;'
|
||
PAGE4XX='((res.status >= 400 && res.status < 500 && res.status !== 408) || body?.sent === false)'
|
||
# Round 1's 16.
|
||
run cli-no-bus-ok "$C" ' if (sendOn) throw new Error(`--send needs the bus configured (${why})`);' '' send
|
||
run start-send-nonfunction "$S" "(preview === null || typeof send !== 'function')" '(preview === null)' send
|
||
run open-no-invalid-response "$B" "const OPEN = ['outcome-unknown', 'invalid-response', 'response-too-large'];" "const OPEN = ['outcome-unknown', 'response-too-large'];" send
|
||
run open-no-too-large "$B" "const OPEN = ['outcome-unknown', 'invalid-response', 'response-too-large'];" "const OPEN = ['outcome-unknown', 'invalid-response'];" send
|
||
run nonbus-definite "$B" "err instanceof BusReadError ? err.code : 'outcome-unknown'" "err?.code ?? 'invalid-request'" send
|
||
run missing-to-passes "$S" " || !('to' in value)" '' send
|
||
run route-any-method "$S" " if (req.method !== 'POST') return json(res, 405, { error: 'method not allowed' });" '' send
|
||
run status-mnf-502 "$B" "'message-not-found': 400, " '' send
|
||
run success-unlogged "$S" ' line(`id=${result.id}`);' '' send
|
||
run page-never-clears "$P" "if (draft.body === text) draft.body = '';" '' send-browser
|
||
run page-caret-lost "$P" " if (k.caret && el.tagName === 'TEXTAREA') { el.setSelectionRange(k.caret[0], k.caret[1]); el.scrollTop = k.caret[2]; }" '' send-browser
|
||
run page-sentfalse-ignored "$P" "$PAGE4XX" '(res.status >= 400 && res.status < 500 && res.status !== 408)' send-browser
|
||
run page-no-config-gate "$P" "if (c?.send === true) {" "if (c) {" send-browser
|
||
run page-composer-always "$P" " if (!canSend) return '';" '' send-browser
|
||
run app-reply-4xx-unknown "$A" "$REFUSED" 'const refused = false;' send-browser
|
||
run app-reply-5xx-refused "$A" "$REFUSED" 'const refused = err.status >= 400 && err.status !== 408;' send-browser
|
||
# Round 2's changes.
|
||
run page-code-never "$P" '${r.message.includes(`(${r.code})`) ? '"''"' : ` (<code>${txt(r.code)}</code>)`}' '' send-browser
|
||
run page-code-any-paren "$P" 'r.message.includes(`(${r.code})`)' "r.message.includes('(')" send-browser
|
||
run page-prefix-anywhere "$P" "body.message.replace(/^not sent: /, '')" "body.message.replace(/not sent: /g, '')" send-browser
|
||
run page-408-only-with-body "$P" "$PAGE4XX" '((res.status >= 400 && res.status < 500 && (res.status !== 408 || body?.error)) || body?.sent === false)' send-browser
|
||
run app-reply-4xx-all "$A" "$REFUSED" 'const refused = err.status >= 400 && err.status < 500;' send-browser
|
||
run send-log-uncut "$S" 'JSON.stringify(to.slice(0, 64))' 'JSON.stringify(to)' send
|