Skip to content

NFR-2.1: Unit tests for public API (≥80% coverage) #30

Description

@itsniper

Goal

Write unit tests for every public API surface on ReliaBLEManager and related public types, achieving at least 80% code-path coverage across the library's test target.

Context

Parent requirement NFR-2.1 from #9:

Write unit tests for all public API methods, covering at least 80% of code paths.

The library already has a ReliaBLETests target (Tests/ReliaBLETests/ReliaBLEManagerTests.swift) with a handful of behavioral and compile-time Sendable proofs. Coverage is still thin relative to the public API:

Surface Current coverage
init(config:) Implicit only (every test constructs a manager)
loggingService Compile-time Sendable proof only
state / currentState Replay + broadcast tests
authorizeBluetooth() Compile-time call only; no authorization success/failure paths
peripheralDiscoveries No-replay test only
discoveredPeripherals No dedicated tests
startScanning(services:) / stopScanning() Compile-time call only; no scanning lifecycle
connect(to:) Stale-snapshot notFound path only

Public types such as BluetoothState.description, AuthorizationError, PeripheralError, Peripheral, AdvertisementData, PeripheralDiscoveryEvent, and ReliaBLEConfig also lack direct behavioral tests.

Deliverable

  1. Expand ReliaBLEManagerTests (and add focused test files if warranted) to exercise every public method and property on ReliaBLEManager, including error and edge-case paths.
  2. Add tests for public value types where behavior is non-trivial (e.g. BluetoothState.description for each case, Peripheral identity/hash semantics).
  3. Establish a coverage baseline — run swift test with code-coverage enabled (e.g. swift test --enable-code-coverage + llvm-cov / Xcode coverage report) and document the measured percentage in the PR that closes this issue.
  4. Reach ≥ 80% code-path coverage for Sources/ReliaBLE/ as exercised through ReliaBLETests. If the target is not met, list the remaining uncovered paths with rationale for deferral (if any).

Suggested test scenarios (non-exhaustive)

  • authorizeBluetooth() — denied, restricted, and allowed paths (driven via mock central state).
  • startScanning / stopScanning — state transitions to .scanning and back; no-op when central manager is not yet initialized.
  • discoveredPeripherals — replay on subscribe; list updates when peripherals are discovered.
  • peripheralDiscoveries — events emitted during a mock-driven scan.
  • connect(to:) — success path when peripheral is in the live registry (pairs with NFR-2.2 mock harness).
  • BluetoothState.description — all enum cases produce expected strings.

Acceptance criteria

  • Every public method and property on ReliaBLEManager has at least one behavioral test (not just a compile-time Sendable proof).
  • swift test passes on macOS with zero failures.
  • Measured code coverage for Sources/ReliaBLE/ is ≥ 80% (attach the coverage report or command output to the closing PR).
  • New tests follow existing conventions: Swift Testing (@Test), @testable import ReliaBLEMock, no real CoreBluetooth hardware required.

References

  • Parent: NFR 2: Automated Testing #9 (NFR 2 — Automated Testing)
  • Related: NFR-2.2 sub-issue (BLE mocking infrastructure for CI)
  • Architecture: AGENTS.md (three-target SPM trick, @BluetoothActor serialization)
  • Existing tests: Tests/ReliaBLETests/ReliaBLEManagerTests.swift

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions