Across the 85 mutations that can be read statically, 8411 characters are quoted, 2721 of them the same text in both halves. A mutation that deletes a fragment quotes the whole line twice so the halves differ in one place, and a mutation that inserts one does the same. Where the two copies drift, the mutation breaks something other than what its regression sentence names.
| Shape |
Mutations |
Chars quoted twice |
| fragment deleted |
27 |
1132 |
| fragment inserted |
12 |
711 |
| larger rewrite |
28 |
623 |
| small token swapped |
14 |
247 |
| whole snippet deleted |
3 |
0 |
| condition forced to a constant |
1 |
8 |
Two operators cover the first two shapes, each quoting one copy:
Mutation.deleting(module, snippet, regression), which is Mutation(module, snippet, "", regression). Three call sites already spell it that way, _NO_SHORTER_HEADING and _NO_NESTED_RELEASE_END in tests/update_time/domain/test_changelog.py and one in tests/update_time/sources/test_github.py.
Mutation.inserting(module, text, after, regression), which is Mutation(module, after, after + text, regression).
The other shapes are left alone. A larger rewrite has two halves that are genuinely different code. A token swap quotes its line for uniqueness rather than for context: the framework requires the snippet to occur exactly once, and == never does. Only a locator scoping a snippet to a function would shorten those, which is the largest change for the smallest of the four payoffs.
Work
Across the 85 mutations that can be read statically, 8411 characters are quoted, 2721 of them the same text in both halves. A mutation that deletes a fragment quotes the whole line twice so the halves differ in one place, and a mutation that inserts one does the same. Where the two copies drift, the mutation breaks something other than what its regression sentence names.
Two operators cover the first two shapes, each quoting one copy:
Mutation.deleting(module, snippet, regression), which isMutation(module, snippet, "", regression). Three call sites already spell it that way,_NO_SHORTER_HEADINGand_NO_NESTED_RELEASE_ENDintests/update_time/domain/test_changelog.pyand one intests/update_time/sources/test_github.py.Mutation.inserting(module, text, after, regression), which isMutation(module, after, after + text, regression).The other shapes are left alone. A larger rewrite has two halves that are genuinely different code. A token swap quotes its line for uniqueness rather than for context: the framework requires the snippet to occur exactly once, and
==never does. Only a locator scoping a snippet to a function would shorten those, which is the largest change for the smallest of the four payoffs.Work
Mutation.deleting, test-driven, since it adds behaviour to the framework.Mutation.inserting, test-driven.