-
Notifications
You must be signed in to change notification settings - Fork 60
Expand file tree
/
Copy pathgolden_test_set_up_accumulation_test.dart
More file actions
143 lines (126 loc) · 4.85 KB
/
Copy pathgolden_test_set_up_accumulation_test.dart
File metadata and controls
143 lines (126 loc) · 4.85 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import 'package:alchemist/alchemist.dart';
import 'package:alchemist/src/golden_test_adapter.dart';
import 'package:alchemist/src/golden_test_runner.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
class MockGoldenTestRunner extends Mock implements GoldenTestRunner {}
class MockWidgetTester extends Mock implements WidgetTester {}
void main() {
setUpAll(() {
registerFallbackValue(MockWidgetTester());
registerFallbackValue(const SizedBox());
registerFallbackValue(const BoxConstraints());
});
group('goldenTest setUp accumulation', () {
// Stores every callback passed to setUp during test registration.
late List<ValueGetter<dynamic>> registeredSetUpCallbacks;
// Stores every (variant, callback) pair passed to testWidgets.
late List<(TestVariant<Object?>, Future<void> Function(WidgetTester))>
registeredTests;
late MockGoldenTestRunner runner;
setUp(() {
registeredSetUpCallbacks = [];
registeredTests = [];
runner = MockGoldenTestRunner();
// Use the real adapter so goldenTest → adapter.setUp → setUpFn path
// is exercised.
goldenTestAdapter = const FlutterGoldenTestAdapter();
goldenTestRunner = runner;
hostPlatform = HostPlatform.linux;
// Intercept setUp: record each callback without registering it in
// flutter_test's real infrastructure (which would pollute this test).
setUpFn = (body) {
registeredSetUpCallbacks.add(body);
};
// Intercept testWidgets: record the test but don't execute it yet.
testWidgetsFn = (
String description,
Future<void> Function(WidgetTester) callback, {
bool? skip,
Timeout? timeout,
bool semanticsEnabled = true,
TestVariant<Object?> variant = const DefaultTestVariant(),
dynamic tags,
int? retry,
}) {
registeredTests.add((variant, callback));
};
when(
() => runner.run(
tester: any(named: 'tester'),
goldenPath: any(named: 'goldenPath'),
widget: any(named: 'widget'),
globalConfigTheme: any(named: 'globalConfigTheme'),
variantConfigTheme: any(named: 'variantConfigTheme'),
goldenTestTheme: any(named: 'goldenTestTheme'),
forceUpdate: any(named: 'forceUpdate'),
obscureText: any(named: 'obscureText'),
renderShadows: any(named: 'renderShadows'),
textScaleFactor: any(named: 'textScaleFactor'),
constraints: any(named: 'constraints'),
pumpBeforeTest: any(named: 'pumpBeforeTest'),
pumpWidget: any(named: 'pumpWidget'),
whilePerforming: any(named: 'whilePerforming'),
),
).thenAnswer((_) async {});
});
tearDown(() {
goldenTestAdapter = defaultGoldenTestAdapter;
goldenTestRunner = defaultGoldenTestRunner;
hostPlatform = defaultHostPlatform;
setUpFn = defaultSetUpFn;
testWidgetsFn = defaultTestWidgetsFn;
});
test(
'setUp is registered once and executions scale O(N) not O(N²)',
() async {
const n = 10;
for (var i = 0; i < n; i++) {
await goldenTest(
'test $i',
fileName: 'test_$i',
builder: () => const SizedBox(),
);
}
// FIXED: only one setUp callback should be registered regardless
// of how many goldenTest() calls are made.
expect(
registeredSetUpCallbacks,
hasLength(1),
reason: 'goldenTest should register setUp at most once',
);
// --- Simulate what flutter_test does at runtime ---
//
// flutter_test runs every registered setUp callback before each
// test invocation. With TestVariant producing V values per test,
// each test runs V times.
//
// Total setUp body executions =
// (# tests) × (# variant values per test) × (# setUp callbacks)
var totalSetUpExecutions = 0;
for (final (variant, _) in registeredTests) {
final variantCount = variant.values.length;
for (var v = 0; v < variantCount; v++) {
totalSetUpExecutions += registeredSetUpCallbacks.length;
}
}
// With default AlchemistConfig both platform and CI are enabled,
// so each test has 2 variant values.
//
// Registered setUps : 1
// Registered tests : N
// Variants per test : 2
// Total setUp calls : N × 1 × 2 = 2N
expect(registeredTests, hasLength(n));
expect(
totalSetUpExecutions,
2 * n, // 20 — linear, not quadratic
reason:
'setUp should execute O(N) times '
'($totalSetUpExecutions instead of expected ${2 * n})',
);
},
);
});
}