Keep dropped-out signals as MISSING rows; clear the nav bar in the mark sheet
CI / Analyze & Test (push) Successful in 10s
CI / Debug APK (push) Successful in 26s

A signal absent from the latest state now stays listed (from the last
envelope seen on this gateway) and renders as missing, distinct from
null and stale as BOUNDARY.md requires; rows no longer jump.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DDwfd6Ki8UfG4hK6W5YpJz
This commit is contained in:
2026-10-11 04:01:05 +09:00
parent f6d9eb120e
commit d965031a56
3 changed files with 54 additions and 6 deletions
+18
View File
@@ -91,4 +91,22 @@ void main() {
await b.stop();
await gw.server.close(force: true);
});
test('a signal that drops out stays known as missing', () async {
final gw = FakeGateway();
await gw.start();
final b = Boundary(gw.url)..start();
await until(() => b.state == LinkState.up);
Map<String, dynamic> env(num v) => {'timestamp': 0, 'monotonic': 0, 'value': v, 'unit': 'x'};
gw.sockets.first.add(jsonEncode({'t': 'state', 'seq': 1, 'signals': {'a': env(1), 'b': env(2)}}));
await until(() => b.signals.length == 2);
gw.sockets.first.add(jsonEncode({'t': 'state', 'seq': 2, 'signals': {'a': env(3)}}));
await until(() => b.signals.length == 1);
expect(b.seen.keys, containsAll(['a', 'b']));
expect(b.signals.containsKey('b'), isFalse);
b.retarget(gw.url);
expect(b.seen, isEmpty);
await b.stop();
await gw.server.close(force: true);
});
}