@@ -30,6 +30,120 @@ void main() {
3030 Future <void > sendUndo (WidgetTester tester) => sendUndoRedo (tester);
3131 Future <void > sendRedo (WidgetTester tester) => sendUndoRedo (tester, true );
3232
33+ testWidgets ('UndoHistory widget registers as global undo/redo client' , (WidgetTester tester) async {
34+ final FocusNode focusNode = FocusNode (debugLabel: 'UndoHistory Node' );
35+ final GlobalKey undoHistoryGlobalKey = GlobalKey ();
36+ final ValueNotifier <int > value = ValueNotifier <int >(0 );
37+ addTearDown (value.dispose);
38+
39+ await tester.pumpWidget (
40+ MaterialApp (
41+ home: UndoHistory <int >(
42+ key: undoHistoryGlobalKey,
43+ value: value,
44+ onTriggered: (_) {},
45+ focusNode: focusNode,
46+ child: Focus (
47+ focusNode: focusNode,
48+ child: Container (),
49+ ),
50+ ),
51+ ),
52+ );
53+
54+ // Initially the UndoHistory doesn't have focus, therefore it should
55+ // not be the global undo/redo client. Ensure that's the case.
56+ expect (UndoManager .client, isNull);
57+
58+ // Give focus to the UndoHistory widget.
59+ focusNode.requestFocus ();
60+ await tester.pump ();
61+
62+ // Now that the UndoHistory widget has focus, it should have registered
63+ // itself as the global undo/redo client.
64+ final State ? undoHistoryState = undoHistoryGlobalKey.currentState;
65+ expect (UndoManager .client, undoHistoryState);
66+ });
67+
68+ testWidgets ('UndoHistory widget deregisters as global undo/redo client when it loses focus' ,
69+ (WidgetTester tester) async {
70+ final FocusNode focusNode = FocusNode (debugLabel: 'UndoHistory Node' );
71+ final GlobalKey undoHistoryGlobalKey = GlobalKey ();
72+ final ValueNotifier <int > value = ValueNotifier <int >(0 );
73+ addTearDown (value.dispose);
74+
75+ await tester.pumpWidget (
76+ MaterialApp (
77+ home: UndoHistory <int >(
78+ key: undoHistoryGlobalKey,
79+ value: value,
80+ onTriggered: (_) {},
81+ focusNode: focusNode,
82+ child: Focus (
83+ focusNode: focusNode,
84+ child: Container (),
85+ ),
86+ ),
87+ ),
88+ );
89+
90+ // Give focus to the UndoHistory widget.
91+ focusNode.requestFocus ();
92+ await tester.pump ();
93+
94+ // Ensure that UndoHistory is the global undo/redo client.
95+ final State ? undoHistoryState = undoHistoryGlobalKey.currentState;
96+ expect (UndoManager .client, undoHistoryState);
97+
98+ // Remove focus from UndoHistory widget.
99+ focusNode.unfocus ();
100+ await tester.pump ();
101+
102+ // Ensure the UndoHistory widget is no longer the global client
103+ expect (UndoManager .client, null );
104+ });
105+
106+ testWidgets ('UndoHistory widget deregisters as global undo/redo client when disposed' , (WidgetTester tester) async {
107+ final FocusNode focusNode = FocusNode (debugLabel: 'UndoHistory Node' );
108+ final GlobalKey undoHistoryGlobalKey = GlobalKey ();
109+ final ValueNotifier <int > value = ValueNotifier <int >(0 );
110+ addTearDown (value.dispose);
111+
112+ await tester.pumpWidget (
113+ MaterialApp (
114+ home: UndoHistory <int >(
115+ key: undoHistoryGlobalKey,
116+ value: value,
117+ onTriggered: (_) {},
118+ focusNode: focusNode,
119+ child: Focus (
120+ focusNode: focusNode,
121+ child: Container (),
122+ ),
123+ ),
124+ ),
125+ );
126+
127+ // Give focus to the UndoHistory widget.
128+ focusNode.requestFocus ();
129+ await tester.pump ();
130+
131+ // Ensure that UndoHistory is the global undo/redo client.
132+ final State ? undoHistoryState = undoHistoryGlobalKey.currentState;
133+ expect (UndoManager .client, undoHistoryState);
134+
135+ // Cause the UndoHistory widget to dispose its state.
136+ await tester.pumpWidget (
137+ const MaterialApp (
138+ home: SizedBox (),
139+ ),
140+ );
141+
142+ // Ensure that the disposed UndoHistory state is not still the global
143+ // undo/redo history client.
144+ expect (UndoManager .client, isNull);
145+ });
146+
33147 testWidgets ('allows undo and redo to be called programmatically from the UndoHistoryController' , (WidgetTester tester) async {
34148 final ValueNotifier <int > value = ValueNotifier <int >(0 );
35149 addTearDown (value.dispose);
0 commit comments