1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | import 'package:flutter/foundation.dart'; |
6 | import 'package:flutter/gestures.dart'; |
7 | import 'package:flutter/material.dart'; |
8 | import 'package:flutter/services.dart'; |
9 | import 'package:flutter_test/flutter_test.dart'; |
10 | |
11 | void main() { |
12 | RenderObject getOverlayColor(WidgetTester tester) { |
13 | return tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures' ); |
14 | } |
15 | |
16 | test('SegmentedButtonThemeData copyWith, ==, hashCode basics' , () { |
17 | expect(const SegmentedButtonThemeData(), const SegmentedButtonThemeData().copyWith()); |
18 | expect(const SegmentedButtonThemeData().hashCode, const SegmentedButtonThemeData().copyWith().hashCode); |
19 | |
20 | const SegmentedButtonThemeData custom = SegmentedButtonThemeData( |
21 | style: ButtonStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.green)), |
22 | selectedIcon: Icon(Icons.error), |
23 | ); |
24 | final SegmentedButtonThemeData copy = const SegmentedButtonThemeData().copyWith( |
25 | style: custom.style, |
26 | selectedIcon: custom.selectedIcon, |
27 | ); |
28 | expect(copy, custom); |
29 | }); |
30 | |
31 | test('SegmentedButtonThemeData lerp special cases' , () { |
32 | expect(SegmentedButtonThemeData.lerp(null, null, 0), const SegmentedButtonThemeData()); |
33 | const SegmentedButtonThemeData theme = SegmentedButtonThemeData(); |
34 | expect(identical(SegmentedButtonThemeData.lerp(theme, theme, 0.5), theme), true); |
35 | }); |
36 | |
37 | testWidgets('Default SegmentedButtonThemeData debugFillProperties' , (WidgetTester tester) async { |
38 | final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
39 | const SegmentedButtonThemeData().debugFillProperties(builder); |
40 | |
41 | final List<String> description = builder.properties |
42 | .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)) |
43 | .map((DiagnosticsNode node) => node.toString()) |
44 | .toList(); |
45 | |
46 | expect(description, <String>[]); |
47 | }); |
48 | |
49 | testWidgets('With no other configuration, defaults are used' , (WidgetTester tester) async { |
50 | final ThemeData theme = ThemeData(useMaterial3: true); |
51 | await tester.pumpWidget( |
52 | MaterialApp( |
53 | theme: theme, |
54 | home: Scaffold( |
55 | body: Center( |
56 | child: SegmentedButton<int>( |
57 | segments: const <ButtonSegment<int>>[ |
58 | ButtonSegment<int>(value: 1, label: Text('1' )), |
59 | ButtonSegment<int>(value: 2, label: Text('2' )), |
60 | ButtonSegment<int>(value: 3, label: Text('3' ), enabled: false), |
61 | ], |
62 | selected: const <int>{2}, |
63 | onSelectionChanged: (Set<int> selected) { }, |
64 | ), |
65 | ), |
66 | ), |
67 | ), |
68 | ); |
69 | |
70 | // Test first segment, should be enabled |
71 | { |
72 | final Finder text = find.text('1' ); |
73 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
74 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check)); |
75 | final Material material = tester.widget<Material>(parent); |
76 | expect(material.color, Colors.transparent); |
77 | expect(material.shape, const RoundedRectangleBorder()); |
78 | expect(material.textStyle!.color, theme.colorScheme.onSurface); |
79 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
80 | expect(material.textStyle!.fontSize, 14); |
81 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
82 | expect(selectedIcon, findsNothing); |
83 | } |
84 | |
85 | // Test second segment, should be enabled and selected |
86 | { |
87 | final Finder text = find.text('2' ); |
88 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
89 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check)); |
90 | final Material material = tester.widget<Material>(parent); |
91 | expect(material.color, theme.colorScheme.secondaryContainer); |
92 | expect(material.shape, const RoundedRectangleBorder()); |
93 | expect(material.textStyle!.color, theme.colorScheme.onSecondaryContainer); |
94 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
95 | expect(material.textStyle!.fontSize, 14); |
96 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
97 | expect(selectedIcon, findsOneWidget); |
98 | } |
99 | |
100 | // Test last segment, should be disabled |
101 | { |
102 | final Finder text = find.text('3' ); |
103 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
104 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.check)); |
105 | final Material material = tester.widget<Material>(parent); |
106 | expect(material.color, Colors.transparent); |
107 | expect(material.shape, const RoundedRectangleBorder()); |
108 | expect(material.textStyle!.color, theme.colorScheme.onSurface.withOpacity(0.38)); |
109 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
110 | expect(material.textStyle!.fontSize, 14); |
111 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
112 | expect(selectedIcon, findsNothing); |
113 | } |
114 | }); |
115 | |
116 | testWidgets('ThemeData.segmentedButtonTheme overrides defaults' , (WidgetTester tester) async { |
117 | final ThemeData theme = ThemeData( |
118 | useMaterial3: true, |
119 | segmentedButtonTheme: SegmentedButtonThemeData( |
120 | style: ButtonStyle( |
121 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
122 | if (states.contains(MaterialState.disabled)) { |
123 | return Colors.blue; |
124 | } |
125 | if (states.contains(MaterialState.selected)) { |
126 | return Colors.purple; |
127 | } |
128 | return null; |
129 | }), |
130 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
131 | if (states.contains(MaterialState.disabled)) { |
132 | return Colors.yellow; |
133 | } |
134 | if (states.contains(MaterialState.selected)) { |
135 | return Colors.brown; |
136 | } else { |
137 | return Colors.cyan; |
138 | } |
139 | }), |
140 | ), |
141 | selectedIcon: const Icon(Icons.error), |
142 | ), |
143 | ); |
144 | await tester.pumpWidget( |
145 | MaterialApp( |
146 | theme: theme, |
147 | home: Scaffold( |
148 | body: Center( |
149 | child: SegmentedButton<int>( |
150 | segments: const <ButtonSegment<int>>[ |
151 | ButtonSegment<int>(value: 1, label: Text('1' )), |
152 | ButtonSegment<int>(value: 2, label: Text('2' )), |
153 | ButtonSegment<int>(value: 3, label: Text('3' ), enabled: false), |
154 | ], |
155 | selected: const <int>{2}, |
156 | onSelectionChanged: (Set<int> selected) { }, |
157 | ), |
158 | ), |
159 | ), |
160 | ), |
161 | ); |
162 | |
163 | // Test first segment, should be enabled |
164 | { |
165 | final Finder text = find.text('1' ); |
166 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
167 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error)); |
168 | final Material material = tester.widget<Material>(parent); |
169 | expect(material.color, Colors.transparent); |
170 | expect(material.shape, const RoundedRectangleBorder()); |
171 | expect(material.textStyle!.color, Colors.cyan); |
172 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
173 | expect(material.textStyle!.fontSize, 14); |
174 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
175 | expect(selectedIcon, findsNothing); |
176 | } |
177 | |
178 | // Test second segment, should be enabled and selected |
179 | { |
180 | final Finder text = find.text('2' ); |
181 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
182 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error)); |
183 | final Material material = tester.widget<Material>(parent); |
184 | expect(material.color, Colors.purple); |
185 | expect(material.shape, const RoundedRectangleBorder()); |
186 | expect(material.textStyle!.color, Colors.brown); |
187 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
188 | expect(material.textStyle!.fontSize, 14); |
189 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
190 | expect(selectedIcon, findsOneWidget); |
191 | } |
192 | |
193 | // Test last segment, should be disabled |
194 | { |
195 | final Finder text = find.text('3' ); |
196 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
197 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.error)); |
198 | final Material material = tester.widget<Material>(parent); |
199 | expect(material.color, Colors.blue); |
200 | expect(material.shape, const RoundedRectangleBorder()); |
201 | expect(material.textStyle!.color, Colors.yellow); |
202 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
203 | expect(material.textStyle!.fontSize, 14); |
204 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
205 | expect(selectedIcon, findsNothing); |
206 | } |
207 | }); |
208 | |
209 | testWidgets('SegmentedButtonTheme overrides ThemeData and defaults' , (WidgetTester tester) async { |
210 | final SegmentedButtonThemeData global = SegmentedButtonThemeData( |
211 | style: ButtonStyle( |
212 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
213 | if (states.contains(MaterialState.disabled)) { |
214 | return Colors.blue; |
215 | } |
216 | if (states.contains(MaterialState.selected)) { |
217 | return Colors.purple; |
218 | } |
219 | return null; |
220 | }), |
221 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
222 | if (states.contains(MaterialState.disabled)) { |
223 | return Colors.yellow; |
224 | } |
225 | if (states.contains(MaterialState.selected)) { |
226 | return Colors.brown; |
227 | } else { |
228 | return Colors.cyan; |
229 | } |
230 | }), |
231 | ), |
232 | selectedIcon: const Icon(Icons.error), |
233 | ); |
234 | final SegmentedButtonThemeData segmentedTheme = SegmentedButtonThemeData( |
235 | style: ButtonStyle( |
236 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
237 | if (states.contains(MaterialState.disabled)) { |
238 | return Colors.lightBlue; |
239 | } |
240 | if (states.contains(MaterialState.selected)) { |
241 | return Colors.lightGreen; |
242 | } |
243 | return null; |
244 | }), |
245 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
246 | if (states.contains(MaterialState.disabled)) { |
247 | return Colors.lime; |
248 | } |
249 | if (states.contains(MaterialState.selected)) { |
250 | return Colors.amber; |
251 | } else { |
252 | return Colors.deepPurple; |
253 | } |
254 | }), |
255 | ), |
256 | selectedIcon: const Icon(Icons.plus_one), |
257 | ); |
258 | final ThemeData theme = ThemeData( |
259 | useMaterial3: true, |
260 | segmentedButtonTheme: global, |
261 | ); |
262 | await tester.pumpWidget( |
263 | MaterialApp( |
264 | theme: theme, |
265 | home: SegmentedButtonTheme( |
266 | data: segmentedTheme, |
267 | child: Scaffold( |
268 | body: Center( |
269 | child: SegmentedButton<int>( |
270 | segments: const <ButtonSegment<int>>[ |
271 | ButtonSegment<int>(value: 1, label: Text('1' )), |
272 | ButtonSegment<int>(value: 2, label: Text('2' )), |
273 | ButtonSegment<int>(value: 3, label: Text('3' ), enabled: false), |
274 | ], |
275 | selected: const <int>{2}, |
276 | onSelectionChanged: (Set<int> selected) { }, |
277 | ), |
278 | ), |
279 | ), |
280 | ), |
281 | ), |
282 | ); |
283 | |
284 | // Test first segment, should be enabled |
285 | { |
286 | final Finder text = find.text('1' ); |
287 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
288 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one)); |
289 | final Material material = tester.widget<Material>(parent); |
290 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
291 | expect(material.borderRadius, null); |
292 | expect(material.color, Colors.transparent); |
293 | expect(material.shape, const RoundedRectangleBorder()); |
294 | expect(material.textStyle!.color, Colors.deepPurple); |
295 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
296 | expect(material.textStyle!.fontSize, 14); |
297 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
298 | expect(selectedIcon, findsNothing); |
299 | } |
300 | |
301 | // Test second segment, should be enabled and selected |
302 | { |
303 | final Finder text = find.text('2' ); |
304 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
305 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one)); |
306 | final Material material = tester.widget<Material>(parent); |
307 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
308 | expect(material.borderRadius, null); |
309 | expect(material.color, Colors.lightGreen); |
310 | expect(material.shape, const RoundedRectangleBorder()); |
311 | expect(material.textStyle!.color, Colors.amber); |
312 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
313 | expect(material.textStyle!.fontSize, 14); |
314 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
315 | expect(selectedIcon, findsOneWidget); |
316 | } |
317 | |
318 | // Test last segment, should be disabled |
319 | { |
320 | final Finder text = find.text('3' ); |
321 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
322 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.plus_one)); |
323 | final Material material = tester.widget<Material>(parent); |
324 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
325 | expect(material.borderRadius, null); |
326 | expect(material.color, Colors.lightBlue); |
327 | expect(material.shape, const RoundedRectangleBorder()); |
328 | expect(material.textStyle!.color, Colors.lime); |
329 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
330 | expect(material.textStyle!.fontSize, 14); |
331 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
332 | expect(selectedIcon, findsNothing); |
333 | } |
334 | }); |
335 | |
336 | testWidgets('Widget parameters overrides SegmentedTheme, ThemeData and defaults' , (WidgetTester tester) async { |
337 | final SegmentedButtonThemeData global = SegmentedButtonThemeData( |
338 | style: ButtonStyle( |
339 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
340 | if (states.contains(MaterialState.disabled)) { |
341 | return Colors.blue; |
342 | } |
343 | if (states.contains(MaterialState.selected)) { |
344 | return Colors.purple; |
345 | } |
346 | return null; |
347 | }), |
348 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
349 | if (states.contains(MaterialState.disabled)) { |
350 | return Colors.yellow; |
351 | } |
352 | if (states.contains(MaterialState.selected)) { |
353 | return Colors.brown; |
354 | } else { |
355 | return Colors.cyan; |
356 | } |
357 | }), |
358 | ), |
359 | selectedIcon: const Icon(Icons.error), |
360 | ); |
361 | final SegmentedButtonThemeData segmentedTheme = SegmentedButtonThemeData( |
362 | style: ButtonStyle( |
363 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
364 | if (states.contains(MaterialState.disabled)) { |
365 | return Colors.lightBlue; |
366 | } |
367 | if (states.contains(MaterialState.selected)) { |
368 | return Colors.lightGreen; |
369 | } |
370 | return null; |
371 | }), |
372 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
373 | if (states.contains(MaterialState.disabled)) { |
374 | return Colors.lime; |
375 | } |
376 | if (states.contains(MaterialState.selected)) { |
377 | return Colors.amber; |
378 | } else { |
379 | return Colors.deepPurple; |
380 | } |
381 | }), |
382 | ), |
383 | selectedIcon: const Icon(Icons.plus_one), |
384 | ); |
385 | final ThemeData theme = ThemeData( |
386 | useMaterial3: true, |
387 | segmentedButtonTheme: global, |
388 | ); |
389 | await tester.pumpWidget( |
390 | MaterialApp( |
391 | theme: theme, |
392 | home: SegmentedButtonTheme( |
393 | data: segmentedTheme, |
394 | child: Scaffold( |
395 | body: Center( |
396 | child: SegmentedButton<int>( |
397 | segments: const <ButtonSegment<int>>[ |
398 | ButtonSegment<int>(value: 1, label: Text('1' )), |
399 | ButtonSegment<int>(value: 2, label: Text('2' )), |
400 | ButtonSegment<int>(value: 3, label: Text('3' ), enabled: false), |
401 | ], |
402 | selected: const <int>{2}, |
403 | onSelectionChanged: (Set<int> selected) { }, |
404 | style: ButtonStyle( |
405 | backgroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
406 | if (states.contains(MaterialState.disabled)) { |
407 | return Colors.black12; |
408 | } |
409 | if (states.contains(MaterialState.selected)) { |
410 | return Colors.grey; |
411 | } |
412 | return null; |
413 | }), |
414 | foregroundColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) { |
415 | if (states.contains(MaterialState.disabled)) { |
416 | return Colors.amberAccent; |
417 | } |
418 | if (states.contains(MaterialState.selected)) { |
419 | return Colors.deepOrange; |
420 | } else { |
421 | return Colors.deepPurpleAccent; |
422 | } |
423 | }), |
424 | ), |
425 | selectedIcon: const Icon(Icons.alarm), |
426 | ), |
427 | ), |
428 | ), |
429 | ), |
430 | ), |
431 | ); |
432 | |
433 | // Test first segment, should be enabled |
434 | { |
435 | final Finder text = find.text('1' ); |
436 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
437 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm)); |
438 | final Material material = tester.widget<Material>(parent); |
439 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
440 | expect(material.borderRadius, null); |
441 | expect(material.color, Colors.transparent); |
442 | expect(material.shape, const RoundedRectangleBorder()); |
443 | expect(material.textStyle!.color, Colors.deepPurpleAccent); |
444 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
445 | expect(material.textStyle!.fontSize, 14); |
446 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
447 | expect(selectedIcon, findsNothing); |
448 | } |
449 | |
450 | // Test second segment, should be enabled and selected |
451 | { |
452 | final Finder text = find.text('2' ); |
453 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
454 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm)); |
455 | final Material material = tester.widget<Material>(parent); |
456 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
457 | expect(material.borderRadius, null); |
458 | expect(material.color, Colors.grey); |
459 | expect(material.shape, const RoundedRectangleBorder()); |
460 | expect(material.textStyle!.color, Colors.deepOrange); |
461 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
462 | expect(material.textStyle!.fontSize, 14); |
463 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
464 | expect(selectedIcon, findsOneWidget); |
465 | } |
466 | |
467 | // Test last segment, should be disabled |
468 | { |
469 | final Finder text = find.text('3' ); |
470 | final Finder parent = find.ancestor(of: text, matching: find.byType(Material)).first; |
471 | final Finder selectedIcon = find.descendant(of: parent, matching: find.byIcon(Icons.alarm)); |
472 | final Material material = tester.widget<Material>(parent); |
473 | expect(material.animationDuration, const Duration(milliseconds: 200)); |
474 | expect(material.borderRadius, null); |
475 | expect(material.color, Colors.black12); |
476 | expect(material.shape, const RoundedRectangleBorder()); |
477 | expect(material.textStyle!.color, Colors.amberAccent); |
478 | expect(material.textStyle!.fontFamily, 'Roboto' ); |
479 | expect(material.textStyle!.fontSize, 14); |
480 | expect(material.textStyle!.fontWeight, FontWeight.w500); |
481 | expect(selectedIcon, findsNothing); |
482 | } |
483 | }); |
484 | |
485 | testWidgets('SegmentedButtonTheme SegmentedButton.styleFrom overlayColor overrides default overlay color' , (WidgetTester tester) async { |
486 | const Color overlayColor = Color(0xffff0000); |
487 | await tester.pumpWidget( |
488 | MaterialApp( |
489 | theme: ThemeData( |
490 | segmentedButtonTheme: SegmentedButtonThemeData( |
491 | style: SegmentedButton.styleFrom(overlayColor: overlayColor), |
492 | ), |
493 | ), |
494 | home: Scaffold( |
495 | body: Center( |
496 | child: SegmentedButton<int>( |
497 | segments: const <ButtonSegment<int>>[ |
498 | ButtonSegment<int>( |
499 | value: 0, |
500 | label: Text('Option 1' ), |
501 | ), |
502 | ButtonSegment<int>( |
503 | value: 1, |
504 | label: Text('Option 2' ), |
505 | ), |
506 | ], |
507 | onSelectionChanged: (Set<int> selected) {}, |
508 | selected: const <int>{1}, |
509 | ), |
510 | ), |
511 | ), |
512 | ), |
513 | ); |
514 | |
515 | // Hovered selected segment, |
516 | Offset center = tester.getCenter(find.text('Option 1' )); |
517 | final TestGesture gesture = await tester.createGesture( |
518 | kind: PointerDeviceKind.mouse, |
519 | ); |
520 | await gesture.addPointer(); |
521 | await gesture.moveTo(center); |
522 | await tester.pumpAndSettle(); |
523 | expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08))); |
524 | |
525 | // Hovered unselected segment, |
526 | center = tester.getCenter(find.text('Option 2' )); |
527 | await gesture.moveTo(center); |
528 | await tester.pumpAndSettle(); |
529 | expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.08))); |
530 | |
531 | // Highlighted unselected segment (pressed). |
532 | center = tester.getCenter(find.text('Option 1' )); |
533 | await gesture.down(center); |
534 | await tester.pumpAndSettle(); |
535 | expect( |
536 | getOverlayColor(tester), |
537 | paints |
538 | ..rect(color: overlayColor.withOpacity(0.08)) |
539 | ..rect(color: overlayColor.withOpacity(0.1)), |
540 | ); |
541 | // Remove pressed and hovered states, |
542 | await gesture.up(); |
543 | await tester.pumpAndSettle(); |
544 | await gesture.moveTo(const Offset(0, 50)); |
545 | await tester.pumpAndSettle(); |
546 | |
547 | // Highlighted selected segment (pressed) |
548 | center = tester.getCenter(find.text('Option 2' )); |
549 | await gesture.down(center); |
550 | await tester.pumpAndSettle(); |
551 | expect( |
552 | getOverlayColor(tester), |
553 | paints |
554 | ..rect(color: overlayColor.withOpacity(0.08)) |
555 | ..rect(color: overlayColor.withOpacity(0.1)), |
556 | ); |
557 | // Remove pressed and hovered states, |
558 | await gesture.up(); |
559 | await tester.pumpAndSettle(); |
560 | await gesture.moveTo(const Offset(0, 50)); |
561 | await tester.pumpAndSettle(); |
562 | |
563 | // Focused unselected segment. |
564 | await tester.sendKeyEvent(LogicalKeyboardKey.tab); |
565 | await tester.pumpAndSettle(); |
566 | expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1))); |
567 | |
568 | // Focused selected segment. |
569 | await tester.sendKeyEvent(LogicalKeyboardKey.tab); |
570 | await tester.pumpAndSettle(); |
571 | expect(getOverlayColor(tester), paints..rect(color: overlayColor.withOpacity(0.1))); |
572 | }); |
573 | } |
574 | |