Skip to content

fix gen5 pairing test pinning a stale present() signature - #302

Merged
abdulsaheel merged 2 commits into
OpenStrap:mainfrom
DropTabl:fix/gen5-pairing-test-present-signature
Aug 28, 2026
Merged

fix gen5 pairing test pinning a stale present() signature#302
abdulsaheel merged 2 commits into
OpenStrap:mainfrom
DropTabl:fix/gen5-pairing-test-present-signature

Conversation

@DropTabl

@DropTabl DropTabl commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

test/gen5_pairing_filter_test.dart fails deterministically on main (verified at 979b20d, in isolation).

What broke

The test reads ios/Runner/AccessorySetup.swift as source text and pinned two exact lines:

present(items, allowGen4Retry: true)
self.present([items[0]], allowGen4Retry: false)

Both calls gained a known: parameter when present started forwarding the pre-picker accessory list, so neither literal matches any more:

present(items, known: known, allowGen4Retry: true)          // :242
self.present([items[0]], known: known, allowGen4Retry: false) // :275

Both had drifted, not just the one in the failure output — the first expect aborts the test body, so the second was never reached.

The fix

Match by shape rather than by full line. The invariant the test actually guards is that the widened list is presented with the Gen 4 retry armed, and that the single-item retry targets items[0] with the retry disarmed. [^)]* absorbs any intervening arguments, and is deliberately paren-free so it cannot run past the end of the call.

Checked that this is not merely permissive — against mutated copies of the Swift:

Mutation Caught
widened list presented with allowGen4Retry: false yes
retry target changed to items[1] yes
retry re-arms the retry (infinite loop) yes
an extra parameter added before allowGen4Retry: tolerated, as intended

Scope

Every other pinned literal in the file was re-checked against its source and still holds: whoopMemberUUID16, CBUUID(string: AccessorySetup.whoopMemberUUID16), bluetoothNameSubstring, the four retryInFlight pins, the items-ordering indexOf pair, and the Info.plist / ble_engine.dart literals. The other 19 tests that read source files as text were swept for the same failure mode; none pin a call signature with named parameters, so there is no cleanup backlog behind this. No production code is touched.

Verification

flutter test — 3165 passed, 0 failed, 423 skipped.

Summary by Sourcery

Harden the Gen 5 pairing test’s source-level assertions against future present call signature changes.

Bug Fixes:

  • Update the Gen 5 pairing source-text test to continue validating retry behavior after the Swift present call signature changes.

Enhancements:

  • Make call assertions resilient to additional named arguments while preserving checks for the widened list, retry target, and retry flags.

Tests:

  • Add balanced-call parsing and complete named-argument matching to prevent stale or overly permissive source-based assertions.

The test read AccessorySetup.swift as source text and asserted the exact
lines `present(items, allowGen4Retry: true)` and
`self.present([items[0]], allowGen4Retry: false)`. Both calls gained a
`known:` parameter when present() started forwarding the pre-picker
accessory list, so the full-line match no longer held and the test failed
deterministically on main. Only the first was ever reported, since it
aborts the test body before the second runs.

Match by shape instead: the invariant is that the widened list is
presented WITH the Gen 4 retry armed and the single-item retry targets
items[0] with the retry disarmed, whatever else rides along in between.
Verified the regexes still fail on a disarmed widened list, a retry
target that is not items[0], and a retry that re-arms itself.

Every other pinned literal in the file was re-checked against its source
and still holds.
@sourcery-ai

sourcery-ai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Updates the Gen 5 pairing source-text test to tolerate added named arguments to Swift present calls while continuing to verify the widened-list retry and non-looping items[0] fallback behavior; no production code changes are included.

File-Level Changes

Change Details Files
Replace brittle full-line source-text assertions with regex shape matching that preserves the test’s behavioral invariants.
  • Match the widened items presentation while requiring allowGen4Retry: true.
  • Match the items[0] single-item retry while requiring allowGen4Retry: false.
  • Allow intervening call arguments without allowing the pattern to cross a closing parenthesis.
  • Add reasons documenting the invariants enforced by each assertion.
test/gen5_pairing_filter_test.dart

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

@coderabbitai

coderabbitai Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • test/gen5_pairing_filter_test.dart is excluded by !test/**

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ba29606c-dafc-41d1-92d2-432ad7068cb5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@sourcery-ai sourcery-ai 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.

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="test/gen5_pairing_filter_test.dart" line_range="179" />
<code_context>
+      // the argument the retry hinges on, whatever else rides along.
+      expect(
+        swift,
+        matches(RegExp(r'present\(\s*items\s*,[^)]*allowGen4Retry:\s*true')),
+        reason: 'the widened list must be presented WITH the Gen 4 retry armed',
+      );
</code_context>
<issue_to_address>
**issue (testing):** The assertions match only the `true` or `false` prefix of the `allowGen4Retry` expression, so `allowGen4Retry: true && false` passes the first assertion while leaving retry disabled, and `allowGen4Retry: false || true` passes the second while re-arming the retry.

**Triggers:** When the Swift argument is changed from a boolean literal to a compound boolean expression.

**Suggested fix:** Require the boolean value to be a complete argument token, such as by matching `true` or `false` followed by optional whitespace and the closing parenthesis or a comma.
</issue_to_address>

### Comment 2
<location path="test/gen5_pairing_filter_test.dart" line_range="179" />
<code_context>
+      // the argument the retry hinges on, whatever else rides along.
+      expect(
+        swift,
+        matches(RegExp(r'present\(\s*items\s*,[^)]*allowGen4Retry:\s*true')),
+        reason: 'the widened list must be presented WITH the Gen 4 retry armed',
+      );
</code_context>
<issue_to_address>
**issue (testing):** The regexes fail when an intervening argument contains a parenthesized expression, because `[^)]*` stops at that inner closing parenthesis even though the outer `present` call has the required retry setting.

**Triggers:** When `present` gains an intervening argument such as `known: accessories.map((item) => item.id)` or another function call.

**Suggested fix:** Use a parser or a regex that explicitly supports the expected argument syntax instead of assuming intervening arguments contain no parentheses.
</issue_to_address>

Sourcery assessment

Approval pending. 2 findings to address first.

Blocking findings: test/gen5_pairing_filter_test.dart:179, test/gen5_pairing_filter_test.dart:179


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread test/gen5_pairing_filter_test.dart Outdated
Comment thread test/gen5_pairing_filter_test.dart Outdated
main fixed the same failure at f268b5e by re-pinning the new exact lines
(`present(items, known: known, allowGen4Retry: true)`). That is the same
brittle construct that broke in the first place: the next parameter added
to present() breaks it again. Resolved in favour of this branch's
shape-matching assertion, which tolerates the `known:` parameter and any
future one.

Also addresses two findings from the PR bot, both of which were correct:

- The value was matched as a prefix, so `allowGen4Retry: true && false`
  would have passed while leaving the retry disabled. It is now read as a
  complete token and a compound expression matches nothing.
- The `[^)]*` gap could not cross a parenthesis, so an intervening
  argument containing a call (`known: ids.map((i) => i.uuid)`) would have
  failed the assertion spuriously — the exact drift this PR exists to
  stop. Arguments are now extracted with balanced parentheses.

Verified against mutated copies of the Swift: a disarmed widened list, a
retry target that is not items[0], a retry that re-arms itself, and both
compound-boolean forms all fail; a nested-paren argument and an extra
trailing parameter both still pass.

@sourcery-ai sourcery-ai 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.

Sourcery assessment

Approved.

@abdulsaheel
abdulsaheel merged commit 0455325 into OpenStrap:main Aug 28, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants