Skip to content

Commit f18f53c

Browse files
author
Mirror Bot
committed
Mirror from private (13dbe150)
1 parent 6f65385 commit f18f53c

17 files changed

Lines changed: 5917 additions & 19 deletions
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import Foundation
2+
import Testing
3+
@testable import WhatCableCore
4+
5+
/// Corpus-replay sweep for `CableDB.vendorName(vid:)`, `CableDB.isUSBIFRegistered(_:)`,
6+
/// and `CableDB.curatedCables(vid:pid:)` (`Sources/WhatCableCore/Cable/CableDB.swift`),
7+
/// the bundled-SQLite-backed lookup no existing test drives against real
8+
/// corpus identities.
9+
///
10+
/// Reads `research/customer-probes/corpus.jsonl`, the committed distillation
11+
/// (not gitignored raw probes), so this sweep runs on a fresh clone with no
12+
/// re-fetch needed. Each record's `devices` and `cables` arrays carry
13+
/// `{"vid": "0x...", "pid": "0x..."}` pairs seen on real hardware: `devices`
14+
/// are connected-peripheral SOP identities, `cables` are cable e-marker
15+
/// (SOP'/SOP'') identities.
16+
@Suite("CableDB: corpus lookup sweep")
17+
struct CableDBCorpusLookupTests {
18+
19+
private static let corpusRoot: URL = {
20+
URL(fileURLWithPath: #filePath)
21+
.deletingLastPathComponent() // WhatCableCoreTests
22+
.deletingLastPathComponent() // Tests
23+
.deletingLastPathComponent() // repo root
24+
.appendingPathComponent("research/customer-probes")
25+
}()
26+
27+
private struct Identity: Hashable {
28+
let vid: Int
29+
let pid: Int
30+
}
31+
32+
/// Every (VID, PID) pair seen anywhere in `corpus.jsonl`'s `devices` or
33+
/// `cables` arrays, across every folder. `vid`/`pid` are hex strings like
34+
/// `"0x05AC"`; entries missing either field, or equal to `"0x0000"`, are
35+
/// skipped (mirrors `CableDB.curatedCables`'s own zero-VID/PID guard --
36+
/// there is nothing to look up for an unidentified accessory).
37+
private static let identities: Set<Identity> = {
38+
let url = corpusRoot.appendingPathComponent("corpus.jsonl")
39+
guard let text = try? String(contentsOf: url, encoding: .utf8) else { return [] }
40+
41+
var result: Set<Identity> = []
42+
for line in text.split(separator: "\n") {
43+
guard let data = line.data(using: .utf8),
44+
let obj = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
45+
else { continue }
46+
let arrays = [obj["devices"] as? [[String: Any]] ?? [], obj["cables"] as? [[String: Any]] ?? []]
47+
for array in arrays {
48+
for entry in array {
49+
guard let vidStr = entry["vid"] as? String, vidStr.hasPrefix("0x"),
50+
let pidStr = entry["pid"] as? String, pidStr.hasPrefix("0x"),
51+
let vid = Int(vidStr.dropFirst(2), radix: 16),
52+
let pid = Int(pidStr.dropFirst(2), radix: 16),
53+
vid != 0, pid != 0
54+
else { continue }
55+
result.insert(Identity(vid: vid, pid: pid))
56+
}
57+
}
58+
}
59+
return result
60+
}()
61+
62+
/// The 5 corpus-identified cables added to `data/known-cables.md` /
63+
/// `whatcable.db` from test-kit evidence (commit c45018418, "Add 5
64+
/// corpus-identified cables to the known-cables database"). Each must
65+
/// resolve to a curated row: this is the same database the app bundles,
66+
/// so a lookup miss here means the running app can't identify these
67+
/// cables either.
68+
private static let recentlyAddedCables: [(vid: Int, pid: Int, brandContains: String)] = [
69+
(0x05AC, 0x7209, "Studio Display"),
70+
(0x05AC, 0x7203, "Apple"),
71+
(0x20C2, 0x080F, "Sumitomo"),
72+
(0x20C2, 0x0714, "Sumitomo"),
73+
(0x0C62, 0xC8F1, "Chant Sincere"),
74+
]
75+
76+
// MARK: - Coverage floor
77+
//
78+
// Measured directly against the committed corpus.jsonl at the time this
79+
// sweep was written, by a Python script mirroring this file's own filter
80+
// exactly (vid/pid must be "0x"-prefixed strings that parse as hex and
81+
// are both non-zero): 231 distinct (VID, PID) pairs across every folder's
82+
// `devices` + `cables` arrays. Floor = 85% of 231, rounded down:
83+
// 231 * 0.85 = 196.35 -> 196.
84+
//
85+
// An earlier scoping pass (used only to gauge scale before this file was
86+
// written, not the filter that shipped) had counted 268 by checking the
87+
// vid/pid strings were merely non-empty rather than non-zero, so it
88+
// counted zero-VID/zero-PID entries (e.g. `"0x0000"`/`"0x0000"`) as a
89+
// valid pair. This file's actual filter excludes those (mirroring
90+
// `CableDB.curatedCables`'s own zero-VID/PID guard, see the doc comment
91+
// above), so 268 never matched what the shipped code counts; 231 is the
92+
// correct figure for the filter actually in this file.
93+
//
94+
// corpus.jsonl is committed (unlike the gitignored raw probes the other
95+
// sweeps depend on), so this floor never skips on a fresh clone.
96+
private static let coverageFloor = 196
97+
98+
// MARK: - Tests
99+
100+
@Test("Coverage: the corpus has enough distinct (VID, PID) identities to exercise CableDB")
101+
func coverageFloorHolds() {
102+
#expect(Self.identities.count >= Self.coverageFloor,
103+
"Expected at least \(Self.coverageFloor) distinct (VID, PID) identities (85% of the 231 counted when this sweep was written); found \(Self.identities.count).")
104+
}
105+
106+
@Test("No crash: every corpus (VID, PID) identity survives a CableDB round trip")
107+
func noCrashAcrossCorpus() {
108+
for id in Self.identities {
109+
_ = CableDB.vendorName(vid: id.vid)
110+
_ = CableDB.isUSBIFRegistered(id.vid)
111+
_ = CableDB.curatedCables(vid: id.vid, pid: id.pid)
112+
}
113+
#expect(Bool(true))
114+
}
115+
116+
@Test("Invariant: a vendor name is never empty when CableDB resolves one")
117+
func vendorNameNeverEmptyWhenResolved() {
118+
var examined = 0
119+
var violations: [String] = []
120+
for id in Self.identities {
121+
guard let name = CableDB.vendorName(vid: id.vid) else { continue }
122+
examined += 1
123+
if name.isEmpty {
124+
violations.append("VID 0x\(String(format: "%04X", id.vid)) resolved to an empty vendor name")
125+
}
126+
}
127+
if examined == 0 {
128+
Issue.record("No corpus VID resolved a vendor name at all; this invariant is untested by this sweep")
129+
}
130+
#expect(violations.isEmpty, "\(violations.joined(separator: "\n"))")
131+
}
132+
133+
@Test("Invariant: isUSBIFRegistered implies vendorName is also resolvable")
134+
func usbifRegisteredImpliesVendorNameResolves() {
135+
// Source: `isUSBIFRegistered` checks `store.vendors[vid]?.source == "usbif"`,
136+
// which can only be true if `store.vendors[vid]` exists at all --
137+
// the same dictionary `vendorName(vid:)` reads. A VID that is
138+
// USB-IF-registered but resolves no name at all would mean the two
139+
// methods are reading inconsistent state.
140+
var examined = 0
141+
for id in Self.identities {
142+
guard CableDB.isUSBIFRegistered(id.vid) else { continue }
143+
examined += 1
144+
#expect(CableDB.vendorName(vid: id.vid) != nil,
145+
"VID 0x\(String(format: "%04X", id.vid)) is USB-IF registered but vendorName(vid:) returned nil")
146+
}
147+
if examined == 0 {
148+
Issue.record("No corpus VID was USB-IF registered; this invariant is untested by this sweep")
149+
}
150+
}
151+
152+
@Test("The 5 recently-added corpus-identified cables resolve to their curated rows", arguments: Self.recentlyAddedCables)
153+
func recentlyAddedCablesResolve(_ fixture: (vid: Int, pid: Int, brandContains: String)) {
154+
let matches = CableDB.curatedCables(vid: fixture.vid, pid: fixture.pid)
155+
#expect(!matches.isEmpty,
156+
"0x\(String(format: "%04X", fixture.vid)):0x\(String(format: "%04X", fixture.pid)) resolved no curated cable row")
157+
#expect(matches.contains { $0.brand.localizedCaseInsensitiveContains(fixture.brandContains) },
158+
"0x\(String(format: "%04X", fixture.vid)):0x\(String(format: "%04X", fixture.pid)) resolved \(matches.map(\.brand)), none containing '\(fixture.brandContains)'")
159+
}
160+
}

