import 'package:flutter_test/flutter_test.dart'; import 'package:iperf3gui/domain/models/iperf3_event.dart'; void main() { group('Iperf3Event.parse', () { test('parses a start event', () { const line = '{"event":"start","data":{' '"connecting_to":{"host":"192.168.2.182","port":5201},' '"test_start":{"protocol":"TCP","num_streams":4,"duration":10}}}'; final event = Iperf3Event.parse(line); expect(event, isA()); final start = event as Iperf3Start; expect(start.targetHost, equals('192.168.2.182')); expect(start.targetPort, equals(5201)); expect(start.streamCount, equals(4)); expect(start.durationSeconds, equals(10)); expect(start.protocol, equals('TCP')); }); test('parses an interval event with per-stream detail', () { const line = '{"event":"interval","data":{' '"streams":[{"socket":143,"bytes":49283072,' '"bits_per_second":394264576.0,"retransmits":0,"snd_cwnd":2023424,' '"rtt":3521}],' '"sum":{"start":0.0,"end":1.000151,"seconds":1.000151,' '"bytes":98566144,"bits_per_second":788410352.0,"retransmits":0,' '"omitted":false,"sender":true}}}'; final event = Iperf3Event.parse(line); expect(event, isA()); final interval = event as Iperf3Interval; expect(interval.bytes, equals(98566144)); expect(interval.bitsPerSecond, closeTo(788410352.0, 0.1)); expect(interval.retransmits, equals(0)); expect(interval.omitted, isFalse); expect(interval.streams, hasLength(1)); expect(interval.streams.single.socket, equals(143)); expect(interval.streams.single.rtt, equals(3521)); }); test('marks omitted intervals', () { const line = '{"event":"interval","data":{"streams":[],' '"sum":{"start":0.0,"end":1.0,"bytes":1,"bits_per_second":8.0,' '"omitted":true}}}'; final interval = Iperf3Event.parse(line) as Iperf3Interval; expect(interval.omitted, isTrue); }); test('parses an end event with sent and received totals', () { const line = '{"event":"end","data":{' '"sum_sent":{"seconds":10.0,"bytes":987654321,' '"bits_per_second":790123456.0,"retransmits":7},' '"sum_received":{"seconds":10.01,"bytes":987000000,' '"bits_per_second":789000000.0},' '"cpu_utilization_percent":{"host_total":12.5,"remote_total":3.25}}}'; final end = Iperf3Event.parse(line) as Iperf3End; expect(end.sent!.bytes, equals(987654321)); expect(end.sent!.retransmits, equals(7)); expect(end.received!.bitsPerSecond, closeTo(789000000.0, 0.1)); expect(end.hostCpuPercent, closeTo(12.5, 0.01)); expect(end.remoteCpuPercent, closeTo(3.25, 0.01)); }); test('falls back to bidir-reverse keys when present', () { const line = '{"event":"interval","data":{"streams":[],' '"sum_bidir_reverse":{"start":0.0,"end":1.0,"bytes":42,' '"bits_per_second":336.0}}}'; final interval = Iperf3Event.parse(line) as Iperf3Interval; expect(interval.bytes, equals(42)); }); test('parses an error event', () { const line = '{"event":"error","data":"unable to connect to server"}'; final event = Iperf3Event.parse(line); expect(event, isA()); expect((event as Iperf3Error).message, equals('unable to connect to server')); }); test('parses the bridge stop marker', () { final event = Iperf3Event.parse('{"event":"jni_stopped","data":{}}'); expect(event, isA()); }); test('surfaces non-JSON output as a log line rather than dropping it', () { final event = Iperf3Event.parse('iperf3: something unexpected'); expect(event, isA()); expect((event as Iperf3LogLine).text, equals('iperf3: something unexpected')); }); test('surfaces malformed JSON as a log line', () { final event = Iperf3Event.parse('{"event":"interval",'); expect(event, isA()); }); test('treats an unknown event name as a log line', () { final event = Iperf3Event.parse('{"event":"future_thing","data":{}}'); expect(event, isA()); }); test('tolerates a missing data object', () { final event = Iperf3Event.parse('{"event":"interval"}'); expect(event, isA()); expect((event as Iperf3Interval).bytes, equals(0)); }); }); }