Skip to content

Commit 95a9062

Browse files
committed
Point bundled-plugin tests at gatt-battery
1 parent 837a1ed commit 95a9062

1 file changed

Lines changed: 21 additions & 11 deletions

File tree

Tests/BluetoothExplorerPluginEngineTests/WasmTests.swift

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// BluetoothExplorerPluginEngineTests
44
//
55
// Exercises the WASM runner against hand-written WAT fixtures compiled at test time, plus the
6-
// bundled battery-level.wasm, and checks parity against the native parsers.
6+
// bundled GATT plugins, and checks parity against the native parsers.
77
//
88

99
import Foundation
@@ -144,7 +144,9 @@ struct WasmRunnerTests {
144144
let wasm = try [UInt8](wat2wasm(batteryWAT))
145145
let wasmPlugin = try WasmParserPlugin(manifest: batteryManifest(), moduleBytes: wasm)
146146
let native = NativeWellKnownCharacteristicParser()
147-
for level: UInt8 in [0, 1, 42, 99, 100, 255] {
147+
// 0...100 only: the GATT plugin enforces the spec's valid range, unlike the legacy
148+
// native parser, so 255 is deliberately excluded here and asserted separately below.
149+
for level: UInt8 in [0, 1, 42, 99, 100] {
148150
let request = ParseRequest(kind: .characteristic, uuid: .bit16(0x2A19), payload: Data([level]))
149151
let wasmResult = try #require(await wasmPlugin.parse(request))
150152
let nativeResult = try #require(await native.parse(request))
@@ -162,24 +164,26 @@ struct PluginLoaderTests {
162164
let result = PluginLoader.loadBundled(from: PluginEngineResources.bundle)
163165
#expect(result.failures.isEmpty, "load failures: \(result.failures.map(\.message))")
164166
let battery = try #require(result.loaded.first {
165-
$0.manifest.identifier == "org.pureswift.plugin.battery-level"
167+
$0.manifest.identifier == "org.pureswift.plugin.gatt-battery"
166168
})
167169
// The bundled module (validated against its manifest sha256) decodes a real value.
168170
let request = ParseRequest(kind: .characteristic, uuid: .bit16(0x2A19), payload: Data([88]))
169171
let decoded = try #require(await battery.plugin.parse(request))
170-
#expect(decoded.title == "Battery")
172+
#expect(decoded.title == "Battery Level")
171173
#expect(decoded.fields.first?.value == .uint(88))
172174
}
173175

174176
@Test("Bundled Embedded Swift plugin matches the native parser across values")
175177
func bundledSwiftPluginParity() async throws {
176178
let result = PluginLoader.loadBundled(from: PluginEngineResources.bundle)
177179
let battery = try #require(result.loaded.first {
178-
$0.manifest.identifier == "org.pureswift.plugin.battery-level"
180+
$0.manifest.identifier == "org.pureswift.plugin.gatt-battery"
179181
})
180182
let native = NativeWellKnownCharacteristicParser()
181183
var failures = [UInt8]()
182-
for level: UInt8 in [0, 1, 42, 99, 100, 255] {
184+
// 0...100 only: the GATT plugin enforces the spec's valid range, unlike the legacy
185+
// native parser, so 255 is deliberately excluded here and asserted separately below.
186+
for level: UInt8 in [0, 1, 42, 99, 100] {
183187
let request = ParseRequest(kind: .characteristic, uuid: .bit16(0x2A19), payload: Data([level]))
184188
guard let wasmResult = await battery.plugin.parse(request) else {
185189
failures.append(level)
@@ -191,13 +195,19 @@ struct PluginLoaderTests {
191195
#expect(wasmResult.fields.first?.unit == "%", "level \(level)")
192196
}
193197
#expect(failures.isEmpty, "levels returning nil: \(failures)")
198+
199+
// Out-of-range battery level: the plugin rejects it (GATTBatteryPercentage is 0...100)
200+
// where the legacy native parser happily returns 255.
201+
let invalid = ParseRequest(kind: .characteristic, uuid: .bit16(0x2A19), payload: Data([255]))
202+
#expect(await battery.plugin.parse(invalid) == nil)
203+
#expect(await native.parse(invalid) != nil)
194204
}
195205

196206
@Test("Bundled plugin declines a payload it does not recognize")
197207
func bundledSwiftPluginDeclines() async throws {
198208
let result = PluginLoader.loadBundled(from: PluginEngineResources.bundle)
199209
let battery = try #require(result.loaded.first {
200-
$0.manifest.identifier == "org.pureswift.plugin.battery-level"
210+
$0.manifest.identifier == "org.pureswift.plugin.gatt-battery"
201211
})
202212
// Empty payload: the guest returns 0 ("not mine"), which must surface as nil, not an error.
203213
let empty = ParseRequest(kind: .characteristic, uuid: .bit16(0x2A19), payload: Data())
@@ -212,19 +222,19 @@ struct PluginLoaderTests {
212222
let manifestURLs = PluginEngineResources.bundle.urls(
213223
forResourcesWithExtension: "json", subdirectory: "Plugins") ?? []
214224
let batteryManifestURL = try #require(manifestURLs.first {
215-
$0.lastPathComponent == "battery-level.bleplugin.json"
225+
$0.lastPathComponent == "gatt-battery.bleplugin.json"
216226
})
217227
// Write a manifest copy with a wrong hash next to the real module and load it.
218228
let tempDir = URL(fileURLWithPath: NSTemporaryDirectory())
219229
.appendingPathComponent("bleplug-\(UUID().uuidString)")
220230
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
221231
defer { try? FileManager.default.removeItem(at: tempDir) }
222232

223-
let moduleURL = batteryManifestURL.deletingLastPathComponent().appendingPathComponent("battery-level.wasm")
224-
try Data(contentsOf: moduleURL).write(to: tempDir.appendingPathComponent("battery-level.wasm"))
233+
let moduleURL = batteryManifestURL.deletingLastPathComponent().appendingPathComponent("gatt-battery.wasm")
234+
try Data(contentsOf: moduleURL).write(to: tempDir.appendingPathComponent("gatt-battery.wasm"))
225235
let badManifest = """
226236
{"manifestVersion":1,"id":"x","name":"x","version":"1.0.0","abi":1,
227-
"module":"battery-level.wasm","sha256":"deadbeef","matches":{"characteristicUUIDs":["2A19"]}}
237+
"module":"gatt-battery.wasm","sha256":"deadbeef","matches":{"characteristicUUIDs":["2A19"]}}
228238
"""
229239
let badManifestURL = tempDir.appendingPathComponent("x.bleplugin.json")
230240
try Data(badManifest.utf8).write(to: badManifestURL)

0 commit comments

Comments
 (0)