feat: add trainer scan protocol models
This commit is contained in:
@ -108,6 +108,126 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
group('TrainerScanEvent.fromBytes', () {
|
||||
test('parses scan lifecycle events', () {
|
||||
expect(
|
||||
TrainerScanEvent.fromBytes(const [1, 0, 7]).kind,
|
||||
TrainerScanEventKind.scanStarted,
|
||||
);
|
||||
expect(
|
||||
TrainerScanEvent.fromBytes(const [1, 2, 8]).kind,
|
||||
TrainerScanEventKind.scanFinished,
|
||||
);
|
||||
expect(
|
||||
TrainerScanEvent.fromBytes(const [1, 3, 9]).kind,
|
||||
TrainerScanEventKind.scanCancelled,
|
||||
);
|
||||
});
|
||||
|
||||
test('parses device event with signed RSSI and flags', () {
|
||||
final event = TrainerScanEvent.fromBytes([
|
||||
1,
|
||||
1,
|
||||
42,
|
||||
0xc1,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
0xd6,
|
||||
trainerScanDeviceFlagFtmsDetected |
|
||||
trainerScanDeviceFlagNameComplete |
|
||||
trainerScanDeviceFlagConnectable,
|
||||
5,
|
||||
...'Kickr'.codeUnits,
|
||||
]);
|
||||
|
||||
expect(event.kind, TrainerScanEventKind.device);
|
||||
expect(event.sequence, 42);
|
||||
expect(event.result, isNotNull);
|
||||
expect(event.result!.address.flags, 0xc1);
|
||||
expect(event.result!.address.bytes, [1, 2, 3, 4, 5, 6]);
|
||||
expect(event.result!.rssi, -42);
|
||||
expect(event.result!.name, 'Kickr');
|
||||
expect(event.result!.ftmsDetected, isTrue);
|
||||
expect(event.result!.nameComplete, isTrue);
|
||||
expect(event.result!.scanResponseSeen, isFalse);
|
||||
expect(event.result!.connectable, isTrue);
|
||||
});
|
||||
|
||||
test('rejects invalid scan payloads', () {
|
||||
expect(
|
||||
() => TrainerScanEvent.fromBytes(const []),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => TrainerScanEvent.fromBytes(const [2, 0, 1]),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => TrainerScanEvent.fromBytes(const [1, 9, 1]),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => TrainerScanEvent.fromBytes(const [1, 1, 1]),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => TrainerScanEvent.fromBytes(const [
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
4,
|
||||
65,
|
||||
]),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('encodeTrainerAddress', () {
|
||||
test('encodes flags and address bytes', () {
|
||||
expect(
|
||||
encodeTrainerAddress(
|
||||
const TrainerAddress(flags: 0xc1, bytes: [1, 2, 3, 4, 5, 6]),
|
||||
),
|
||||
[0xc1, 1, 2, 3, 4, 5, 6],
|
||||
);
|
||||
});
|
||||
|
||||
test('rejects invalid address values', () {
|
||||
expect(
|
||||
() => encodeTrainerAddress(
|
||||
const TrainerAddress(flags: 0, bytes: [1, 2, 3, 4, 5]),
|
||||
),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => encodeTrainerAddress(
|
||||
const TrainerAddress(flags: 256, bytes: [1, 2, 3, 4, 5, 6]),
|
||||
),
|
||||
throwsFormatException,
|
||||
);
|
||||
expect(
|
||||
() => encodeTrainerAddress(
|
||||
const TrainerAddress(flags: 0, bytes: [1, 2, 3, 4, 5, 256]),
|
||||
),
|
||||
throwsFormatException,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
group('standard GATT telemetry parsing', () {
|
||||
test('decodes battery level percentage', () {
|
||||
expect(parseBatteryLevelPercent([0]), 0);
|
||||
|
||||
Reference in New Issue
Block a user