@spardutti/claude-skills 2.35.0 → 2.36.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -36,12 +36,16 @@ owner_of() {
|
|
|
36
36
|
# Blaming an unreachable database for that sent one agent chasing Docker for 20 minutes.
|
|
37
37
|
mutmut_unchecked() { # mutmut_unchecked <label> <base> <count> <run log>
|
|
38
38
|
echo " $1 mutmut — UNPROVEN: $3 mutant(s) were never run."
|
|
39
|
-
|
|
39
|
+
# "Failed to run pytest with args" is one line carrying every selected test id — 20KB of
|
|
40
|
+
# them on one repo — so the line is cut. Unlisted, the gate blamed a database instead.
|
|
41
|
+
stop='Failed to run clean test|failed to collect stats|Failed to collect list of tests|Stopping early|Failed to run pytest with args|BadTestExecutionCommandsException'
|
|
40
42
|
if grep -aqsE "$stop" "$4"; then
|
|
41
43
|
echo " mutmut stopped before testing a single mutant:"
|
|
42
|
-
grep -aE "^(FAILED|ERROR) |^[A-Za-z]*Error: |$stop" "$4" | tail -8 | sed 's/^/ /'
|
|
44
|
+
grep -aE "^(FAILED|ERROR) |^[A-Za-z]*Error: |$stop" "$4" | tail -8 | cut -c1-200 | sed 's/^/ /'
|
|
43
45
|
echo " It runs the whole suite, then these tests again in one process, so a"
|
|
44
46
|
echo " test that passes alone can fail here on state an earlier test left."
|
|
47
|
+
echo " mutmut hides pytest's own error: set debug = true under [tool.mutmut]"
|
|
48
|
+
echo " and run it again to read it."
|
|
45
49
|
return
|
|
46
50
|
fi
|
|
47
51
|
echo " They are recorded \"not checked\", so the suite proved nothing"
|
|
@@ -105,3 +109,17 @@ project_key() { # project_key <owner> <tool>
|
|
|
105
109
|
case "$(family_of "$f")" in "$fam"|any) printf '%s\n' "$f"; [ -f "$f" ] && cat "$f" ;; esac
|
|
106
110
|
done; } | git hash-object --stdin
|
|
107
111
|
}
|
|
112
|
+
|
|
113
|
+
# A page test renders a whole screen, so it "kills" mutants in every util that screen calls.
|
|
114
|
+
# Backoffice ran 23 minutes that way, and hid 104 mutants no logic test checked.
|
|
115
|
+
stryker_page_tests() { # stryker_page_tests <base> <label>
|
|
116
|
+
grep -qs configFile "$1"stryker.conf* && return 0
|
|
117
|
+
pages=$(git ls-files -co --exclude-standard -- "${1:-.}" | grep -E '\.test\.[jt]sx$' \
|
|
118
|
+
| grep -vE '/(hooks|queries)/|(^|/)\.stryker-tmp/' | head -3)
|
|
119
|
+
[ -n "$pages" ] || return 0
|
|
120
|
+
echo " $2 stryker — UNPROVEN: page tests count as proof for logic, e.g."
|
|
121
|
+
printf '%s\n' "$pages" | sed 's/^/ /'
|
|
122
|
+
echo " Give Stryker a Vitest config that runs logic tests only — see"
|
|
123
|
+
echo " testing-best-practices/MUTATION-TESTING.md, \"Keep Page Tests Out Of The Run\"."
|
|
124
|
+
[ "$STATUS" = 0 ] && STATUS=2
|
|
125
|
+
}
|
|
@@ -12,8 +12,9 @@ added_files() {
|
|
|
12
12
|
git ls-files --others --exclude-standard 2>/dev/null; } | sort -u
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
has_subject() { # has_subject <test path>: a file the test is named for,
|
|
15
|
+
has_subject() { # has_subject <test path>: a file the test is named for, beside it or above its __tests__/
|
|
16
16
|
d=$(dirname "$1")
|
|
17
|
+
[ "${d##*/}" = __tests__ ] && d=$(dirname "$d")
|
|
17
18
|
stem=$(basename "$1" | sed -E 's/\.(test|spec)\.[^.]+$//')
|
|
18
19
|
while :; do
|
|
19
20
|
for e in ts tsx js jsx mjs cjs astro; do [ -f "$d/$stem.$e" ] && return 0; done
|
package/hooks/ship-gate.sh
CHANGED
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
# Exit codes:
|
|
26
26
|
# 0 clean — nothing over the line limit, nothing survived, nothing uncovered
|
|
27
27
|
# 1 findings that must be dealt with before shipping
|
|
28
|
-
# 2 ran, but could not prove the tests (a mutation tool is missing
|
|
29
|
-
# don't block; the output names
|
|
28
|
+
# 2 ran, but could not prove the tests (a mutation tool is missing, or page tests
|
|
29
|
+
# count as proof) — report, don't block; the output names the fix and where
|
|
30
30
|
#
|
|
31
31
|
# Config: the same .claude/gauntlet.conf as the Stop hook.
|
|
32
32
|
# GAUNTLET_MAX_LINES=200 the per-file limit; 0 turns the check off
|
|
@@ -271,7 +271,7 @@ for owner in $OWNERS; do
|
|
|
271
271
|
# 8 of them on one commit, all long since killed. --mutate already scopes
|
|
272
272
|
# the run to the changed hunks, so incremental buys nothing here and costs
|
|
273
273
|
# a cache that goes stale exactly the way mutmut's did.
|
|
274
|
-
CMD="${RUN}npx --no-install stryker run --mutate '${FLAGS#,}'"
|
|
274
|
+
CMD="${RUN}npx --no-install stryker run --mutate '${FLAGS#,}'"; stryker_page_tests "$base" "$label"
|
|
275
275
|
elif [ -f "$base"package.json ]; then
|
|
276
276
|
MISSING="$MISSING $label needs Stryker:
|
|
277
277
|
npm --prefix ${owner} i -D @stryker-mutator/core @stryker-mutator/vitest-runner
|