Why
tray.rs (976 LOC) and mpris.rs (879 LOC) are the two largest single-file services and have zero test modules — yet they contain exactly the pure, hermetically-testable logic that most deserves tests: parse_layout_node/parse_menu_entry recursively parse untrusted DBusMenu structures from arbitrary tray apps (separator roots, invisible nodes, submenu recursion, toggle-type strings), and read_metadata/parse_artist_array/parse_length/parse_track_id parse arbitrary media-player metadata including documented spec violations (i64 lengths, string trackids). bluetooth/ and wifi/ already model the answer: a parse.rs + types.rs split with the parser under unit test. Also de-risks PR #198 (tray diff-by-key), which leans on parser output stability.
Sketch
- Promote
tray.rs → tray/{mod.rs,parse.rs,types.rs} and mpris.rs → mpris/{mod.rs,parse.rs}.
- Move
parse_layout_node, parse_menu_entry, bool_prop/str_prop/i32_prop, strip_accel into tray/parse.rs; parse_artist_array, parse_length, parse_track_id and the map-extraction half of read_metadata into mpris/parse.rs.
- Both parsers take
OwnedValue, so tests construct zvariant Structure/Array fixtures in memory — pure hermetic bucket, runs in the default cargo test and the nix doCheck.
- Adversarial cases to pin: <3-field structures, invisible root, separator-as-root, deep submenu nesting, negative mpris:length, trackid as Variant-wrapped ObjectPath.
- Public API (
menu(), Player) unchanged.
Effort: medium · Value: high
💡 From a Fable codebase idea-sweep — grounded against main @ 610a499. The sketch is a starting point, not a spec.
Why
tray.rs(976 LOC) andmpris.rs(879 LOC) are the two largest single-file services and have zero test modules — yet they contain exactly the pure, hermetically-testable logic that most deserves tests:parse_layout_node/parse_menu_entryrecursively parse untrusted DBusMenu structures from arbitrary tray apps (separator roots, invisible nodes, submenu recursion, toggle-type strings), andread_metadata/parse_artist_array/parse_length/parse_track_idparse arbitrary media-player metadata including documented spec violations (i64 lengths, string trackids). bluetooth/ and wifi/ already model the answer: a parse.rs + types.rs split with the parser under unit test. Also de-risks PR #198 (tray diff-by-key), which leans on parser output stability.Sketch
tray.rs→tray/{mod.rs,parse.rs,types.rs}andmpris.rs→mpris/{mod.rs,parse.rs}.parse_layout_node,parse_menu_entry,bool_prop/str_prop/i32_prop,strip_accelinto tray/parse.rs;parse_artist_array,parse_length,parse_track_idand the map-extraction half ofread_metadatainto mpris/parse.rs.OwnedValue, so tests construct zvariant Structure/Array fixtures in memory — pure hermetic bucket, runs in the defaultcargo testand the nix doCheck.menu(),Player) unchanged.Effort: medium · Value: high
💡 From a Fable codebase idea-sweep — grounded against
main@ 610a499. The sketch is a starting point, not a spec.