You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Ensure all BLE interactions in tests use mocking or simulation so swift test runs reliably in CI without physical Bluetooth hardware or user authorization prompts.
Use mocking or simulation for BLE peripherals to facilitate testing in CI environments.
The project already has foundational mock infrastructure via the three-target SPM trick documented in AGENTS.md:
ReliaBLE — production target; real CoreBluetooth.
ReliaBLEMock — same sources with CBCentralManagerFactory.swift excluded; CoreBluetoothMockAliases.swift rebinds CBCentralManager, CBPeripheral, etc. to Nordic Semi's CBM* types.
ReliaBLETests — depends on ReliaBLEMock, not ReliaBLE.
BluetoothActor instantiates the central via CBCentralManagerFactory.instance(..., forceMock: true). The production factory ignores forceMock; the mock factory honors it — this parameter is load-bearing and must not be removed.
Current tests exercise the mock target but do not yet drive simulated peripherals or central-manager state changes. Several NFR-2.1 scenarios (scanning, discovery events, connection success, authorization flows) depend on this harness.
Deliverable
Document the mock testing pattern in a brief comment block or test helper (e.g. MockBLEHarness / BluetoothTestSupport) that shows how to:
Obtain the mock CBMCentralManager (or equivalent) from the test context.
Simulate central-manager state changes (powered on/off, unauthorized, etc.).
Simulate peripheral discovery (simulatePeripheral or delegate callback injection).
Simulate connection events.
Refactor or extend tests so every test that touches BLE goes through the mock stack — no test should require a real radio or iOS Bluetooth permission dialog.
Verify CI readiness — confirm swift test passes in a headless macOS environment (GitHub Actions runner) with no Bluetooth adapter dependency. Coordinate with NFR 11: Continuous Integration (GitHub Actions) #21 (NFR 11 — CI) so the test job uses the mock target exclusively.
Preserve the three-target constraint — library code must continue to call CBCentralManagerFactory.instance(...), never CBCentralManager(...) directly. Do not move mock-only logic into Sources/ReliaBLE/.
Existing aliases in Sources/ReliaBLEMock/CoreBluetoothMockAliases.swift.
@testable import ReliaBLEMock for access to internal BluetoothActor in tests.
Acceptance criteria
swift test completes successfully on a macOS CI runner with no Bluetooth hardware.
At least one integration-style test drives a full mock flow: central powers on → scan discovers a simulated peripheral → discoveredPeripherals / peripheralDiscoveries emit expected values.
No test imports or links against the production ReliaBLE target.
forceMock: true remains in BluetoothActor.setupCentralManager() (or equivalent).
A reusable test helper exists so NFR-2.1 tests can add scenarios without duplicating mock setup boilerplate.
Goal
Ensure all BLE interactions in tests use mocking or simulation so
swift testruns reliably in CI without physical Bluetooth hardware or user authorization prompts.Context
Parent requirement NFR-2.2 from #9:
The project already has foundational mock infrastructure via the three-target SPM trick documented in
AGENTS.md:ReliaBLE— production target; realCoreBluetooth.ReliaBLEMock— same sources withCBCentralManagerFactory.swiftexcluded;CoreBluetoothMockAliases.swiftrebindsCBCentralManager,CBPeripheral, etc. to Nordic Semi'sCBM*types.ReliaBLETests— depends onReliaBLEMock, notReliaBLE.BluetoothActorinstantiates the central viaCBCentralManagerFactory.instance(..., forceMock: true). The production factory ignoresforceMock; the mock factory honors it — this parameter is load-bearing and must not be removed.Current tests exercise the mock target but do not yet drive simulated peripherals or central-manager state changes. Several NFR-2.1 scenarios (scanning, discovery events, connection success, authorization flows) depend on this harness.
Deliverable
MockBLEHarness/BluetoothTestSupport) that shows how to:CBMCentralManager(or equivalent) from the test context.simulatePeripheralor delegate callback injection).swift testpasses in a headless macOS environment (GitHub Actions runner) with no Bluetooth adapter dependency. Coordinate with NFR 11: Continuous Integration (GitHub Actions) #21 (NFR 11 — CI) so the test job uses the mock target exclusively.CBCentralManagerFactory.instance(...), neverCBCentralManager(...)directly. Do not move mock-only logic intoSources/ReliaBLE/.Mock capabilities to leverage
CBMCentralManager,CBMPeripheral, delegate simulation APIs.Sources/ReliaBLEMock/CoreBluetoothMockAliases.swift.@testable import ReliaBLEMockfor access to internalBluetoothActorin tests.Acceptance criteria
swift testcompletes successfully on a macOS CI runner with no Bluetooth hardware.discoveredPeripherals/peripheralDiscoveriesemit expected values.ReliaBLEtarget.forceMock: trueremains inBluetoothActor.setupCentralManager()(or equivalent).References
AGENTS.md(three-target SPM trick, lazy central-manager init)Sources/ReliaBLEMock/CoreBluetoothMockAliases.swift