@@ -28,6 +28,7 @@ void main() {
28
28
expect (invoked, isTrue);
29
29
});
30
30
});
31
+
31
32
group (Actions , () {
32
33
Intent ? invokedIntent;
33
34
Action <Intent >? invokedAction;
@@ -99,6 +100,7 @@ void main() {
99
100
expect (result, isTrue);
100
101
expect (invoked, isTrue);
101
102
});
103
+
102
104
testWidgets ('maybeInvoke returns null when no action is found' , (WidgetTester tester) async {
103
105
final GlobalKey containerKey = GlobalKey ();
104
106
bool invoked = false ;
@@ -125,6 +127,7 @@ void main() {
125
127
expect (result, isNull);
126
128
expect (invoked, isFalse);
127
129
});
130
+
128
131
testWidgets ('invoke throws when no action is found' , (WidgetTester tester) async {
129
132
final GlobalKey containerKey = GlobalKey ();
130
133
bool invoked = false ;
@@ -151,6 +154,7 @@ void main() {
151
154
expect (result, isNull);
152
155
expect (invoked, isFalse);
153
156
});
157
+
154
158
testWidgets ('Actions widget can invoke actions with custom dispatcher' , (WidgetTester tester) async {
155
159
final GlobalKey containerKey = GlobalKey ();
156
160
bool invoked = false ;
@@ -181,6 +185,7 @@ void main() {
181
185
expect (invoked, isTrue);
182
186
expect (invokedIntent, equals (intent));
183
187
});
188
+
184
189
testWidgets ('Actions can invoke actions in ancestor dispatcher' , (WidgetTester tester) async {
185
190
final GlobalKey containerKey = GlobalKey ();
186
191
bool invoked = false ;
@@ -217,6 +222,7 @@ void main() {
217
222
expect (invokedAction, equals (testAction));
218
223
expect (invokedDispatcher.runtimeType, equals (TestDispatcher1 ));
219
224
});
225
+
220
226
testWidgets ("Actions can invoke actions in ancestor dispatcher if a lower one isn't specified" , (WidgetTester tester) async {
221
227
final GlobalKey containerKey = GlobalKey ();
222
228
bool invoked = false ;
@@ -252,6 +258,7 @@ void main() {
252
258
expect (invokedAction, equals (testAction));
253
259
expect (invokedDispatcher.runtimeType, equals (TestDispatcher1 ));
254
260
});
261
+
255
262
testWidgets ('Actions widget can be found with of' , (WidgetTester tester) async {
256
263
final GlobalKey containerKey = GlobalKey ();
257
264
final ActionDispatcher testDispatcher = TestDispatcher1 (postInvoke: collect);
@@ -268,6 +275,7 @@ void main() {
268
275
final ActionDispatcher dispatcher = Actions .of (containerKey.currentContext! );
269
276
expect (dispatcher, equals (testDispatcher));
270
277
});
278
+
271
279
testWidgets ('Action can be found with find' , (WidgetTester tester) async {
272
280
final GlobalKey containerKey = GlobalKey ();
273
281
final ActionDispatcher testDispatcher = TestDispatcher1 (postInvoke: collect);
@@ -314,6 +322,7 @@ void main() {
314
322
expect (() => Actions .find <DoNothingIntent >(containerKey.currentContext! ), throwsAssertionError);
315
323
expect (Actions .maybeFind <DoNothingIntent >(containerKey.currentContext! ), isNull);
316
324
});
325
+
317
326
testWidgets ('FocusableActionDetector keeps track of focus and hover even when disabled.' , (WidgetTester tester) async {
318
327
FocusManager .instance.highlightStrategy = FocusHighlightStrategy .alwaysTraditional;
319
328
final GlobalKey containerKey = GlobalKey ();
@@ -383,6 +392,7 @@ void main() {
383
392
expect (hovering, isFalse);
384
393
expect (focusing, isFalse);
385
394
});
395
+
386
396
testWidgets ('FocusableActionDetector changes mouse cursor when hovered' , (WidgetTester tester) async {
387
397
await tester.pumpWidget (
388
398
MouseRegion (
@@ -415,6 +425,7 @@ void main() {
415
425
416
426
expect (RendererBinding .instance.mouseTracker.debugDeviceActiveCursor (1 ), SystemMouseCursors .forbidden);
417
427
});
428
+
418
429
testWidgets ('Actions.invoke returns the value of Action.invoke' , (WidgetTester tester) async {
419
430
final GlobalKey containerKey = GlobalKey ();
420
431
final Object sentinel = Object ();
@@ -445,6 +456,7 @@ void main() {
445
456
expect (identical (result, sentinel), isTrue);
446
457
expect (invoked, isTrue);
447
458
});
459
+
448
460
testWidgets ('ContextAction can return null' , (WidgetTester tester) async {
449
461
final GlobalKey containerKey = GlobalKey ();
450
462
const TestIntent intent = TestIntent ();
@@ -471,6 +483,7 @@ void main() {
471
483
expect (invokedDispatcher.runtimeType, equals (TestDispatcher1 ));
472
484
expect (testAction.capturedContexts.single, containerKey.currentContext);
473
485
});
486
+
474
487
testWidgets ('Disabled actions stop propagation to an ancestor' , (WidgetTester tester) async {
475
488
final GlobalKey containerKey = GlobalKey ();
476
489
bool invoked = false ;
@@ -775,6 +788,7 @@ void main() {
775
788
expect (hovering, isFalse);
776
789
expect (focusing, isFalse);
777
790
});
791
+
778
792
testWidgets ('FocusableActionDetector shows focus highlight appropriately when focused and disabled' , (WidgetTester tester) async {
779
793
FocusManager .instance.highlightStrategy = FocusHighlightStrategy .alwaysTraditional;
780
794
final GlobalKey containerKey = GlobalKey ();
@@ -805,6 +819,7 @@ void main() {
805
819
await tester.pump ();
806
820
expect (focusing, isTrue);
807
821
});
822
+
808
823
testWidgets ('FocusableActionDetector can be used without callbacks' , (WidgetTester tester) async {
809
824
FocusManager .instance.highlightStrategy = FocusHighlightStrategy .alwaysTraditional;
810
825
final GlobalKey containerKey = GlobalKey ();
@@ -951,6 +966,110 @@ void main() {
951
966
expect (buttonNode2.hasFocus, isFalse);
952
967
},
953
968
);
969
+
970
+ testWidgets ('FocusableActionDetector can exclude Focus semantics' , (WidgetTester tester) async {
971
+ await tester.pumpWidget (
972
+ MaterialApp (
973
+ home: FocusableActionDetector (
974
+ child: Column (
975
+ children: < Widget > [
976
+ TextButton (
977
+ onPressed: () {},
978
+ child: const Text ('Button 1' ),
979
+ ),
980
+ TextButton (
981
+ onPressed: () {},
982
+ child: const Text ('Button 2' ),
983
+ ),
984
+ ],
985
+ ),
986
+ ),
987
+ ),
988
+ );
989
+
990
+ expect (
991
+ tester.getSemantics (find.byType (FocusableActionDetector )),
992
+ matchesSemantics (
993
+ scopesRoute: true ,
994
+ children: < Matcher > [
995
+ // This semantic is from `Focus` widget under `FocusableActionDetector`.
996
+ matchesSemantics (
997
+ isFocusable: true ,
998
+ children: < Matcher > [
999
+ matchesSemantics (
1000
+ hasTapAction: true ,
1001
+ isButton: true ,
1002
+ hasEnabledState: true ,
1003
+ isEnabled: true ,
1004
+ isFocusable: true ,
1005
+ label: 'Button 1' ,
1006
+ textDirection: TextDirection .ltr,
1007
+ ),
1008
+ matchesSemantics (
1009
+ hasTapAction: true ,
1010
+ isButton: true ,
1011
+ hasEnabledState: true ,
1012
+ isEnabled: true ,
1013
+ isFocusable: true ,
1014
+ label: 'Button 2' ,
1015
+ textDirection: TextDirection .ltr,
1016
+ ),
1017
+ ],
1018
+ ),
1019
+ ],
1020
+ ),
1021
+ );
1022
+
1023
+ // Set `includeFocusSemantics` to false to exclude semantics
1024
+ // from `Focus` widget under `FocusableActionDetector`.
1025
+ await tester.pumpWidget (
1026
+ MaterialApp (
1027
+ home: FocusableActionDetector (
1028
+ includeFocusSemantics: false ,
1029
+ child: Column (
1030
+ children: < Widget > [
1031
+ TextButton (
1032
+ onPressed: () {},
1033
+ child: const Text ('Button 1' ),
1034
+ ),
1035
+ TextButton (
1036
+ onPressed: () {},
1037
+ child: const Text ('Button 2' ),
1038
+ ),
1039
+ ],
1040
+ ),
1041
+ ),
1042
+ ),
1043
+ );
1044
+
1045
+ // Semantics from the `Focus` widget will be removed.
1046
+ expect (
1047
+ tester.getSemantics (find.byType (FocusableActionDetector )),
1048
+ matchesSemantics (
1049
+ scopesRoute: true ,
1050
+ children: < Matcher > [
1051
+ matchesSemantics (
1052
+ hasTapAction: true ,
1053
+ isButton: true ,
1054
+ hasEnabledState: true ,
1055
+ isEnabled: true ,
1056
+ isFocusable: true ,
1057
+ label: 'Button 1' ,
1058
+ textDirection: TextDirection .ltr,
1059
+ ),
1060
+ matchesSemantics (
1061
+ hasTapAction: true ,
1062
+ isButton: true ,
1063
+ hasEnabledState: true ,
1064
+ isEnabled: true ,
1065
+ isFocusable: true ,
1066
+ label: 'Button 2' ,
1067
+ textDirection: TextDirection .ltr,
1068
+ ),
1069
+ ],
1070
+ ),
1071
+ );
1072
+ });
954
1073
});
955
1074
956
1075
group ('Action subclasses' , () {
0 commit comments