Skip to content

Commit f6b9581

Browse files
authored
Migrate to Swift Testing (#58)
# Migrate to Swift Testing ## ♻️ Current situation & Problem This PR migrates the project to use Swift Testing for unit testing. ## ⚙️ Release Notes * Migrate to Swift Testing. ## 📚 Documentation -- ## ✅ Testing -- ## 📝 Code of Conduct & Contributing Guidelines By creating and submitting this pull request, you agree to follow our [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md): - [x] I agree to follow the [Code of Conduct](https://github.com/StanfordSpezi/.github/blob/main/CODE_OF_CONDUCT.md) and [Contributing Guidelines](https://github.com/StanfordSpezi/.github/blob/main/CONTRIBUTING.md).
1 parent e2600a2 commit f6b9581

22 files changed

+561
-500
lines changed

Package.swift

+7-9
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,19 @@ let package = Package(
2525
.library(name: "SpeziBluetooth", targets: ["SpeziBluetooth"])
2626
],
2727
dependencies: [
28-
.package(url: "https://github.com/StanfordSpezi/SpeziFoundation", from: "2.0.0-beta.1"),
29-
.package(url: "https://github.com/StanfordSpezi/Spezi", from: "1.7.1"),
30-
.package(url: "https://github.com/StanfordSpezi/SpeziNetworking", from: "2.1.0"),
28+
.package(url: "https://github.com/StanfordSpezi/SpeziFoundation.git", from: "2.1.1"),
29+
.package(url: "https://github.com/StanfordSpezi/Spezi.git", from: "1.7.1"),
30+
.package(url: "https://github.com/StanfordSpezi/SpeziNetworking.git", from: "2.3.0"),
3131
.package(url: "https://github.com/apple/swift-nio.git", from: "2.59.0"),
3232
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.4"),
33-
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.2.0"),
34-
.package(url: "https://github.com/StanfordBDHG/XCTestExtensions.git", from: "1.0.0")
33+
.package(url: "https://github.com/apple/swift-atomics.git", from: "1.2.0")
3534
] + swiftLintPackage(),
3635
targets: [
3736
.target(
3837
name: "SpeziBluetooth",
3938
dependencies: [
4039
.product(name: "Spezi", package: "Spezi"),
41-
.product(name: "NIO", package: "swift-nio"),
40+
.product(name: "NIOCore", package: "swift-nio"),
4241
.product(name: "OrderedCollections", package: "swift-collections"),
4342
.product(name: "SpeziFoundation", package: "SpeziFoundation"),
4443
.product(name: "ByteCoding", package: "SpeziNetworking"),
@@ -80,9 +79,8 @@ let package = Package(
8079
dependencies: [
8180
.target(name: "SpeziBluetooth"),
8281
.target(name: "SpeziBluetoothServices"),
83-
.product(name: "XCTByteCoding", package: "SpeziNetworking"),
84-
.product(name: "NIO", package: "swift-nio"),
85-
.product(name: "XCTestExtensions", package: "XCTestExtensions")
82+
.product(name: "NIOCore", package: "swift-nio"),
83+
.product(name: "ByteCodingTesting", package: "SpeziNetworking")
8684
],
8785
plugins: [] + swiftLintPlugin()
8886
)

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ class ExampleDelegate: SpeziAppDelegate {
148148
Once you have the `Bluetooth` module configured within your Spezi app, you can access the module within your
149149
[`Environment`](https://developer.apple.com/documentation/swiftui/environment).
150150

151-
You can use the [`scanNearbyDevices(enabled:with:minimumRSSI:advertisementStaleInterval:autoConnect:)`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/swiftui/view/scanNearbyDevices(enabled:with:minimumRSSI:advertisementStaleInterval:autoConnect:))
152-
and [`autoConnect(enabled:with:minimumRSSI:advertisementStaleInterval:)`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/swiftui/view/autoConnect(enabled:with:minimumRSSI:advertisementStaleInterval:))
151+
You can use the [`scanNearbyDevices(enabled:with:minimumRSSI:advertisementStaleInterval:autoConnect:)`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/swiftuicore/view/scannearbydevices(enabled:with:minimumrssi:advertisementstaleinterval:autoconnect:))
152+
and [`autoConnect(enabled:with:minimumRSSI:advertisementStaleInterval:)`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/swiftuicore/view/autoconnect(enabled:with:minimumrssi:advertisementstaleinterval:))
153153
modifiers to scan for nearby devices and/or auto connect to the first available device. Otherwise, you can also manually start and stop scanning for nearby devices
154154
using [`scanNearbyDevices(minimumRSSI:advertisementStaleInterval:autoConnect:)`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/bluetooth/scanNearbyDevices(minimumRSSI:advertisementStaleInterval:autoConnect:)) and [`stopScanning()`](https://swiftpackageindex.com/stanfordspezi/spezibluetooth/documentation/spezibluetooth/bluetooth/stopScanning()).
155155

Sources/SpeziBluetooth/CoreBluetooth/BluetoothManager.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
import CoreBluetooth
10-
import NIO
10+
import NIOCore
1111
import Observation
1212
import OrderedCollections
1313
import OSLog

Sources/SpeziBluetoothServices/Characteristics/BloodPressureMeasurement.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import ByteCoding
1010
import Foundation
11-
import NIO
11+
import NIOCore
1212
import SpeziNumerics
1313

1414

Sources/SpeziBluetoothServices/Characteristics/MeasurementInterval.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
import ByteCoding
10-
import NIO
10+
import NIOCore
1111

1212

1313
/// Represents the time between measurements.

Sources/SpeziBluetoothServices/Characteristics/PnPID.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
import ByteCoding
10-
import NIO
10+
import NIOCore
1111

1212

1313
/// Bluetooth Vendor ID Source.

Sources/SpeziBluetoothServices/Characteristics/RecordAccess/RecordAccessResponseFormatError.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public struct RecordAccessResponseFormatError {
4747
}
4848

4949

50-
extension RecordAccessResponseFormatError.Reason: Sendable {}
50+
extension RecordAccessResponseFormatError.Reason: Sendable, Hashable {}
5151

5252

5353
extension RecordAccessResponseFormatError: Error {}

Sources/SpeziBluetoothServices/Characteristics/TemperatureMeasurement.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import ByteCoding
1010
import Foundation
11-
import NIO
11+
import NIOCore
1212

1313

1414
/// A temperature measurement.

Sources/SpeziBluetoothServices/Characteristics/TemperatureType.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
import ByteCoding
10-
import NIO
10+
import NIOCore
1111

1212

1313
/// The location of a temperature measurement.

Sources/SpeziBluetoothServices/Characteristics/Time/DateTime.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import ByteCoding
1010
import Foundation
11-
import NIO
11+
import NIOCore
1212

1313

1414
/// Date and time information.

Sources/SpeziBluetoothServices/TestingSupport/EventLog.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
@_spi(TestingSupport)
1010
import ByteCoding
1111
import CoreBluetooth
12-
import NIO
12+
import NIOCore
1313
@_spi(TestingSupport)
1414
import SpeziBluetooth
1515

Tests/SpeziBluetoothServicesTests/BloodPressureTests.swift

+25-24
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@
66
// SPDX-License-Identifier: MIT
77
//
88

9+
import ByteCodingTesting
910
import CoreBluetooth
10-
import NIO
11+
import NIOCore
1112
@_spi(TestingSupport)
1213
@testable import SpeziBluetooth
1314
@_spi(TestingSupport)
1415
@testable import SpeziBluetoothServices
15-
import XCTByteCoding
16-
import XCTest
16+
import Testing
1717

1818

19-
final class BloodPressureTests: XCTestCase {
19+
@Suite("Blood Pressure Service")
20+
struct BloodPressureTests {
21+
@Test("Blood Pressure Measurement")
2022
func testBloodPressureMeasurement() throws {
2123
let time = DateTime(hours: 13, minutes: 12, seconds: 12)
2224

@@ -35,6 +37,7 @@ final class BloodPressureTests: XCTestCase {
3537
))
3638
}
3739

40+
@Test("Immediate Cuff Pressure")
3841
func testIntermediateCuffPressure() throws {
3942
let time = DateTime(hours: 13, minutes: 12, seconds: 12)
4043

@@ -51,6 +54,7 @@ final class BloodPressureTests: XCTestCase {
5154
))
5255
}
5356

57+
@Test("Blood Pressure Feature")
5458
func testBloodPressureFeature() throws {
5559
let features: BloodPressureFeature = [
5660
.bodyMovementDetectionSupported,
@@ -64,15 +68,15 @@ final class BloodPressureTests: XCTestCase {
6468
.userFacingTimeSupported
6569
]
6670

67-
XCTAssertTrue(features.contains(.bodyMovementDetectionSupported))
68-
XCTAssertTrue(features.contains(.cuffFitDetectionSupported))
69-
XCTAssertTrue(features.contains(.irregularPulseDetectionSupported))
70-
XCTAssertTrue(features.contains(.pulseRateRangeDetectionSupported))
71-
XCTAssertTrue(features.contains(.measurementPositionDetectionSupported))
72-
XCTAssertTrue(features.contains(.multipleBondsSupported))
73-
XCTAssertTrue(features.contains(.e2eCrcSupported))
74-
XCTAssertTrue(features.contains(.userDataServiceSupported))
75-
XCTAssertTrue(features.contains(.userFacingTimeSupported))
71+
#expect(features.contains(.bodyMovementDetectionSupported))
72+
#expect(features.contains(.cuffFitDetectionSupported))
73+
#expect(features.contains(.irregularPulseDetectionSupported))
74+
#expect(features.contains(.pulseRateRangeDetectionSupported))
75+
#expect(features.contains(.measurementPositionDetectionSupported))
76+
#expect(features.contains(.multipleBondsSupported))
77+
#expect(features.contains(.e2eCrcSupported))
78+
#expect(features.contains(.userDataServiceSupported))
79+
#expect(features.contains(.userFacingTimeSupported))
7680

7781
let features2: BloodPressureFeature = [BloodPressureFeature.bodyMovementDetectionSupported, .irregularPulseDetectionSupported]
7882
let features3: BloodPressureFeature = [BloodPressureFeature.bodyMovementDetectionSupported, .userFacingTimeSupported]
@@ -82,6 +86,7 @@ final class BloodPressureTests: XCTestCase {
8286
try testIdentity(from: features3)
8387
}
8488

89+
@Test("Blood Pressure Feature Strings")
8590
func testBloodPressureFeatureStrings() {
8691
let features: BloodPressureFeature = [
8792
.bodyMovementDetectionSupported,
@@ -95,14 +100,12 @@ final class BloodPressureTests: XCTestCase {
95100
.userFacingTimeSupported
96101
]
97102

98-
XCTAssertEqual(
99-
features.description,
100-
"[bodyMovementDetectionSupported, cuffFitDetectionSupported, irregularPulseDetectionSupported, pulseRateRangeDetectionSupported, measurementPositionDetectionSupported, multipleBondsSupported, e2eCrcSupported, userDataServiceSupported, userFacingTimeSupported]"
101-
) // swiftlint:disable:previous line_length
102-
103-
XCTAssertEqual(features.debugDescription, "BloodPressureFeature(rawValue: 0x1FF)")
103+
// swiftlint:disable:next line_length
104+
#expect(features.description == "[bodyMovementDetectionSupported, cuffFitDetectionSupported, irregularPulseDetectionSupported, pulseRateRangeDetectionSupported, measurementPositionDetectionSupported, multipleBondsSupported, e2eCrcSupported, userDataServiceSupported, userFacingTimeSupported]")
105+
#expect(features.debugDescription == "BloodPressureFeature(rawValue: 0x1FF)")
104106
}
105107

108+
@Test("Blood Pressure Status Strings")
106109
func testBloodPressureStatusStrings() {
107110
let status: BloodPressureMeasurement.Status = [
108111
.bodyMovementDetected,
@@ -113,10 +116,8 @@ final class BloodPressureTests: XCTestCase {
113116
.improperMeasurementPosition
114117
]
115118

116-
XCTAssertEqual(
117-
status.description,
118-
"[bodyMovementDetected, looseCuffFit, irregularPulse, pulseRateExceedsUpperLimit, pulseRateBelowLowerLimit, improperMeasurementPosition]"
119-
)
120-
XCTAssertEqual(status.debugDescription, "Status(rawValue: 0x3F)")
119+
// swiftlint:disable:next line_length
120+
#expect(status.description == "[bodyMovementDetected, looseCuffFit, irregularPulse, pulseRateExceedsUpperLimit, pulseRateBelowLowerLimit, improperMeasurementPosition]")
121+
#expect(status.debugDescription == "Status(rawValue: 0x3F)")
121122
}
122123
}

Tests/SpeziBluetoothServicesTests/BluetoothServicesTests.swift

+10-6
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@
66
// SPDX-License-Identifier: MIT
77
//
88

9-
import NIO
9+
import ByteCodingTesting
10+
import NIOCore
1011
@_spi(TestingSupport)
1112
@testable import SpeziBluetooth
1213
@_spi(TestingSupport)
1314
@testable import SpeziBluetoothServices
14-
import XCTByteCoding
15-
import XCTest
15+
import Testing
1616

1717

18-
final class BluetoothServicesTests: XCTestCase {
19-
func testServices() async throws {
18+
@Suite("Bluetooth Services")
19+
struct BluetoothServicesTests {
20+
@Test("Services init")
21+
func testServices() {
2022
_ = TestService()
2123
_ = HealthThermometerService()
2224
_ = DeviceInformationService()
@@ -27,10 +29,12 @@ final class BluetoothServicesTests: XCTestCase {
2729
_ = PulseOximeterService()
2830
}
2931

32+
@Test("BT UUID")
3033
func testUUID() {
31-
XCTAssertEqual(BTUUID.toCustomShort(.testService), "F001")
34+
#expect(BTUUID.toCustomShort(.testService) == "F001")
3235
}
3336

37+
@Test("Event Log")
3438
func testEventLog() throws {
3539
try testIdentity(from: EventLog.none)
3640
try testIdentity(from: EventLog.subscribedToNotification(.eventLogCharacteristic))

0 commit comments

Comments
 (0)