Tests/WhatCableCoreTests/CorpusCoverageTests.swift

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,22 @@ struct CorpusCoverageTests {
7373
@Test("advanced-PD fixtures present (DAR-136)")
7474
func advancedPDFixtures() throws {
7575
let n = try Self.records().filter { ((Self.signals($0)["advanced_pd"] as? [Any]) ?? []).isEmpty == false }.count
76-
// Actual 226 as of 2026-07. Floor set to ~88% of actual (200), not the
77-
// stale 80 (35% of actual).
78-
#expect(n >= 200, "expected 200+ advanced-PD folders as fixtures for DAR-136; found \(n)")
76+
// Actual 226 (pre-fix) dropped to 117 (2026-07) after correcting a
77+
// Python-pipeline bug in `scripts/inspect-probe.py`'s advanced-PD
78+
// detection: it used to substring-match the bare text "EPR" anywhere
79+
// in probe 19's output, which also matched an ordinary Fixed Supply
80+
// PDO's "EPR-Capable" flag suffix (and, on machines with a TB dock,
81+
// the unrelated "EEPROM Version" property text) even when no PDO
82+
// actually decoded as an EPR AVS APDO. 109 folders flipped from
83+
// "has advanced PD" to "no advanced PD" once that false-positive
84+
// source was removed; the corrected 117 is real signal, matched
85+
// 1:1 by Swift's `PDO.decode` (see PythonOracleCrosscheckTests.swift's
86+
// check 6). The old floor of 200 was calibrated against the inflated
87+
// 226 and would now always fail, so it is re-derived from the
88+
// corrected actual: 0.85 * 117 = 99.45, floor set to 100 (85.5% of
89+
// actual), same margin-not-brittleness standard as the other rows
90+
// in this file.
91+
#expect(n >= 100, "expected 100+ advanced-PD folders as fixtures for DAR-136; found \(n)")
7992
}
8093

8194
@Test("zeroed-VID cable-trust fixtures present (DAR-137)")

0 commit comments

Comments
 (0)