Skip to content

tests/test_doctor_legs_members_next.py: the fixed words of the explanations its checkout scenarios reach are held clear of shell syntax over a root that needs quoting, and the file says the PowerShell form of a line is checked as text, by two tests, and run by no job (#415) - #899

Merged
brettheap merged 4 commits into
mainfrom
fix/415-legs-members-next-tests
Oct 18, 2026

Conversation

@brettheap

@brettheap brettheap commented Oct 18, 2026 •

Copy link
Copy Markdown
Contributor

Lane: openreposhape-1 (openRepoShape-1)
Claim: #415 (comment)

A v1.2.0 draft, authored on the v1.1.1 release commit 5017830. Lane 3 placed #415 in v1.2.0 (#473, issuecomment-6250991055). It changes tests/test_doctor_legs_members_next.py only. shape-doctor.py is unchanged.

N7: the "no character a pasted tail would break on" test held only by accident

The test asserted that the explanation holds none of ;, ', a backtick or a parenthesis. That held only because pytest's temporary roots need no quoting. Over a root like my atlas, the keep line is git -C '<root>/my atlas/spec' branch NAME, and the old test fails on the '. Lane 1's writer measured this over the detached scenario.

Since #415 was filed, #277 has landed. The sentence is the row's why, on its own WHY line, and is no longer a pasted # tail. submodule_update_next's docstring now says the no-;' rule "no longer binds it". So the old test claimed more than the code needs.

Now:

  • A new helper, assert_fixed_words_are_plain(why, *spelled):
    • it asserts that each quote_arg-spelled path is in why, so the check cannot pass vacuously;
    • it replaces each path with PATH;
    • it holds the fixed words that remain clear of the five characters.
  • The restated test, test_the_explanations_fixed_words_hold_no_shell_syntax_over_a_quoted_root:
    • it runs the five scenarios over two roots that need quoting, my atlas and do ct'or, each a copy of the project, so the doctor's real row is read;
    • the keep line is cut from why, and shlex.split of it must give ["git", "-C", "<mount>", "branch", "NAME"]. That check is skipped on Windows, where PowerShell doubles an apostrophe.
  • Three more tests carried the same loop, and now use the helper: #413a and #413c, over a sentence that names a quoted path, and the members git line, whose sentence names no path. That last one passes no path, so there the helper reads the whole of why, as the loop it replaced did.

Mutants (in shape-doctor.py, restored after each):

Mutant Restated test Old test, over pytest's roots
M1: a ' in submodule_update_next's fixed words 15 fail, counting the converted sites 5 fail
M2: a ' in checkout_notes's keep-line sentence 2 fail (the detached scenario, both roots) 1 fails
M3: the keep line's path left unquoted 2 fail (No closing quotation, or a wrong split) all pass

N6: the PowerShell form of the line is never run

This is documented, not tested.

Left alone: the precedent tests/test_shape_doctor.py::test_a_template_validators_next_runs_when_pasted_into_powershell (line 10493) is likewise never run by CI. Its docstring still names the tests-windows job that #597 dropped. That is outside #415.

Review

Lane 1's independent reviewer r415 (sonnet):

  • CHANGES at 1ce9a8c8. SHOULD S1: the docstring called that test "THE ONLY CHECK OF THE POWERSHELL FORM", and there are two. NITs N1 to N5.
  • The fix round is docstrings and comments only: 732696c8 (S1, N1, N2 and N3), and fbfcc9e8, which closes S1's sentence with a full stop.
  • READY at fbfcc9e8. Outside docstrings, the AST is unchanged from 1ce9a8c8, and each new sentence was checked against the code it names.
  • Left alone:
    • N4: CHECKOUT_SCENARIOS never reaches rerun_sentence, since rerun is set only when a pin is missing or differs from the gitlink. A ( there survives this test, as it survived the old one. So the title now claims the fixed words of the explanations these scenarios reach, not every explanation.
    • N5: the runtime of eight cases with no path in their sentence.

Tests

Run with /usr/bin/python3 -m pytest, a stub gh first on PATH, a bogus GH_TOKEN, an empty GH_CONFIG_DIR and GIT_CONFIG_GLOBAL=/dev/null:

File Result
tests/test_doctor_legs_members_next.py 186 passed, 6 skipped. The skips are git 2.43 behaviours. The file has 192 tests, up from 187.
tests/test_repo_hygiene.py 78 passed
tests/test_doctor_paste_through_git.py and tests/test_no_auto_maintenance.py 79 passed, 2 skipped

No added line is over 79 columns, the change is ASCII, and git diff --check is clean.

Closes #415

🤖 Generated with Claude Code

Summary by Sourcery

Harden doctor explanation tests against shell syntax regressions across quoted roots and clarify the limits of PowerShell coverage.

Bug Fixes:

  • Strengthen shell-safety coverage for doctor explanations by testing quoted repository roots and validating extracted keep commands as parsed arguments.

Enhancements:

  • Replace the broad explanation-character checks with reusable assertions that distinguish quoted paths from fixed explanatory text.
  • Document that PowerShell command forms are validated as text only because the relevant test file is not run by CI on Windows.

Tests:

  • Expand checkout explanation tests to cover roots containing spaces and apostrophes, including POSIX shell parsing of keep lines.
  • Apply the shared fixed-word shell-syntax checks across related explanation and members-git-line tests.

… are held clear of `;`, `'`, a backtick and a parenthesis over a root whose path needs quoting, and each keep line is read back by `shlex` as one path, so a `'` in the words fails and the quoting of a path does not, and the file says the PowerShell form of a line is checked as text and run by no job (#415)

N7. The test that the sentence holds none of the five characters read the
whole `why` over pytest's temporary roots, which need no quoting, so it
held by accident: over a root with a space the detached leg's keep line is
`git -C '<root>/spec' branch NAME`, and the old test fails on its `'`
(measured: 4 of 5 scenarios pass, the detached one fails). It is now
`test_the_explanations_fixed_words_hold_no_shell_syntax_over_a_quoted_root`,
over a copy of the project at `my atlas` and at `do ct'or` (a space and an
apostrophe). Each path the sentence names is put as `PATH` before the words
are read (`assert_fixed_words_are_plain`), and the keep line is read as `sh`
reads it: `shlex.split` gives `git -C <mount> branch NAME` with the mount as
one argument. Mutants in shape-doctor.py, each restored after: a `'` in the
words every scenario carries (`isn't`) and a `'` only in the keep-line
sentence (`one's`) fail the new test, and so does a keep line whose path is
not quoted, which the old test passes over pytest's roots. The same whole-
sentence loop at three more sites (the members git line, #413 a and #413 c)
is replaced by a call of the same helper.

N6. The PowerShell form is asserted as text only
(`test_the_line_is_spelled_for_the_readers_shell`) and every paste test is
`WINDOWS_SKIP`. No Windows-only test is added: `tests.yml` runs the suite on
ubuntu-latest alone since #597, and its one Windows job, `tests-git-bash`,
runs three launcher and installer files, so a `skipif(os.name != "nt")` test
here would be skipped by every runner. The module docstring, the section
header and that test's docstring now say so, and that
`test_a_template_validators_next_runs_when_pasted_into_powershell` in
test_shape_doctor.py, the precedent the issue names, is no better placed.

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@brettheap brettheap added this to the v1.2.0 milestone Oct 18, 2026
@sourcery-ai

sourcery-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR revises the doctor explanation tests to distinguish fixed prose from quoted paths, exercising real rows over roots containing spaces and apostrophes and validating copied POSIX commands structurally. It also documents that PowerShell output is checked only as text because this test module has no Windows CI job.

File-Level Changes

Change Details Files
Strengthen shell-safety assertions for explanation text and copied keep commands when repository roots require quoting.
  • Add a helper that verifies expected quoted paths are present, masks path-specific shell syntax, and checks fixed words.
  • Exercise checkout explanations across roots containing spaces and apostrophes.
  • Parse each extracted POSIX keep command with shlex and verify the quoted path remains one argument.
  • Apply the helper to the related members, 413a, and 413c explanation tests.
  • Increase mutation-test coverage for fixed-word punctuation and unquoted paths.
tests/test_doctor_legs_members_next.py
Document that PowerShell command forms are validated as generated text rather than executed.
  • Clarify in the module documentation that this test file runs on Ubuntu and has no Windows CI coverage.
  • State that the reader-shell test is the only check of the PowerShell form and does not invoke PowerShell.
  • Update section headings and explanatory comments to distinguish cross-platform text assertions from executable POSIX-shell tests.
tests/test_doctor_legs_members_next.py
Update test setup and imports to support quoted-root scenarios.
  • Import shlex for POSIX command parsing.
  • Reuse the awkward-root fixture value and define parametrized quoted roots.
  • Copy the project into each quoted root before running scenarios.
  • Capture the created leg path needed for validating the generated explanation.
tests/test_doctor_legs_members_next.py

Assessment against linked issues

Issue Objective Addressed Explanation
#415 Add a Windows-only test that pastes the PowerShell-form legs git line into PowerShell and verifies it succeeds and leaves the legs row healthy, including coverage for a root path with a space. ❌ The PR explicitly documents that the PowerShell form is checked only as text and is never run. It adds no PowerShell execution test, so the issue’s requested runtime verification remains unimplemented.
#415 Correct the shell-syntax assertion so it checks the fixed words of the explanation independently of quoted paths, and verify keep-line quoting under roots that require quoting. ✅

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Brett Heap and others added 2 commits October 18, 2026 15:05
…hell form is checked as text by two tests and run by no job, that the text-level tests give way on Windows only where `shlex` or a non-UTF-8 name cannot, and that `assert_fixed_words_are_plain` reads all of `why` where it is passed no path (#415)

Review r415 of PR #899 at 1ce9a8c:

S1. `test_the_line_is_spelled_for_the_readers_shell` called itself the
only check of the PowerShell form. `test_413a_the_kept_repositorys_keep_
line_is_spelled_for_the_readers_shell` asserts the `platform="nt"` spelling
of the `--git-dir=` and `--work-tree=` keep line too. Both are named, in
that docstring and in the module's, and "no job could" is "no job does".

N2. The module docstring said the text-level assertions carry no skip. They
give way on Windows in two places of their own: a member named in bytes
(the command line cannot carry it) and the keep line of the quoted-root
test, whose `shlex` read is skipped there. It says so.

N3. `assert_fixed_words_are_plain` said a sentence that names nothing fails.
That holds where a path is passed. Passed none, as the members git line is,
it reads the whole of `why`, which is the loop it replaced. It says so.

N1. The `os.name` skip of that `shlex` read is kept and has its reason:
PowerShell doubles an apostrophe, which `shlex` misreads; Git Bash is
`host_shell_dialect() == "posix"`, where `shlex` is right; and no job runs
this file on Windows today.

Docstrings and one comment only: no assertion changes.

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ne_is_spelled_for_the_readers_shell` closes the sentence that names the #413 a spelling test with a full stop (#415)

The name was on a line of its own, in backticks, and "No test in this file
runs the form" followed it with no stop. With the backticks and a stop the
line would be 80 columns, so the name is written without them, at 78. The
module docstring's paragraph naming both tests reads as one sentence
("`a` and `b` ask `quote_arg` for it") and has no such gap.

Docstring only: no code changes.

Lane: openreposhape-1 (openRepoShape-1)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@brettheap brettheap changed the title tests/test_doctor_legs_members_next.py: the explanation's fixed words are held clear of shell syntax over a root that needs quoting, and the file says the PowerShell form of a line is checked as text and run by no job (#415) tests/test_doctor_legs_members_next.py: the fixed words of the explanations its checkout scenarios reach are held clear of shell syntax over a root that needs quoting, and the file says the PowerShell form of a line is checked as text, by two tests, and run by no job (#415) Oct 18, 2026
@brettheap

Copy link
Copy Markdown
Contributor Author

(lane openRepoShape-1, 2026-10-18T15:11:52Z) Independent review of #899 (#415), by lane 1's reviewer r415 (sonnet), who is not its writer: READY at fbfcc9e8.

Round 1, at 1ce9a8c8: CHANGES.

  • SHOULD S1. test_the_line_is_spelled_for_the_readers_shell called itself "THE ONLY CHECK OF THE POWERSHELL FORM". test_413a_the_kept_repositorys_keep_line_is_spelled_for_the_readers_shell also asserts the platform="nt" spelling.
  • NIT N1. The shlex skip covers Git Bash too.
  • NIT N2. The module docstring said "carry no skip".
  • NIT N3. The helper's docstring overstated what a call with no path checks.
  • NIT N4. rerun_sentence is never reached by these scenarios. That gap was already there.
  • NIT N5. Eight cases add runtime only.
  • Mutants: X2, X3, X4, X5, X8, X9, X11 and X12 were caught. X1, a ( in rerun_sentence, survives (N4).

The fix round is docstrings and comments only: 732696c8 took S1, N1, N2 and N3, and fbfcc9e8 closes S1's sentence with a full stop.

Round 2, at fbfcc9e8: READY, with no new finding.

  • Every new sentence is true of the code it names: repo_shape.py's host_shell_dialect, the 36 WINDOWS_SKIP tests, and the two platform="nt" checks.
  • With docstrings blanked, the AST is unchanged.
  • No added line is over 78 columns, and git diff --check is clean.
  • Runs:
    • -k "spelled or plain": 3 passed;
    • the restated and converted tests: 15 passed;
    • tests/test_repo_hygiene.py: 78 passed;
    • the whole file at 732696c8: 186 passed, 6 skipped.

N4 and N5 are left. The title now claims only the explanations the scenarios reach, and the body says why.

Lane: openreposhape-1 (openRepoShape-1)

@sonarqubecloud

Copy link
Copy Markdown

@brettheap
brettheap marked this pull request as ready for review October 18, 2026 17:38
@sourcery-ai

sourcery-ai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Sorry @brettheap, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 1 day and 7 hours by commenting @sourcery-ai review. Upgrade to get a review now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment