Skip to content

Fix spurious leading spaces in reflowed wrap output (#291) - #298

Merged
leynos merged 8 commits into
mainfrom
issue-291-reflow-introduces-spurious-leading-spaces-at-the-start-of-wrapped-lines
May 27, 2026
Merged

Fix spurious leading spaces in reflowed wrap output (#291)#298
leynos merged 8 commits into
mainfrom
issue-291-reflow-introduces-spurious-leading-spaces-at-the-start-of-wrapped-lines

Conversation

@leynos

@leynos leynos commented May 27, 2026

Copy link
Copy Markdown
Owner

Summary

This branch fixes spurious leading spaces on wrapped continuation lines when
mdtablefix --wrap reflows Markdown paragraphs containing inline code spans.
Link reference definition passthrough was already landed on main via
#292 / #294.

Closes #291.

Review walkthrough

Validation

  • make check-fmt: passed
  • make lint: passed
  • make test: passed
  • coderabbit review --agent: 0 findings

Summary by Sourcery

Fix leading-space bugs in wrapped Markdown output and extend test coverage for wrapping behaviour.

Bug Fixes:

  • Remove spurious leading spaces from wrapped continuation lines in inline Markdown rendering while preserving list indentation semantics.
  • Correct wrapping expectations in existing tests, including whitespace handling and hard line break fixtures.

Tests:

  • Add regression and property-based tests to guard against leading-space reflow bugs across paragraphs and list items, backed by new fixture data files.
  • Refactor and expand wrap-related integration tests, reorganising modules and strengthening assertions for CLI, link references, lists, footnotes, fenced code blocks, and inline code spans.

Trim leading whitespace in `render_line` so reflow no longer emits
spurious spaces at the start of wrapped lines, particularly after
inline code spans. Add regression tests using the issue examples and
update expectations that previously relied on carry whitespace.

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Fix spurious leading spaces in reflowed wrap output

This PR resolves issue #291 by preventing spurious leading spaces at the start of wrapped continuation lines when reflowing Markdown with mdtablefix --wrap (notably around inline code spans).

Technical change

  • src/wrap/inline.rs: render_line now accepts strip_leading_carry_whitespace and only trims leading carry-whitespace for continuation lines (call sites in wrap_preserving_code pass !lines.is_empty()). This preserves intentional leading whitespace on the first emitted line while preventing extra spaces on wrapped continuation lines. Trailing-space trimming behaviour for non-final lines is unchanged.

Tests and validation

  • Unit tests: src/wrap/tests/inline_wrapping.rs updated and extended to assert continuation lines do not begin with carried spaces; added a test ensuring intentional leading whitespace on the first line is preserved.
  • Property/regression tests: tests/wrap_leading_spaces.rs (new module) plus tests/wrap_leading_spaces.proptest-regressions include fixture-based regression checks and proptest cases asserting no spurious leading spaces across paragraphs and list continuations.
  • Integration/fixture updates: multiple tests under tests/wrap/ and fixtures under tests/data/issue_291_*.txt were added/adjusted (including an ExecPlan input fixture) to exercise affected scenarios and document expectations.
  • Documentation: docs/developers-guide.md updated to document render_line behaviour and the strip_leading_carry_whitespace invariant.
  • Validation: make check-fmt, make lint and make test passed; CodeRabbit reported 0 findings.

Related work

Outcome

  • Continuation lines no longer start with spaces that were not present in the original input; link reference definitions remain preserved per the passthrough behaviour.

Walkthrough

Trim leading carry whitespace on wrapped continuation lines in the inline wrapping path and validate the change with updated unit tests, a new regression/proptest module, fixture updates, integration-test adjustments and documentation.

Changes

Spurious leading spaces reflow fix

Layer / File(s) Summary
Core implementation: trim leading whitespace from continuation lines
src/wrap/inline.rs
render_line gains a strip_leading_carry_whitespace parameter and conditionally calls trim_start(); wrap_preserving_code passes !lines.is_empty() to strip carry whitespace on non-first emitted lines.
Unit test: inline wrapping strips leading carry whitespace
src/wrap/tests/inline_wrapping.rs
Rename and update tests to assert continuation lines do not start with a space and to preserve intentional leading whitespace on first lines.
Regression & property tests for leading-space invariants
tests/wrap_leading_spaces.rs, tests/wrap_leading_spaces.proptest-regressions
Add regression module with list_continuation_indent and assert_no_spurious_leading_spaces helpers, fixture-based regression tests, saved proptest seed(s), and property tests generating prose, inline code spans and list prefixes.
Test fixture data defining inputs and expected outputs
tests/data/issue_291_*_{input,expected}.txt
Update/add ExecPlan, errors, Kani/netsuke/ordered-list fixtures that exercise inline-code wrap boundaries and list continuation scenarios used by regression tests.
Integration test suite updates for reflow fix validation
tests/wrap.rs, tests/wrap/cli.rs, tests/wrap/fence_behaviour.rs, tests/wrap/footnotes.rs, tests/wrap/hard_line_breaks.rs, tests/wrap/link_reference_definitions.rs, tests/wrap/links.rs, tests/wrap/lists.rs, tests/wrap/mod.rs, tests/wrap/paragraphs.rs, tests/wrap_unit.rs
Adjust fixture include paths, rework assertions for robustness, switch some strict equality checks to substring assertions for inline code/step guidance, and mark tab-indented checkbox tests as verbatim-preserved.

Sequence Diagram(s)

No sequence diagram generated.

Possibly related PRs

  • leynos/mdtablefix#271: Refactor of the inline wrapping/rendering pipeline touches the same continuation whitespace rendering behaviour.

Poem

Trim the carry, make lines align,
No rogue space will cross the line,
Tests declare each wrapped display,
Preserve first intent and list indent’s way,
CI will nod and green checks shine.

🚥 Pre-merge checks | ✅ 18 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
User-Facing Documentation ⚠️ Warning PR fixes issue #291 (spurious leading spaces in wrap output). Only developers-guide.md updated; users-guide.md lacks documentation of this corrected user-facing behaviour. Document in docs/users-guide.md that wrap output does not insert spurious leading spaces on continuation lines, clarifying the corrected behaviour.
Developer Documentation ⚠️ Warning Three lines in developers-guide.md exceed the 80-column limit (181–182: 84–81 chars; 220: 83 chars), violating documented coding guidelines despite adequate API documentation coverage. Run make fmt to reflow documentation to comply with the 80-column wrapped-line requirement per coding guidelines.
✅ Passed checks (18 passed)
Check name Status Explanation
Title check ✅ Passed The title directly addresses the main fix (spurious leading spaces in wrap output) and includes the linked issue reference (#291) as required.
Description check ✅ Passed The description explains the fix for spurious leading spaces, references linked issues (#292, #294), and provides a review walkthrough with validation results.
Linked Issues check ✅ Passed The PR successfully addresses #291 by implementing carry-whitespace stripping in render_line and adding comprehensive regression/property tests covering paragraphs, lists, and inline code spans.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing spurious leading spaces and extending test coverage; documentation updates and test refactoring directly support the stated objectives.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Testing (Overall) ✅ Passed Unit tests assert no leading spaces on inline code; fixture tests verify #291 examples exactly; property tests with random inputs. All fail without the fix.
Module-Level Documentation ✅ Passed All 17 Rust modules carry module-level docstrings (//!) clearly explaining purpose and utility, including the new tests/wrap_leading_spaces.rs regression module documenting issue #291.
Testing (Unit And Behavioural) ✅ Passed Unit tests verify render_line's strip flag. Fixture tests exercise #291 scenarios. Property tests verify invariants with generated input. CLI tests drive --wrap via cargo_bin() end-to-end.
Testing (Property / Proof) ✅ Passed PR introduces an invariant over wrapped output (no spurious leading spaces) and adds substantive proptest coverage using oracle-based assertions with independent indent calculation logic.
Testing (Compile-Time / Ui) ✅ Passed Regression and property tests validate the fix. Six fixture tests with custom assertions, two property tests with preconditions and stored seed failures.
Unit Architecture ✅ Passed Explicit parameter makes mutations visible. Decision in wrap_preserving_code, trimming in render_line. No hidden state or dependencies. Tests verify behaviour directly.
Domain Architecture ✅ Passed Domain logic properly segregated; no infrastructure/adapter concerns leaked. The strip_leading_carry_whitespace parameter is honest about its enforcement and semantics.
Observability ✅ Passed This PR fixes text-processing bugs in private function render_line() without introducing new operational behaviour, error modes, boundaries, or reliability changes requiring observability.
Security And Privacy ✅ Passed PR introduces no secrets, injection risks, unsafe operations, or sensitive data exposure. Changes are limited to safe Markdown text-processing logic with inline code and whitespace trimming.
Performance And Resource Use ✅ Passed No algorithmic regressions or unbounded resource growth. Conditional trim_start() per output line, proptest configs bounded, test fixtures small.
Concurrency And State ✅ Passed The PR modifies text-wrapping logic with no concurrency, shared state, or parallelism concerns. All changes operate on isolated, stack-allocated data within sequential function calls.
Architectural Complexity And Maintainability ✅ Passed Core fix adds one boolean parameter to render_line() without new traits, factories, registries, dependencies, or circular dependencies. Architecture remains minimal and proportionate to the issue.
Rust Compiler Lint Integrity ✅ Passed No problematic lint suppressions. The strip_leading_carry_whitespace parameter is meaningfully used, all test helpers are actively called, and no artificial lint appeasement patterns exist.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #291

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-291-reflow-introduces-spurious-leading-spaces-at-the-start-of-wrapped-lines

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai

sourcery-ai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Fixes whitespace handling in inline wrapping so wrapped continuation lines no longer start with spurious leading spaces, while preserving list-item continuation indentation, and adds focused regression, property-based, and integration tests to lock in the behavior across paragraphs, lists, CLI, and footnotes.

Flow diagram for inline render_line whitespace trimming

flowchart LR
    A[InlineWrapper] --> B[render_line]
    B --> C[collect InlineFragment text]
    C --> D{last char is space?}
    D -- yes --> E[text.pop]
    D -- no --> F[skip pop]
    E --> G[trim_start]
    F --> G[trim_start]
    G --> H[to_string]
    H --> I[wrapped line without leading spaces]
Loading

File-Level Changes

Change Details Files
Strip carry-over leading whitespace at inline wrap boundaries so continuation lines never start with spurious spaces.
  • Update inline render_line to trim leading whitespace from the assembled line before returning it
  • Adjust inline wrapping unit test expectations to assert no leading spaces on wrapped fragments and to join wrapped text with spaces where appropriate
  • Add targeted regression tests ensuring wrapped paragraphs and inline code spans do not produce leading spaces on any continuation line
src/wrap/inline.rs
src/wrap/tests/inline_wrapping.rs
tests/wrap/paragraphs.rs
tests/wrap_unit.rs
Introduce regression and property-based tests specifically guarding against leading-space reflow bugs, including list continuation indentation rules.
  • Add wrap_leading_spaces.rs integration/property test module with helpers to compute expected list continuation indent and to assert absence of spurious leading spaces
  • Add multiple fixture-based tests for paragraphs and various list styles exercising the original issue scenarios
  • Introduce proptest strategies and regression corpus to randomly generate prose, inline code spans, and list prefixes to validate wrapping invariants
tests/wrap_leading_spaces.rs
tests/wrap_leading_spaces.proptest-regressions
tests/data/issue_291_execplan_input.txt
tests/data/issue_291_execplan_expected.txt
tests/data/issue_291_errors_input.txt
tests/data/issue_291_errors_expected.txt
tests/data/issue_291_netsuke_list_input.txt
tests/data/issue_291_netsuke_list_expected.txt
tests/data/issue_291_kani_list_input.txt
tests/data/issue_291_kani_list_expected.txt
tests/data/issue_291_ordered_list_input.txt
tests/data/issue_291_ordered_list_expected.txt
tests/data/issue_291_nested_ordered_list_input.txt
tests/data/issue_291_nested_ordered_list_expected.txt
Tighten and clarify existing wrapping integration tests (CLI, paragraphs, lists, fences, link reference definitions, links, footnotes, and hard line breaks) to reflect the new whitespace behavior and improve assertions.
  • Refine CLI wrap tests to assert preservation of inline code spans and critical substrings rather than full-output equality, making them robust to reflow while still guarding semantics
  • Update paragraph and list tests to use correct include_lines paths and to expect no leading whitespace on continuation lines, and change some tests to assert verbatim passthrough where wrapping is intentionally disabled (e.g., tab-indented code-like content)
  • Improve fence, footnote, link, and link-reference tests to have clearer assertions and formatting, and re-organize the wrap test module structure to run all submodules through wrap/mod.rs with an integration harness
tests/wrap/cli.rs
tests/wrap/paragraphs.rs
tests/wrap/lists.rs
tests/wrap/fence_behaviour.rs
tests/wrap/footnotes.rs
tests/wrap/link_reference_definitions.rs
tests/wrap/hard_line_breaks.rs
tests/wrap/links.rs
tests/wrap/mod.rs
tests/wrap.rs

Assessment against linked issues

Issue Objective Addressed Explanation
#291 Ensure that mdtablefix --wrap does not introduce spurious leading spaces at the start of wrapped lines (particularly around inline code spans and wrap boundaries).
#291 Ensure that link reference definition blocks are not reflowed and are preserved verbatim line-by-line when using mdtablefix --wrap.

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

leynos and others added 3 commits May 27, 2026 20:09
Introduce exact before/after fixture tests for the reported paragraph,
list, and ordered-list reflow cases, plus proptest coverage that rejects
spurious carry whitespace on wrapped continuation lines while preserving
legitimate list-item indents.

Co-authored-by: Cursor <cursoragent@cursor.com>
Include tests/wrap/mod.rs from tests/wrap.rs so paragraph, list, footnote,
and link reference definition integration tests execute under make test.
Repair stale fixture paths, rstest attributes, and expectations that no
longer matched current wrapping behaviour.

Co-authored-by: Cursor <cursoragent@cursor.com>
Reformat the step-definitions guidance string in the CLI wrap test so
make check-fmt passes after the integration test suite was wired up.

Co-authored-by: Cursor <cursoragent@cursor.com>
@leynos

leynos commented May 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already.

#291 Ensure that link reference definition blocks are not reflowed at all (each definition remains on its own line and is left untouched). ❌ This PR does not modify the handling of link reference definitions. The PR description states that link reference definition passthrough was already implemented in separate work (#292 / #294), and there are no code or test changes in this diff related to skipping reflow for link reference definitions.

@leynos
leynos marked this pull request as ready for review May 27, 2026 18:26
@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check status of PR `#294`
gh pr view 294 --repo leynos/mdtablefix --json state,mergedAt,title,body

# Check status of PR `#292` issue
gh issue view 292 --repo leynos/mdtablefix --json state,title,body

# Check for link reference definition handling in current branch
rg -n "link.ref|link_ref|lrd|reference.def|ReferenceDefinition|LinkRef" --type rust

# Check the wrap module for any passthrough/skip logic
rg -n "passthrough|pass_through|skip|lrd\|link" --type rust -C3

Length of output: 29424



@leynos: The check is now resolved. PR #294 ("Keep link reference definitions verbatim during wrap") was merged on 27 May 2026, and this branch carries all of that work. The evidence from the codebase:

  • src/wrap/link_reference.rsLinkReferenceMatcher and LinkTitleWindow centralise all regex access for link reference queries.
  • src/wrap/block.rsBlockKind::LinkReferenceDefinition is a distinct variant in the block classifier.
  • src/wrap.rs Line 62–69is_passthrough_block routes BlockKind::LinkReferenceDefinition (and standalone title continuations) straight through, untouched.
  • tests/wrap/link_reference_definitions.rs — six regression tests covering: single definition, the exact multi-definition block from the issue report, bare URLs, inline titles, mixed paragraph context, and document boundary positions.
  • src/wrap/tests/link_ref_regex.rs — property-based tests asserting regex correctness across all title and URL variants.

No further work is required for this item.

sourcery-ai[bot]

This comment was marked as resolved.

@coderabbitai coderabbitai Bot added the Issue label May 27, 2026
Pass a continuation flag into render_line so intentional leading
whitespace on the first wrapped line is preserved while carry whitespace
is still stripped from later lines. Tighten the list-item proptest to
use prop_assume for input constraints and prop_assert for postconditions.

Co-authored-by: Cursor <cursoragent@cursor.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e978fb2df9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tests/wrap.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/wrap_leading_spaces.rs`:
- Around line 203-206: The test uses prop_assume! to check postconditions
(output length, prefix match, multi-line) which improperly discards cases;
change those three calls to prop_assert! so the property fails when invariants
are violated. Specifically, replace prop_assume!(output.iter().all(|line|
line.len() <= 80)), prop_assume!(output[0].starts_with(&prefix)), and
prop_assume!(output.len() > 1) with prop_assert! equivalents in the test using
the variables output and prefix so failures are reported instead of being
filtered out.

In `@tests/wrap.rs`:
- Line 1: Remove the crate-level blanket attribute
`#![allow(unfulfilled_lint_expectations)]` and instead attach a narrowly scoped
attribute to the specific item that needs suppression, e.g. add
`#[expect(unfulfilled_lint_expectations, reason = "temporary: <explain why>")]`
directly above the test function or module that triggers the lint (replace
<explain why> with a short justification), ensuring no other items keep the
global allow.

In `@tests/wrap/links.rs`:
- Around line 57-58: Replace the escaped-line string literal in the test (the
long markdown link literal that currently uses a backslash to continue the line)
with a concat!() invocation that joins the two parts into one compile-time
string; locate the string in tests/wrap/links.rs (the link beginning with
"[`rust-multithreaded-logging-framework-for-python-design.md`](" and split it
into separate quoted segments passed to concat!), remove the trailing backslash,
and ensure the resulting concat!() call produces the exact same content and
formatting as the original literal.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 163a124c-a173-4906-8d1f-1b3144726069

📥 Commits

Reviewing files that changed from the base of the PR and between 2fe5c54 and e978fb2.

⛔ Files ignored due to path filters (1)
  • tests/snapshots/wrap_unit__inline_footnote_reference_wrap.snap is excluded by !**/*.snap
📒 Files selected for processing (27)
  • src/wrap/inline.rs
  • src/wrap/tests/inline_wrapping.rs
  • tests/data/issue_291_errors_expected.txt
  • tests/data/issue_291_errors_input.txt
  • tests/data/issue_291_execplan_expected.txt
  • tests/data/issue_291_execplan_input.txt
  • tests/data/issue_291_kani_list_expected.txt
  • tests/data/issue_291_kani_list_input.txt
  • tests/data/issue_291_nested_ordered_list_expected.txt
  • tests/data/issue_291_nested_ordered_list_input.txt
  • tests/data/issue_291_netsuke_list_expected.txt
  • tests/data/issue_291_netsuke_list_input.txt
  • tests/data/issue_291_ordered_list_expected.txt
  • tests/data/issue_291_ordered_list_input.txt
  • tests/wrap.rs
  • tests/wrap/cli.rs
  • tests/wrap/fence_behaviour.rs
  • tests/wrap/footnotes.rs
  • tests/wrap/hard_line_breaks.rs
  • tests/wrap/link_reference_definitions.rs
  • tests/wrap/links.rs
  • tests/wrap/lists.rs
  • tests/wrap/mod.rs
  • tests/wrap/paragraphs.rs
  • tests/wrap_leading_spaces.proptest-regressions
  • tests/wrap_leading_spaces.rs
  • tests/wrap_unit.rs

Comment thread tests/wrap_leading_spaces.rs Outdated
Comment thread tests/wrap.rs Outdated
Comment thread tests/wrap/links.rs Outdated
@leynos

leynos commented May 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following now been resolved?

Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity.

Please address the comments from this code review:

## Overall Comments
- In `wrap_preserving_code_strips_leading_carry_whitespace` the change to `render_line` using `trim_start()` now strips all leading whitespace, including potentially intentional indentation or alignment; consider restricting this behavior to continuation lines only (e.g., by passing a flag into `render_line`) so that genuinely significant leading spaces are not removed.
- In the `proptest!` block in `tests/wrap_leading_spaces.rs`, the `wrap_list_items_do_not_introduce_spurious_leading_spaces` test calls `assert_no_spurious_leading_spaces(&output)` before the `prop_assume!` filters, which means failing cases will hard-fail instead of being discarded; move the `prop_assume!` checks before assertions so the assumptions behave as intended.

## Individual Comments

### Comment 1
<location path="tests/wrap_leading_spaces.rs" line_range="74-83" />
<code_context>
     );
     let input = lines_vec![first_paragraph, "```", code_line, "```", closing_paragraph];
     let output = process_stream(&input);
-    assert!(!output.iter().any(|l| l.starts_with("``") && l.len() == 2), "no false 2-tick fences");
+    assert!(
</code_context>
<issue_to_address>
**issue (testing):** Property test uses `prop_assume!` where `prop_assert!` is needed, so key invariants are not actually being checked

In `wrap_list_items_do_not_introduce_spurious_leading_spaces`, the last three `prop_assume!` calls are acting as postcondition checks on `process_stream` (width ≤ 80, prefix preserved, wrapping occurs). As `prop_assume!` they only discard failing cases instead of failing the test, so regressions in these behaviors could be missed.

If these are required postconditions, please change them to `prop_assert!`. If instead they are preconditions on generated inputs, move them before the `process_stream` call so they constrain the input strategy rather than the behavior under test.
</issue_to_address>

@coderabbitai

coderabbitai Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check current state of render_line in src/wrap/inline.rs
cat src/wrap/inline.rs

echo "---"

# Check current state of the proptest in tests/wrap_leading_spaces.rs
cat tests/wrap_leading_spaces.rs

Length of output: 23902



@leynos: Both comments are now resolved.

Overall comment 1 — trim_start() restricted to continuation lines

render_line now accepts a strip_leading_carry_whitespace: bool parameter and only calls trim_start() when that flag is set. The call sites pass !lines.is_empty(), so the trim applies exclusively to continuation lines (the second and subsequent wrapped lines), leaving the first rendered line untouched.

Overall comment 2 / individual comment — prop_assume! vs prop_assert! ordering

wrap_list_items_do_not_introduce_spurious_leading_spaces is now correctly structured:

  1. prop_assume!(leading_spaces < 4) and prop_assume!(line.len() > 80) — preconditions, placed before process_stream.
  2. Three prop_assert! calls — postconditions on output.len() > 1, prefix preservation, and max-line-width.
  3. assert_no_spurious_leading_spaces(&output) — called last, after all assume/assert guards.

Regressions in wrapping behaviour will now cause hard test failures rather than being silently discarded.

leynos and others added 2 commits May 27, 2026 20:34
The wrap integration test crate no longer needs a crate-level
unfulfilled_lint_expectations allow; per-item expects in common helpers
already cover the shared test utilities.

Co-authored-by: Cursor <cursoragent@cursor.com>
Use concat! for the long markdown link string in
test_wrap_link_with_trailing_punctuation, matching project conventions
and avoiding a backslash line continuation in the literal.

Co-authored-by: Cursor <cursoragent@cursor.com>
Describe render_line and strip_leading_carry_whitespace in the wrapping
pipeline post-processing section so continuation-line trimming behaviour
is recorded alongside the other inline wrapping invariants.

Co-authored-by: Cursor <cursoragent@cursor.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/developers-guide.md`:
- Around line 156-163: Reflow the paragraph in docs/developers-guide.md so no
lines exceed 80 columns: break the sentence describing render_line in
src/wrap/inline.rs and its strip_leading_carry_whitespace flag into multiple
wrapped lines, preserving meaning (mention that strip_leading_carry_whitespace
removes carry whitespace attached to wrapped continuation lines and is only set
after wrap_preserving_code has emitted at least one line), and ensure the note
about trailing space/hard-break is wrapped as well; after editing, run `make
fmt` to apply documentation formatting and fix table markup.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5e6fbfb0-5af0-4db4-b4c8-57f0661db0a5

📥 Commits

Reviewing files that changed from the base of the PR and between 0f9e8bf and 365cab1.

📒 Files selected for processing (1)
  • docs/developers-guide.md

Comment thread docs/developers-guide.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reflow introduces spurious leading spaces at the start of wrapped lines

1 participant