#!/usr/bin/env bash # Row 63 (#1556) round 2 mutants: round 1's 18, then 7 more. Run from the candidate worktree's root: # bash mutants.sh /path/to/mut.mjs > mutants.txt # Each mutant edits one site with mut.mjs (exactly one match, else exit 3), # runs the named test files and restores the file. "killed" means the run # failed; "survived" means it passed. set -u MUT=$1 run() { local name=$1 file=$2 from=$3 to=$4; shift 4 cp -- "$file" "$file.orig" if ! node "$MUT" "$file" "$from" "$to"; then echo "$name: NO MATCH"; mv -- "$file.orig" "$file"; return fi if node --test "$@" > "${LOG:-.}/mut-$name.log" 2>&1; then echo "$name: survived" else echo "$name: killed ($(grep -m1 -o 'ℹ fail [0-9]*' "${LOG:-.}/mut-$name.log"), $(grep -m1 -o "code: '[a-z-]*'" "${LOG:-.}/mut-$name.log" || echo 'assertion'))" fi mv -- "$file.orig" "$file" } V=packages/tasks/src/verbs.mjs T=(packages/tasks/tests/verbs.test.mjs packages/tasks/tests/tree.test.mjs) H=packages/harness/src/tools.mjs HT=(packages/harness/tests/tools.test.mjs) run watch-only-writable $V $' if (!view) fail(\'project-not-installed\');\n' '' "${T[@]}" run create-root-only $V 'plan.at = { project, view: ctx.tree.get(project) };' 'plan.at = { project: ctx.project, view: ctx.view };' "${T[@]}" run create-watch-only-ok $V "if (!ctx.tree.get(project)) fail('project-not-installed');" "if (!ctx.tree.has(project)) fail('project-not-installed');" "${T[@]}" run create-project-any $V "if (!Number.isSafeInteger(project) || project < 1) fail('invalid-request');" '' "${T[@]}" run move-root-view $V 'const to = args.state === undefined ? fields.bucket : view.ids[args.state];' 'const to = args.state === undefined ? fields.bucket : ctx.view.ids[args.state];' "${T[@]}" run move-path-root-view $V '`/projects/${project}/views/${view.id}/buckets/${to}/tasks`' '`/projects/${project}/views/${ctx.view.id}/buckets/${to}/tasks`' "${T[@]}" run close-root-done $V '`/projects/${project}/views/${view.id}/buckets/${view.done}/tasks`' '`/projects/${project}/views/${view.id}/buckets/${ctx.view.done}/tasks`' "${T[@]}" run read-root-board $V 'bucket = (await board(ctx, at.project, at.view)).get(id)?.bucket;' 'bucket = (await board(ctx)).get(id)?.bucket;' "${T[@]}" run read-no-project $V "if (x.json.project_id !== at.project) fail('task-moved');" '' "${T[@]}" run relation-any-project $V $' installed(other.project);\n' '' "${T[@]}" run handle-no-located $V $' await located(plan.others ?? []);\n' '' "${T[@]}" run create-no-located $V $' await located(plan.others);\n' '' "${T[@]}" run located-no-project $V "if (x.json.project_id !== r.project) fail('task-moved');" '' "${T[@]}" run schedule-add-only $V 'plan.others = [...relations.add, ...relations.remove];' 'plan.others = [...relations.add];' "${T[@]}" run located-after-authorize $V $' await located(plan.others ?? []);\n ctx.broker.authorize(cap, verb, { decision: plan.decision, target: args.task_ref });\n' $' ctx.broker.authorize(cap, verb, { decision: plan.decision, target: args.task_ref });\n await located(plan.others ?? []);\n' "${T[@]}" run tool-project-string $H 'project: { type: "integer", minimum: 1,' 'project: { type: "string", minimum: 1,' "${HT[@]}" run tool-project-zero $H 'project: { type: "integer", minimum: 1,' 'project: { type: "integer", minimum: 0,' "${HT[@]}" run tool-project-required $H '}, ["title", "request", "requirement"]],' '}, ["title", "request", "requirement", "project"]],' "${HT[@]}" # Round 2: the survivors of Dewey's and Filbert's round 1 mutants, each a child path sent back to # the root's project or view, or the relation read cut to the first relation. R='{ ...at, project: ctx.project, view: ctx.view }' run located-first-only $V 'for (const r of list) {' 'for (const r of list.slice(0, 1)) {' "${T[@]}" run step-reread-root $V $'after = await read(at);\n } catch {\n // the re-read failed too' $'after = await read('"$R"$');\n } catch {\n // the re-read failed too' "${T[@]}" run handle-final-root $V $'after = await read(at);\n } catch {\n // handled below: a failed' $'after = await read('"$R"$');\n } catch {\n // handled below: a failed' "${T[@]}" run create-final-root $V $'after = await read(at);\n } catch {\n // handled below, as in handle()' $'after = await read('"$R"$');\n } catch {\n // handled below, as in handle()' "${T[@]}" run create-fallback-root-todo $V 'taskFields(r.json, at.view.ids.todo)' 'taskFields(r.json, ctx.view.ids.todo)' "${T[@]}" run read-done-root $V 'let bucket = at.view.done;' 'let bucket = ctx.view.done;' "${T[@]}" run close-done-root $V '(a) => a.task.done && a.bucket === view.done,' '(a) => a.task.done && a.bucket === ctx.view.done,' "${T[@]}"