fix(#155): manual path entry honors the configured path-hash width
The "Set Path" dialog parsed, built, and displayed hop prefixes as a fixed 1 byte (substring(0,2)), so on a 2-/3-byte path-hash mesh manual entry produced wrong-width routing paths and the helper text claimed "1 byte". Make it width- aware from connector.pathHashByteWidth. - parsePathPrefixes(text, width, invalid): static + testable; each entry must be EXACTLY width*2 hex chars (wrong-length / malformed go to invalid, never silently truncated); width clamped >= 1. - _updateTextFromContacts / display / maxLength group by the configured width; the display substring is guarded against short keys. - show() takes pathHashByteWidth; the chat + path-management callers pass connector.pathHashByteWidth. - l10n: reworded the path-entry helper / example / instructions to be width- agnostic (dropped the "2 hex / 1 byte / first byte" claims). The 17 non-English locales keep their prior strings, flagged for re-translation (English fixed). analyze clean; 6 parsePathPrefixes tests (incl. exact-length + clamp). Gemini v1 BLOCKER (unguarded substring) + MAJOR (silent truncation) fixed; v2 MAJORs were the pre-existing refresh button (out of scope), v2 MINOR (1-byte example) fixed. Closes #155 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>pull/201/head
parent
09e29f6782
commit
d2d7930858
@ -0,0 +1,57 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:meshcore_open/widgets/path_selection_dialog.dart';
|
||||
|
||||
void main() {
|
||||
group('PathSelectionDialog.parsePathPrefixes (#155)', () {
|
||||
test('width 1 — single-byte hops', () {
|
||||
final invalid = <String>[];
|
||||
expect(PathSelectionDialog.parsePathPrefixes('A1,F2,3C', 1, invalid), [
|
||||
0xA1,
|
||||
0xF2,
|
||||
0x3C,
|
||||
]);
|
||||
expect(invalid, isEmpty);
|
||||
});
|
||||
|
||||
test('width 2 — two-byte hops, each entry 4 hex chars', () {
|
||||
final invalid = <String>[];
|
||||
expect(PathSelectionDialog.parsePathPrefixes('84AB,C1D2', 2, invalid), [
|
||||
0x84,
|
||||
0xAB,
|
||||
0xC1,
|
||||
0xD2,
|
||||
]);
|
||||
expect(invalid, isEmpty);
|
||||
});
|
||||
|
||||
test('wrong-length entries are rejected, never silently truncated', () {
|
||||
final invalid = <String>[];
|
||||
// too short (1 byte) and too long (3 bytes) on a 2-byte mesh
|
||||
final bytes = PathSelectionDialog.parsePathPrefixes(
|
||||
'84,AABBCC',
|
||||
2,
|
||||
invalid,
|
||||
);
|
||||
expect(bytes, isEmpty);
|
||||
expect(invalid, ['84', 'AABBCC']);
|
||||
});
|
||||
|
||||
test('non-hex entry is rejected', () {
|
||||
final invalid = <String>[];
|
||||
PathSelectionDialog.parsePathPrefixes('ZZ', 1, invalid);
|
||||
expect(invalid, ['ZZ']);
|
||||
});
|
||||
|
||||
test('width < 1 is clamped to 1', () {
|
||||
final invalid = <String>[];
|
||||
expect(PathSelectionDialog.parsePathPrefixes('A1', 0, invalid), [0xA1]);
|
||||
expect(invalid, isEmpty);
|
||||
});
|
||||
|
||||
test('empty input → empty path', () {
|
||||
final invalid = <String>[];
|
||||
expect(PathSelectionDialog.parsePathPrefixes('', 2, invalid), isEmpty);
|
||||
expect(invalid, isEmpty);
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Reference in new issue