- Rewrite S300 and KPro DTC tables from hvbt_protocol.pdf (the previous tables did not match the PDF; e.g. ERR01.6 is P0350 IGM, not P1361). - Clear DTC: the adapter never echoes the documented ack, but the ECU does clear (bench: 3 of 4 codes cleared, P0350 re-set at once as an active fault). Judge success from the live ERR bytes; wait only 0.6 s for the ack so polling resumes, and report "N of M cleared". - Set the ECU protocol from the adapter name (S300/KPro) on connect; a stale KPro setting made an S300 adapter look unresponsive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
86 lines
2.9 KiB
Dart
86 lines
2.9 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:hvbt_dash/core/protocol/dtc_map.dart';
|
||
|
||
void main() {
|
||
group('S300 DTC map', () {
|
||
test('contains expected number of entries', () {
|
||
expect(s300DtcMap.length, equals(32)); // 4 bytes × 8 bits
|
||
});
|
||
|
||
// Expected codes come from the S300 "DTC map" in hvbt_protocol.pdf.
|
||
test('ERR00 bit0 = P0130 (O2A)', () {
|
||
expect(s300DtcMap['ERR00_bit0'], startsWith('P0130 — '));
|
||
});
|
||
|
||
test('ERR01 bit5 = P0505 (IAC)', () {
|
||
expect(s300DtcMap['ERR01_bit5'], startsWith('P0505 — '));
|
||
});
|
||
|
||
test('bench codes: ERR01.6 = P0350, ERR02.3 = P1298, ERR02.4 = P2649', () {
|
||
expect(s300DtcMap['ERR01_bit6'], startsWith('P0350 — '));
|
||
expect(s300DtcMap['ERR02_bit3'], startsWith('P1298 — '));
|
||
expect(s300DtcMap['ERR02_bit4'], startsWith('P2649 — '));
|
||
});
|
||
|
||
test('undocumented bits show the raw ERR position', () {
|
||
expect(s300DtcMap['ERR03_bit7'], startsWith('ERR03.7 — '));
|
||
});
|
||
|
||
test('every entry has a code and a description', () {
|
||
for (final v in [...s300DtcMap.values, ...kproDtcMap.values]) {
|
||
expect(v.split(' — ').length, equals(2), reason: v);
|
||
}
|
||
});
|
||
});
|
||
|
||
group('KPro DTC map', () {
|
||
test('contains entries for 18 bytes (ERR00..ERR17)', () {
|
||
// Every ERR byte has 8 bits = 144 entries total
|
||
expect(kproDtcMap.length, equals(144));
|
||
});
|
||
|
||
// Expected codes come from the KPro "DTC map" in hvbt_protocol.pdf.
|
||
test('ERR00 bit1 = P1607, ERR05 bit0 = P1259, ERR11 bit6 = P0304', () {
|
||
expect(kproDtcMap['ERR00_bit1'], startsWith('P1607 — '));
|
||
expect(kproDtcMap['ERR05_bit0'], startsWith('P1259 — '));
|
||
expect(kproDtcMap['ERR11_bit6'], startsWith('P0304 — '));
|
||
});
|
||
|
||
test('ERR17 entries present', () {
|
||
expect(kproDtcMap.containsKey('ERR17_bit0'), isTrue);
|
||
expect(kproDtcMap.containsKey('ERR17_bit7'), isTrue);
|
||
});
|
||
});
|
||
|
||
group('decodeDtcs helper', () {
|
||
test('returns empty list when no errors', () {
|
||
final result = decodeDtcs([0, 0, 0, 0], s300DtcMap);
|
||
expect(result, isEmpty);
|
||
});
|
||
|
||
test('decodes ERR00 bit0 = P0130', () {
|
||
final result = decodeDtcs([0x01, 0, 0, 0], s300DtcMap);
|
||
expect(result, contains(s300DtcMap['ERR00_bit0']));
|
||
});
|
||
|
||
test('decodes multiple bits in one byte', () {
|
||
// ERR00 bits 0 and 1
|
||
final result = decodeDtcs([0x03, 0, 0, 0], s300DtcMap);
|
||
expect(result.length, equals(2));
|
||
});
|
||
|
||
test('decodes bits across multiple bytes', () {
|
||
// ERR00 bit0 + ERR01 bit0
|
||
final result = decodeDtcs([0x01, 0x01, 0, 0], s300DtcMap);
|
||
expect(result.length, equals(2));
|
||
});
|
||
|
||
test('skips bits not in map gracefully', () {
|
||
// Use a small dtcMap with only one entry, but set all bits
|
||
final result = decodeDtcs([0xFF, 0, 0, 0], {'ERR00_bit0': 'P0130 — test'});
|
||
// Only the one mapped bit should appear
|
||
expect(result.length, equals(1));
|
||
});
|
||
});
|
||
}
|