1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import 'package:railway_clean_ip_scanner/app/workbench_model.dart';
import 'package:test/test.dart';
import '../fakes.dart';
void main() {
final results = [ok('10.0.0.1', 80), ok('10.0.0.2', 150), ok('10.0.0.3', 400)];
test('top mode gives each row the next-best IP and wraps', () {
final rows = WorkbenchModel.assignments(
count: 5, mode: 'top', results: results, custom: const <int, String>{});
expect(rows.map((r) => r.ip).toList(),
['10.0.0.1', '10.0.0.2', '10.0.0.3', '10.0.0.1', '10.0.0.2']);
expect(rows.any((r) => r.changed || r.stale), isFalse);
});
test('best mode uses the fastest IP for every row', () {
final rows = WorkbenchModel.assignments(
count: 4, mode: 'best', results: results, custom: const <int, String>{});
expect(rows.every((r) => r.ip == '10.0.0.1'), isTrue);
});
test('custom pick is marked changed when it differs from the auto pick', () {
final rows = WorkbenchModel.assignments(
count: 3, mode: 'custom', results: results, custom: const <int, String>{1: '10.0.0.3'});
expect(rows[1].ip, '10.0.0.3');
expect(rows[1].changed, isTrue);
expect(rows[1].stale, isFalse);
expect(rows[0].changed, isFalse);
});
test('custom pick equal to the auto pick is not marked changed', () {
final rows = WorkbenchModel.assignments(
count: 2, mode: 'custom', results: results, custom: const <int, String>{1: '10.0.0.2'});
expect(rows[1].changed, isFalse);
});
test('a custom pick missing from the latest scan is stale', () {
final rows = WorkbenchModel.assignments(
count: 1, mode: 'custom', results: results, custom: const <int, String>{0: '9.9.9.9'});
expect(rows[0].ip, '9.9.9.9');
expect(rows[0].stale, isTrue);
});
test('no results gives empty rows', () {
final rows = WorkbenchModel.assignments(
count: 2, mode: 'top', results: const [], custom: const <int, String>{});
expect(rows.every((r) => r.ip == null), isTrue);
});
test('shortage notice only for top mode when count exceeds results', () {
expect(WorkbenchModel.shortage(mode: 'top', count: 5, resultCount: 3), isTrue);
expect(WorkbenchModel.shortage(mode: 'top', count: 3, resultCount: 3), isFalse);
expect(WorkbenchModel.shortage(mode: 'best', count: 5, resultCount: 3), isFalse);
expect(WorkbenchModel.shortage(mode: 'top', count: 5, resultCount: 0), isFalse);
expect(WorkbenchModel.shortageText(3), 'Only 3 clean IPs found, so some configs will share one.');
});
test('uniqueIps keeps first-seen order and drops nulls and repeats', () {
final rows = WorkbenchModel.assignments(
count: 5, mode: 'top', results: results, custom: const <int, String>{});
expect(WorkbenchModel.uniqueIps(rows), ['10.0.0.1', '10.0.0.2', '10.0.0.3']);
});
test('measured delta is previous minus new, zero without a previous value', () {
expect(WorkbenchModel.measured(200, 150).delta, 50);
expect(WorkbenchModel.measured(100, 150).delta, -50);
expect(WorkbenchModel.measured(null, 150).delta, 0);
});
test('delta labels: down arrow for improvement, up arrow for regression', () {
expect(WorkbenchModel.deltaLabel(12), '↓12');
expect(WorkbenchModel.deltaLabel(-7), '↑7');
});
test('previous delay prefers the last good test over the scan', () {
final delays = {'10.0.0.1': 80};
expect(WorkbenchModel.previousDelay('10.0.0.1', const {}, delays), 80);
expect(
WorkbenchModel.previousDelay('10.0.0.1',
const {'10.0.0.1': Tested(delayMs: 60)}, delays),
60,
);
expect(
WorkbenchModel.previousDelay('10.0.0.1',
const {'10.0.0.1': Tested(dead: true)}, delays),
80,
);
});
test('chip for a row: measuring, dead, stale, latency with delta', () {
final tested = <String, Tested>{
'a': const Tested(delayMs: 90, delta: 15),
'b': const Tested(dead: true),
};
final delays = {'a': 105, 'c': 200};
ChipInfo chip(String? ip, {bool testing = false, Set<String> testingIps = const {}}) {
return WorkbenchModel.chipFor(
ip: ip, tested: tested, delays: delays, testingIps: testingIps, testing: testing);
}
expect(chip(null).kind, ChipKind.stale);
expect(chip('a', testing: true, testingIps: {'a'}).kind, ChipKind.measuring);
expect(chip('b').kind, ChipKind.dead);
expect(chip('a').kind, ChipKind.latency);
expect(chip('a').ms, 90);
expect(chip('a').delta, 15);
expect(chip('c').kind, ChipKind.latency);
expect(chip('c').ms, 200);
expect(chip('z').kind, ChipKind.stale);
});
test('clamping constants match ui.html', () {
expect(genMin, 1);
expect(genMax, 20);
expect(defaultGenCount, 5);
expect(modeOrder, ['top', 'best', 'custom']);
});
}