Repository navigation
fix(oura): make the nameless-ring label rule one tested twin, not two - #1797
Merged
Merged
Conversation
ryanbr#1783 reports that a ring advertising no local name lists with a blank label on both platforms. It does not. Both platforms already substitute a fallback at the single `DiscoveredRing` construction site, and have since the original Oura commit (4897f26), so `ring.name` is never blank by the time the wizard renders it: Strand/BLE/OuraLiveSource.swift name: name.isEmpty ? "Oura" : name android/…/ble/OuraLiveSource.kt name = name.ifBlank { "Oura" } The three call sites the issue names (`AddDeviceWizard.kt:1339`, `AddDeviceWizard.swift:1160`, and `:1646`, which the issue does not name but has the same shape) render an already-guarded value. Adding a second guard there would be dead code, and a test pinning it would pin nothing. What IS there is a silent divergence between the two guards. `ifBlank` treats an all-whitespace name as absent; `isEmpty` does not. A ring advertising `" "` would have listed as "Oura" on Android and blank on Apple — the same class of Swift/Kotlin drift the parity contract calls out, invisible in review because both lines read correctly on their own. So both guards become one named helper, `ouraAdvertisedLabel`, whitespace-aware on both sides and returning the name UNTRIMMED when present, pinned by an oracle test. The oracle earned its place immediately: the first Kotlin draft was `advertisedName.trim().ifEmpty { fallback }`, which returns the trimmed name where Swift returns the original. Reading the two side by side would not have caught it; `" Oura Ring 4 "` does. Also localises `AddDeviceWizard.kt`'s `?: "Oura ring"` subtitle fallback, which was a hardcoded English literal while `l10n_add_device_wizard_oura_ring_e3431536` already existed in all six locales. That fallback renders precisely when the generation is undetected — which is exactly the nameless bonded-ring case from ryanbr#1776 — so a French user hit untranslated copy on the one row this issue is about. No new string on either platform. Verification: - Android: 5040 tests, 4/4 in OuraNamelessRingDiscoveryTest including the new oracle case. The 2 RecoveryDriversTest float-rounding failures are pre-existing on upstream/main, unrelated. - Apple: `xcodebuild -scheme Strand -destination platform=macOS` BUILD SUCCEEDED (app-target Swift, which no default CI job compiles). - Tools/doc_comment_lint.py and Tools/i18n_audit.py --ci both exit 0. - No hardware validation: this changes a label, not the BLE path. Discovery behaviour itself is unchanged. Refs ryanbr#1783, ryanbr#1776 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Xj4EcmHmVGeL6JrG4JBXK
ryanbr
added a commit
that referenced
this pull request
Sep 1, 2026
…abel
Both doc blocks claimed the Kotlin and Swift label rules part on U+00A0, citing that
Java's Character.isWhitespace excludes it while Swift's .whitespacesAndNewlines includes
it. The first half is true of Character.isWhitespace in isolation, but ifBlank never
calls it: Kotlin's Char.isWhitespace is
Character.isWhitespace(c) || Character.isSpaceChar(c)
and isSpaceChar covers exactly the non-breaking spaces (U+00A0, U+2007, U+202F) that
isWhitespace drops. Verified on the JVM. U+00A0 is therefore blank on BOTH sides - the
one case the note picked out is the case they agree on.
The real divergence set is the opposite pair: U+0085, which .whitespacesAndNewlines
includes and Kotlin does not, and U+001C-U+001F, which Kotlin counts and Swift does not.
Neither reaches a BLE local name, so this is a comment correction with no behaviour
change and no test change.
Worth correcting rather than leaving: the parity ledger reads these doc blocks for twin
claims, the wrong claim was duplicated across both files, and it advertised itself as
"stated rather than silently overclaimed".
Follow-up to #1797 by @pipiche38.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Diff shape
Strand/BLE/OuraLiveSource.swiftouraAdvertisedLabel; both call sites routed through it;.isEmpty→ whitespace-awareandroid/…/ble/OuraLiveSource.ktouraAdvertisedLabel; both call sites routed through itandroid/…/ui/AddDeviceWizard.ktl10n_…_oura_ring_e3431536keyandroid/…/ble/OuraNamelessRingDiscoveryTest.kt88 insertions, 5 deletions. No new strings, so nothing owed in any locale.
Verification actually run
testFullDebugUnitTest -Duser.language=en: 5040 tests, 4/4 inOuraNamelessRingDiscoveryTest. The 2RecoveryDriversTestfloat-rounding failures(
expected:<-0.5> but was:<-0.4999999999999929>) are pre-existing onupstream/main.xcodebuild -project Strand.xcodeproj -scheme Strand -destination platform=macOS CODE_SIGNING_ALLOWED=NO build→ BUILD SUCCEEDED. Required: this touches app-target Swift,which
swift-packages.ymldoes not compile andapp-build.ymlis disabled.Tools/doc_comment_lint.pyexit 0,Tools/i18n_audit.py --ci upstream/mainexit 0.The oracle, for the PR body if asked
Swift twin compiled standalone (
swiftc -O twin.swift main.swift) over the 12-case list; its stdoutis pasted verbatim as the Kotlin expectations. It immediately caught my own first Kotlin draft,
advertisedName.trim().ifEmpty { fallback }— returns the trimmed name where Swift returns theoriginal.
" Oura Ring 4 "is the separating case. Note the oracle guards only theKotlin→Swift direction; the Swift side has no equivalent test, because
Strand/BLEtests run onlyunder
xcodebuild … testandapp-build.ymlis off by default.Known boundary, stated not hidden
Kotlin
isBlank(JavaCharacter.isWhitespace) and Swift.whitespacesAndNewlinesdisagree onexotic Unicode spaces — U+00A0 is whitespace to Swift, not to Java. Documented at the helper on both
sides rather than asserted, since no BLE local name carries one.