Skip to content

tests/test_adopt_plan_paths_spelled.py: follow-up of PR #1154 (#1115) from its review: seven mutants of the plan written to and cloning ... into lines that none of its 18 rows kills (R1-R4, R6, R7, R12) #1167

Open

Description

@brettheap

(lane openRepoShape-4, 2026-10-22T17:32:16Z)

Found by: RV1115, the independent review of PR #1154 (for #1115) at 8a782733 (#1154 issuecomment-6344547992). It found no MUST and no SHOULD, and graded this one N2 (NIT). Its other NIT, N1, was a sentence of the PR body, which lane 4 has corrected; the two cases N1 names are rows here too (R1). Line numbers are approximate: at 038dafba9 (current origin/main) and at 8a7828332 (#1154's head).

What is missing

Nothing a user can see: there is no limit here. #1154's code is right on every case below. RV1115 probed each one, and F3 measured each again on 8a7828332. But seven of RV1115's mutants (R1, R2, R3, R4, R6, R7 and R12) leave the PR's whole test file, tests/test_adopt_plan_paths_spelled.py (18 rows), green, so a later change could break one of these behaviours and no test would fail.

The two lines are Source.clone's cloning {repository} (read only) into {path} (about :2762 at 038dafba9, :2766 at 8a7828332) and cmd_plan's plan written to {out} (about :6338 at 038dafba9, :6345 at 8a7828332), both spelled with _shown (about :3512 at 038dafba9, :3517 at 8a7828332). On 038dafba9 both are still raw: #1154 is a draft and not on main, and the test file is new in it. So these rows go into the file after #1154 lands, or onto #1154's branch if the lane rules so. No change to adopt-project.py.

Rows to add

<D> is the test's tmp_path, and <realpath D> is os.path.realpath of it, as where_the_clone_goes reads it. Every expected line below is what 8a7828332 prints (F3's probes, a stub gh first on PATH, stdout utf-8:surrogateescape). Keep the file's rules: ASCII source (each non-ASCII character an escape), POSIX only, a gh stand-in that refuses for --work-dir.

  • R2 and R3: a printable non-ASCII path prints as it was typed. --out <D>/pl\u00e9an.yaml and --work-dir <D>/wd\u00e9k (the character U+00E9, written as the escape). Expected, with no backticks and the character itself:

    plan written to <D>/pl<U+00E9>an.yaml
    cloning testorg/Thing (read only) into <realpath D>/wd<U+00E9>k/source-readonly/Thing
    

    Mutants: R2 spells every non-ASCII --out; R3 does it for --work-dir.

  • R6 and R7: ESC and CR in both flags, and a --work-dir that is not UTF-8. Add \x1b and \r to CHARACTERS (:54 at 8a7828332), which feeds the --out rows and the --work-dir rows alike. Expected `<D>/pl\x1ban.yaml` and `<D>/pl\ran.yaml` on the plan written to line, and the same two spellings in wd...k on the cloning line. Then one --work-dir row with a lone surrogate in the argument (os.fsencode gives the byte 0xff; tests/test_stdout_encoding.py's --out row shows how, with skip_where_a_name_cannot_be_not_utf_8):

    cloning testorg/Thing (read only) into `<realpath D>/wd\udcffk/source-readonly/Thing`
    

    Mutants: R6 spells only Cf, line feed and tab for --out (ESC, CR and a surrogate stay raw); R7 does it for --work-dir. For --out the non-UTF-8 case is already asserted by tests/test_stdout_encoding.py, which RV1115 did not run against R6.

  • R4: a relative --out. --out plan.yaml and --out ./plan.yaml, run with cwd=tmp_path so the plan is written there. Expected for both: plan written to plan.yaml (Path drops the ./). Mutant R4 prints _shown(os.path.abspath(out)). The file's dot-segment row is <D>/./adoption-plan.yaml, which is absolute already, so it cannot catch it.

  • R1 (N1's two cases): an --out that is printable and still spelled. Both are _shown's rule from adopt-project.py: a kept or dropped name reaches the split commit and the pull request body unspelled, and _spelled, _shown and plan's report print text that reads as another name, or raw #900, and the output is correct. Run with cwd=tmp_path:

    • --out 'plan.yaml ' (a trailing space) expects plan written to `plan.yaml `;
    • --out '`plan.yaml`' (a relative path that begins and ends with a backtick) expects plan written to `\x60plan.yaml\x60`.

    Mutant R1 spells --out by isprintable() alone, with neither rule. A --work-dir cannot reach either case: it prints as <realpath>/source-readonly/<repo>, which neither ends in a space nor begins with a backtick.

  • R12: check and execute say the same cloning line. Source.clone prints it for plan, check and execute alike, and the PR body says so; only plan is run today. Two rows, each with the refusing gh, where <P> is a plan that plan wrote from a local source: check --plan <P> --source testorg/Thing --work-dir <D>/wd<U+202E>k and execute --plan <P> --source testorg/Thing --work-dir <D>/wd<U+202E>k. Expected for both: exit 2, REFUSED source-unclonable on stderr, and

    cloning testorg/Thing (read only) into `<realpath D>/wd\u202ek/source-readonly/Thing`
    

    Mutant R12 spells the line only where the caller keeps a made list. Which row kills it: RV1115 asked for the check row, but main sets args.clones = [] for every command (about :17754 at 038dafba9), so plan and check both hand Source.clone a made list and only execute hands it none (its clone is kept; see Source.clone's docstring, about :2740). F3 ran R12 (_shown(str(path)) if made is not None else str(path)) on 8a7828332: plan and check printed the spelled line, execute printed the U+202E raw. So the execute row is the one that kills R12 and the check row is not; add both, check for its own line.

Done when

Each new row passes on 8a7828332 and fails on its mutant (RV1115's R1, R2, R3, R4, R6, R7 and R12 are defined in its comment above), with each mutant run restored and its sha256 checked.

See #1115 and #1154.

Lane: openreposhape-4 (openRepoShape-4)

Activity

  1. brettheap commented on Oct 22, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-22T19:52:46Z, for #1167

    Logged in lanes/log/openRepoShape-4.md at 645fccd6e051ed86bf5e5fd0a3f90291983af818.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#1167:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#1167"`, kept where the row or its body names `#1167`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `1167` as a whole token:
       none
    
  2. added this to the v1.2.1 milestone on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions