Skip to main content

max / shop

5.2 KB · 95 lines History Blame Raw
1 # Mutants that NO test can kill, with the reason each one is unreachable by any
2 # test that could be written.
3 #
4 # WHY THIS IS AT THE WORKSPACE ROOT AND NOT PER-CRATE. Measured against
5 # cargo-mutants 27.1.0: the config is read from the workspace root and nowhere
6 # else. A `crates/shop-vt/.cargo/mutants.toml` is silently ignored -- both
7 # `cargo mutants -p shop-vt` from here and `cargo mutants` run inside the crate
8 # directory listed the full 191 mutants with it in place, and 170 with the same
9 # file here. So one file covers the workspace, and every pattern is qualified by
10 # the type it belongs to (`Perform::`, `Parser::`) rather than relying on scope.
11 #
12 # THE BAR IS IMPOSSIBILITY, NOT COST. A mutant that a test could kill, where
13 # nobody has written that test, does not belong here however unappealing the
14 # test looks. It stays a visible survivor with a GoingsOn task against it. The
15 # two classes are easy to conflate and the difference is the whole value of the
16 # number: an exclusion list that also absorbs "not worth it" reports zero while
17 # real coverage gaps sit underneath it.
18 #
19 # The patterns are regexes, so `+`, `*`, `|` and `.` need escaping. A bare `||`
20 # is an empty alternation and silently excludes every mutant in the crate.
21
22 exclude_re = [
23 # ===================== shop-vt =====================
24 # --- Default trait method bodies -------------------------------------
25 #
26 # Every `Perform` method has a default body of the form `let _ = args;`,
27 # which exists only to name the arguments so an implementor that wants none
28 # of them compiles without warnings. Replacing that body with `()` is the
29 # same program: the discard has no effect and the method returns `()`
30 # either way. What the parser calls is always the implementor's override,
31 # and no test can observe a default that does nothing being replaced by
32 # nothing.
33 "replace Perform::print with \\(\\)",
34 "replace Perform::execute with \\(\\)",
35 "replace Perform::csi_dispatch with \\(\\)",
36 "replace Perform::esc_dispatch with \\(\\)",
37 "replace Perform::osc_dispatch with \\(\\)",
38 "replace Perform::hook with \\(\\)",
39 "replace Perform::put with \\(\\)",
40 "replace Perform::apc_dispatch with \\(\\)",
41
42 # --- Match arms that fall through to an identical `_ => {}` -----------
43 #
44 # The state handlers are written to mirror the DEC parser's transition
45 # tables arm for arm, including the arms whose action is "nothing". Those
46 # arms document a byte range the spec calls out; deleting one lets the same
47 # bytes reach the handler's own `_ => {}`, which does the same nothing. The
48 # arms are kept because a reader checking this file against vt100.net needs
49 # to find them, and excluded because no observation distinguishes them.
50 #
51 # 0x7F (DEL) is ignored in every state that names it, which is the reason
52 # this list is mostly 0x7F.
53 "delete match arm 0x80\\.\\.= 0xBF in Parser::ground",
54 "delete match arm 0x7F in Parser::escape$",
55 "delete match arm 0x7F in Parser::escape_intermediate",
56 "delete match arm 0x7F in Parser::csi_entry",
57 "delete match arm 0x7F in Parser::csi_param",
58 "delete match arm 0x7F in Parser::csi_intermediate",
59 "delete match arm 0x7F in Parser::dcs_entry",
60 "delete match arm 0x7F in Parser::dcs_param",
61 "delete match arm 0x7F in Parser::dcs_intermediate",
62
63 # The three DCS prelude states discard C0 controls rather than executing
64 # them (unlike the CSI states, which execute). The arm's body is `{}` and
65 # the fall-through is `{}`.
66 "delete match arm 0x00\\.\\.= 0x17 \\| 0x19 \\| 0x1C\\.\\.= 0x1F in Parser::dcs_entry",
67 "delete match arm 0x00\\.\\.= 0x17 \\| 0x19 \\| 0x1C\\.\\.= 0x1F in Parser::dcs_param",
68 "delete match arm 0x00\\.\\.= 0x17 \\| 0x19 \\| 0x1C\\.\\.= 0x1F in Parser::dcs_intermediate",
69
70 # --- Clearing state that is already clear -----------------------------
71 #
72 # `ESC ESC` in the Escape state. Every route into Escape calls `clear()` on
73 # the way in (Ground, Utf8, DcsIgnore, DcsPassthrough, OscString and
74 # ApcString all do), and the only arm inside Escape that writes
75 # intermediates or parameters is 0x20..=0x2F, which leaves Escape as it
76 # writes. So the parser is never in Escape holding anything to clear, and
77 # deleting the arm leaves the byte to a `_ => {}` that also holds the state
78 # still. Kept because the DEC table names the transition.
79 "delete match arm 0x1B in Parser::escape$",
80
81 # --- A reset that its partner has always already done -----------------
82 #
83 # `apc_start` clears `apc_buf` and `string_overflow` on the way into an APC,
84 # SOS or PM body. Every route out of `ApcString` -- the BEL arm and the ESC
85 # arm, which are the only two -- calls `apc_end`, which clears both and
86 # shrinks the buffer besides. So the parser is never in Escape about to open
87 # a string while holding a previous one's bytes or its overflow flag, and
88 # the opening clear has nothing to clear. Kept because the pairing is what
89 # makes that true, and a third exit added later would need it.
90 #
91 # `osc_start` is NOT here and is caught: it also pushes the first parameter
92 # placeholder, which is work nothing else does.
93 "replace Parser::apc_start with \\(\\)",
94 ]
95