Mon filtre rejetait peut-être la montre, et mon message accusait le scan

Le dépôt était bien à jour : c'est moi qui avais mal lu mon propre code. Le
message incriminé EST atteignable par la nouvelle version — l'état Bluetooth est
publié, on passe au scan, et le publisher se tait quand même.

Deux erreurs à moi, pas une du SDK.

D'abord le message. Le publisher de `search()` reste muet dans DEUX cas : le
scan n'a pas démarré, ou il tourne sans rien découvrir — `scanSubject` n'émet
que sur découverte, et un `prepend` de liste vide n'émet pas. Affirmer « le scan
n'a pas démarré » a fait chercher au mauvais endroit pendant trois itérations.
Le message énonce désormais les deux possibilités, et le test qui verrouillait
l'ancienne formulation vérifie maintenant qu'on n'affirme rien de trop.

Ensuite le filtre. `scanPreFilter` rejetait tout ce qui n'avait ni polarDeviceId
ni « polar » dans le nom. Si la Vantage ne s'annonce pas ainsi, c'est NOUS qui
l'écartions, aucune session n'était créée, et le silence qui suivait était
interprété comme une panne du SDK. On laisse donc tout remonter et on trie
après : un test de ressemblance volontairement large (polarDeviceId,
polarDeviceType, ou nom contenant polar/vantage/grit), et on n'ouvre de session
que sur les candidats — ouvrir 43 sessions coûtait des minutes.

Et si rien ne ressemble à un Polar, on RAPPORTE ce qu'on a vu : nombre et noms
des huit premiers. C'est la seule façon de savoir sous quel nom la montre
s'annonce, ou de constater qu'elle ne s'annonce pas du tout — auquel cas
l'hypothèse du lien exclusif avec Polar Flow devient la bonne.

84 tests au vert.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sylvain Bettinelli
2026-08-31 13:36:28 +00:00
parent eef76daa45
commit 60dd22eaeb
3 changed files with 101 additions and 30 deletions

View File

@@ -215,10 +215,15 @@ extension PolarPftpErrorTests {
extension PolarPftpErrorTests {
func testPublisherMuetNAccusePasLaMontre() {
// Assoupli le 2026-08-31 : le message affirmait « le scan n'a pas
// démarré », ce qui était une conclusion de trop le publisher se tait
// aussi quand le scan tourne sans rien découvrir. Ce test vérifie
// désormais qu'on n'accuse ni la montre, ni une cause unique.
let e = PolarPftpError.sdkSilencieux(vusParCoreBluetooth: 43,
publisherAParle: false)
XCTAssertTrue(e.description.contains("n'a pas démarré"))
XCTAssertTrue(e.description.contains("Ce n'est pas la montre"))
XCTAssertTrue(e.description.contains("aucun appareil"))
XCTAssertFalse(e.description.contains("Ce n'est pas la montre"),
"ne rien affirmer sur la montre : on n'en sait rien ici")
}
func testUneErreurDuSdkEstRapporteeTelleQuelle() {
@@ -258,3 +263,30 @@ extension PolarPftpErrorTests {
XCTAssertNotEqual(echeance, vide)
}
}
// MARK: - Ne pas conclure plus que ce qu'on a mesuré
//
// Le publisher de `search()` reste muet dans DEUX cas : le scan n'a pas démarré,
// ou il tourne sans rien découvrir (`scanSubject` n'émet que sur découverte).
// Un message affirmant le premier a fait chercher au mauvais endroit pendant
// trois itérations du 2026-08-31.
extension PolarPftpErrorTests {
func testLeSilenceDuSdkNAffirmePasQueLeScanEstArrete() {
let e = PolarPftpError.sdkSilencieux(vusParCoreBluetooth: 43,
publisherAParle: false)
XCTAssertTrue(e.description.contains("soit"),
"le message doit énoncer les deux possibilités")
XCTAssertFalse(e.description.contains("n'a jamais signalé"))
}
func testAucunPolarListeCeQuiAEteVu() {
let e = PolarPftpError.aucunPolarParmi(
vues: 43, exemples: ["Apple Watch de Sylvain", "(sans nom)"])
XCTAssertTrue(e.description.contains("43"))
XCTAssertTrue(e.description.contains("Apple Watch de Sylvain"))
XCTAssertTrue(e.description.contains("Polar Flow"),
"l'hypothèse du lien exclusif doit être énoncée")
}
}