| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/gestures.dart'; |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/rendering.dart'; |
| import 'package:flutter/services.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| typedef PostInvokeCallback = void Function({Action<Intent> action, Intent intent, ActionDispatcher dispatcher}); |
| |
| class TestIntent extends Intent { |
| const TestIntent(); |
| } |
| |
| class SecondTestIntent extends TestIntent { |
| const SecondTestIntent(); |
| } |
| |
| class ThirdTestIntent extends SecondTestIntent { |
| const ThirdTestIntent(); |
| } |
| |
| class TestAction extends CallbackAction<TestIntent> { |
| TestAction({ |
| @required OnInvokeCallback onInvoke, |
| }) : assert(onInvoke != null), |
| super(onInvoke: onInvoke); |
| |
| @override |
| bool isEnabled(TestIntent intent) => enabled; |
| |
| bool get enabled => _enabled; |
| bool _enabled = true; |
| set enabled(bool value) { |
| if (_enabled == value) { |
| return; |
| } |
| _enabled = value; |
| notifyActionListeners(); |
| } |
| |
| @override |
| void addActionListener(ActionListenerCallback listener) { |
| super.addActionListener(listener); |
| listeners.add(listener); |
| } |
| |
| @override |
| void removeActionListener(ActionListenerCallback listener) { |
| super.removeActionListener(listener); |
| listeners.remove(listener); |
| } |
| List<ActionListenerCallback> listeners = <ActionListenerCallback>[]; |
| |
| void _testInvoke(TestIntent intent) => invoke(intent); |
| } |
| |
| class TestDispatcher extends ActionDispatcher { |
| const TestDispatcher({this.postInvoke}); |
| |
| final PostInvokeCallback postInvoke; |
| |
| @override |
| Object invokeAction(Action<Intent> action, Intent intent, [BuildContext context]) { |
| final Object result = super.invokeAction(action, intent, context); |
| postInvoke?.call(action: action, intent: intent, dispatcher: this); |
| return result; |
| } |
| } |
| |
| class TestDispatcher1 extends TestDispatcher { |
| const TestDispatcher1({PostInvokeCallback postInvoke}) : super(postInvoke: postInvoke); |
| } |
| |
| void main() { |
| testWidgets('CallbackAction passes correct intent when invoked.', (WidgetTester tester) async { |
| Intent passedIntent; |
| final TestAction action = TestAction(onInvoke: (Intent intent) { |
| passedIntent = intent; |
| return true; |
| }); |
| const TestIntent intent = TestIntent(); |
| action._testInvoke(intent); |
| expect(passedIntent, equals(intent)); |
| }); |
| group(ActionDispatcher, () { |
| testWidgets('ActionDispatcher invokes actions when asked.', (WidgetTester tester) async { |
| await tester.pumpWidget(Container()); |
| bool invoked = false; |
| const ActionDispatcher dispatcher = ActionDispatcher(); |
| final Object result = dispatcher.invokeAction( |
| TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ), |
| const TestIntent(), |
| ); |
| expect(result, isTrue); |
| expect(invoked, isTrue); |
| }); |
| }); |
| group(Actions, () { |
| Intent invokedIntent; |
| Action<Intent> invokedAction; |
| ActionDispatcher invokedDispatcher; |
| |
| void collect({Action<Intent> action, Intent intent, ActionDispatcher dispatcher}) { |
| invokedIntent = intent; |
| invokedAction = action; |
| invokedDispatcher = dispatcher; |
| } |
| |
| void clear() { |
| invokedIntent = null; |
| invokedAction = null; |
| invokedDispatcher = null; |
| } |
| |
| setUp(clear); |
| |
| testWidgets('Actions widget can invoke actions with default dispatcher', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked = false; |
| |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<Intent>>{ |
| TestIntent: TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ), |
| }, |
| child: Container(key: containerKey), |
| ), |
| ); |
| |
| await tester.pump(); |
| final Object result = Actions.invoke( |
| containerKey.currentContext, |
| const TestIntent(), |
| ); |
| expect(result, isTrue); |
| expect(invoked, isTrue); |
| }); |
| testWidgets('Actions widget can invoke actions with custom dispatcher', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked = false; |
| const TestIntent intent = TestIntent(); |
| final Action<Intent> testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: TestDispatcher(postInvoke: collect), |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ); |
| |
| await tester.pump(); |
| final Object result = Actions.invoke<TestIntent>( |
| containerKey.currentContext, |
| intent, |
| ); |
| expect(result, isTrue); |
| expect(invoked, isTrue); |
| expect(invokedIntent, equals(intent)); |
| }); |
| testWidgets('Actions can invoke actions in ancestor dispatcher', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked = false; |
| const TestIntent intent = TestIntent(); |
| final Action<Intent> testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: TestDispatcher1(postInvoke: collect), |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| child: Actions( |
| dispatcher: TestDispatcher(postInvoke: collect), |
| actions: const <Type, Action<Intent>>{}, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ); |
| |
| await tester.pump(); |
| final Object result = Actions.invoke<TestIntent>( |
| containerKey.currentContext, |
| intent, |
| ); |
| expect(result, isTrue); |
| expect(invoked, isTrue); |
| expect(invokedIntent, equals(intent)); |
| expect(invokedAction, equals(testAction)); |
| expect(invokedDispatcher.runtimeType, equals(TestDispatcher1)); |
| }); |
| testWidgets("Actions can invoke actions in ancestor dispatcher if a lower one isn't specified", (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked = false; |
| const TestIntent intent = TestIntent(); |
| final Action<Intent> testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: TestDispatcher1(postInvoke: collect), |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| child: Actions( |
| actions: const <Type, Action<Intent>>{}, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ); |
| |
| await tester.pump(); |
| final Object result = Actions.invoke<TestIntent>( |
| containerKey.currentContext, |
| intent, |
| ); |
| expect(result, isTrue); |
| expect(invoked, isTrue); |
| expect(invokedIntent, equals(intent)); |
| expect(invokedAction, equals(testAction)); |
| expect(invokedDispatcher.runtimeType, equals(TestDispatcher1)); |
| }); |
| testWidgets('Actions widget can be found with of', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| final ActionDispatcher testDispatcher = TestDispatcher1(postInvoke: collect); |
| |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: testDispatcher, |
| actions: const <Type, Action<Intent>>{}, |
| child: Container(key: containerKey), |
| ), |
| ); |
| |
| await tester.pump(); |
| final ActionDispatcher dispatcher = Actions.of( |
| containerKey.currentContext, |
| nullOk: true, |
| ); |
| expect(dispatcher, equals(testDispatcher)); |
| }); |
| testWidgets('Action can be found with find', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| final ActionDispatcher testDispatcher = TestDispatcher1(postInvoke: collect); |
| bool invoked = false; |
| final TestAction testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: testDispatcher, |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| child: Actions( |
| actions: const <Type, Action<Intent>>{}, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ); |
| |
| await tester.pump(); |
| expect(Actions.find<TestIntent>(containerKey.currentContext), equals(testAction)); |
| expect(() => Actions.find<DoNothingIntent>(containerKey.currentContext), throwsAssertionError); |
| expect(Actions.find<DoNothingIntent>(containerKey.currentContext, nullOk: true), isNull); |
| |
| await tester.pumpWidget( |
| Actions( |
| dispatcher: testDispatcher, |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| child: Container( |
| child: Actions( |
| actions: const <Type, Action<Intent>>{}, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.pump(); |
| expect(Actions.find<TestIntent>(containerKey.currentContext), equals(testAction)); |
| expect(() => Actions.find<DoNothingIntent>(containerKey.currentContext), throwsAssertionError); |
| expect(Actions.find<DoNothingIntent>(containerKey.currentContext, nullOk: true), isNull); |
| }); |
| testWidgets('FocusableActionDetector keeps track of focus and hover even when disabled.', (WidgetTester tester) async { |
| FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked = false; |
| const Intent intent = TestIntent(); |
| final FocusNode focusNode = FocusNode(debugLabel: 'Test Node'); |
| final Action<Intent> testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| bool hovering = false; |
| bool focusing = false; |
| |
| Future<void> buildTest(bool enabled) async { |
| await tester.pumpWidget( |
| Center( |
| child: Actions( |
| dispatcher: TestDispatcher1(postInvoke: collect), |
| actions: const <Type, Action<Intent>>{}, |
| child: FocusableActionDetector( |
| enabled: enabled, |
| focusNode: focusNode, |
| shortcuts: <LogicalKeySet, Intent>{ |
| LogicalKeySet(LogicalKeyboardKey.enter): intent, |
| }, |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| onShowHoverHighlight: (bool value) => hovering = value, |
| onShowFocusHighlight: (bool value) => focusing = value, |
| child: Container(width: 100, height: 100, key: containerKey), |
| ), |
| ), |
| ), |
| ); |
| return tester.pump(); |
| } |
| |
| await buildTest(true); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
| addTearDown(gesture.removePointer); |
| await gesture.moveTo(tester.getCenter(find.byKey(containerKey))); |
| await tester.pump(); |
| await tester.sendKeyEvent(LogicalKeyboardKey.enter); |
| expect(hovering, isTrue); |
| expect(focusing, isTrue); |
| expect(invoked, isTrue); |
| |
| invoked = false; |
| await buildTest(false); |
| expect(hovering, isFalse); |
| expect(focusing, isFalse); |
| await tester.sendKeyEvent(LogicalKeyboardKey.enter); |
| await tester.pump(); |
| expect(invoked, isFalse); |
| await buildTest(true); |
| expect(focusing, isFalse); |
| expect(hovering, isTrue); |
| await buildTest(false); |
| expect(focusing, isFalse); |
| expect(hovering, isFalse); |
| await gesture.moveTo(Offset.zero); |
| await buildTest(true); |
| expect(hovering, isFalse); |
| expect(focusing, isFalse); |
| }); |
| testWidgets('FocusableActionDetector changes mouse cursor when hovered', (WidgetTester tester) async { |
| await tester.pumpWidget( |
| MouseRegion( |
| cursor: SystemMouseCursors.forbidden, |
| child: FocusableActionDetector( |
| mouseCursor: SystemMouseCursors.text, |
| onShowHoverHighlight: (_) {}, |
| onShowFocusHighlight: (_) {}, |
| child: Container(), |
| ), |
| ), |
| ); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1); |
| await gesture.addPointer(location: const Offset(1, 1)); |
| addTearDown(gesture.removePointer); |
| await tester.pump(); |
| |
| expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text); |
| |
| // Test default |
| await tester.pumpWidget( |
| MouseRegion( |
| cursor: SystemMouseCursors.forbidden, |
| child: FocusableActionDetector( |
| onShowHoverHighlight: (_) {}, |
| onShowFocusHighlight: (_) {}, |
| child: Container(), |
| ), |
| ), |
| ); |
| |
| expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.forbidden); |
| }); |
| }); |
| |
| group('Listening', () { |
| testWidgets('can listen to enabled state of Actions', (WidgetTester tester) async { |
| final GlobalKey containerKey = GlobalKey(); |
| bool invoked1 = false; |
| bool invoked2 = false; |
| bool invoked3 = false; |
| final TestAction action1 = TestAction( |
| onInvoke: (Intent intent) { |
| invoked1 = true; |
| return invoked1; |
| }, |
| ); |
| final TestAction action2 = TestAction( |
| onInvoke: (Intent intent) { |
| invoked2 = true; |
| return invoked2; |
| }, |
| ); |
| final TestAction action3 = TestAction( |
| onInvoke: (Intent intent) { |
| invoked3 = true; |
| return invoked3; |
| }, |
| ); |
| bool enabled1 = true; |
| action1.addActionListener((Action<Intent> action) => enabled1 = action.isEnabled(const TestIntent())); |
| action1.enabled = false; |
| expect(enabled1, isFalse); |
| |
| bool enabled2 = true; |
| action2.addActionListener((Action<Intent> action) => enabled2 = action.isEnabled(const SecondTestIntent())); |
| action2.enabled = false; |
| expect(enabled2, isFalse); |
| |
| bool enabled3 = true; |
| action3.addActionListener((Action<Intent> action) => enabled3 = action.isEnabled(const ThirdTestIntent())); |
| action3.enabled = false; |
| expect(enabled3, isFalse); |
| |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<TestIntent>>{ |
| TestIntent: action1, |
| SecondTestIntent: action2, |
| }, |
| child: Actions( |
| actions: <Type, Action<TestIntent>>{ |
| ThirdTestIntent: action3, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ); |
| |
| Object result = Actions.invoke( |
| containerKey.currentContext, |
| const TestIntent(), |
| ); |
| expect(enabled1, isFalse); |
| expect(result, isFalse); |
| expect(invoked1, isFalse); |
| |
| action1.enabled = true; |
| result = Actions.invoke( |
| containerKey.currentContext, |
| const TestIntent(), |
| ); |
| expect(enabled1, isTrue); |
| expect(result, isTrue); |
| expect(invoked1, isTrue); |
| |
| bool enabledChanged; |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<Intent>>{ |
| TestIntent: action1, |
| SecondTestIntent: action2, |
| }, |
| child: ActionListener( |
| listener: (Action<Intent> action) => enabledChanged = action.isEnabled(const ThirdTestIntent()), |
| action: action2, |
| child: Actions( |
| actions: <Type, Action<Intent>>{ |
| ThirdTestIntent: action3, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.pump(); |
| result = Actions.invoke<TestIntent>( |
| containerKey.currentContext, |
| const SecondTestIntent(), |
| ); |
| expect(enabledChanged, isNull); |
| expect(enabled2, isFalse); |
| expect(result, isFalse); |
| expect(invoked2, isFalse); |
| |
| action2.enabled = true; |
| expect(enabledChanged, isTrue); |
| result = Actions.invoke<TestIntent>( |
| containerKey.currentContext, |
| const SecondTestIntent(), |
| ); |
| expect(enabled2, isTrue); |
| expect(result, isTrue); |
| expect(invoked2, isTrue); |
| |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<Intent>>{ |
| TestIntent: action1, |
| }, |
| child: Actions( |
| actions: <Type, Action<Intent>>{ |
| ThirdTestIntent: action3, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ), |
| ); |
| |
| expect(action1.listeners.length, equals(2)); |
| expect(action2.listeners.length, equals(1)); |
| expect(action3.listeners.length, equals(2)); |
| |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<Intent>>{ |
| TestIntent: action1, |
| ThirdTestIntent: action3, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ); |
| |
| expect(action1.listeners.length, equals(2)); |
| expect(action2.listeners.length, equals(1)); |
| expect(action3.listeners.length, equals(2)); |
| |
| await tester.pumpWidget( |
| Actions( |
| actions: <Type, Action<Intent>>{ |
| TestIntent: action1, |
| }, |
| child: Container(key: containerKey), |
| ), |
| ); |
| |
| expect(action1.listeners.length, equals(2)); |
| expect(action2.listeners.length, equals(1)); |
| expect(action3.listeners.length, equals(1)); |
| |
| await tester.pumpWidget(Container()); |
| await tester.pump(); |
| |
| expect(action1.listeners.length, equals(1)); |
| expect(action2.listeners.length, equals(1)); |
| expect(action3.listeners.length, equals(1)); |
| }); |
| }); |
| |
| group(FocusableActionDetector, () { |
| const Intent intent = TestIntent(); |
| bool invoked; |
| bool hovering; |
| bool focusing; |
| FocusNode focusNode; |
| Action<Intent> testAction; |
| |
| Future<void> pumpTest( |
| WidgetTester tester, { |
| bool enabled = true, |
| bool directional = false, |
| @required Key key, |
| }) async { |
| await tester.pumpWidget( |
| MediaQuery( |
| data: MediaQueryData( |
| navigationMode: directional ? NavigationMode.directional : NavigationMode.traditional, |
| ), |
| child: Center( |
| child: Actions( |
| dispatcher: const TestDispatcher1(), |
| actions: const <Type, Action<Intent>>{}, |
| child: FocusableActionDetector( |
| enabled: enabled, |
| focusNode: focusNode, |
| shortcuts: <LogicalKeySet, Intent>{ |
| LogicalKeySet(LogicalKeyboardKey.enter): intent, |
| }, |
| actions: <Type, Action<Intent>>{ |
| TestIntent: testAction, |
| }, |
| onShowHoverHighlight: (bool value) => hovering = value, |
| onShowFocusHighlight: (bool value) => focusing = value, |
| child: Container(width: 100, height: 100, key: key), |
| ), |
| ), |
| ), |
| ), |
| ); |
| return tester.pump(); |
| } |
| |
| setUp(() async { |
| invoked = false; |
| hovering = false; |
| focusing = false; |
| |
| focusNode = FocusNode(debugLabel: 'Test Node'); |
| testAction = TestAction( |
| onInvoke: (Intent intent) { |
| invoked = true; |
| return invoked; |
| }, |
| ); |
| }); |
| |
| testWidgets('FocusableActionDetector keeps track of focus and hover even when disabled.', (WidgetTester tester) async { |
| FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; |
| final GlobalKey containerKey = GlobalKey(); |
| |
| await pumpTest(tester, enabled: true, key: containerKey); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse); |
| addTearDown(gesture.removePointer); |
| await gesture.moveTo(tester.getCenter(find.byKey(containerKey))); |
| await tester.pump(); |
| await tester.sendKeyEvent(LogicalKeyboardKey.enter); |
| expect(hovering, isTrue); |
| expect(focusing, isTrue); |
| expect(invoked, isTrue); |
| |
| invoked = false; |
| await pumpTest(tester, enabled: false, key: containerKey); |
| expect(hovering, isFalse); |
| expect(focusing, isFalse); |
| await tester.sendKeyEvent(LogicalKeyboardKey.enter); |
| await tester.pump(); |
| expect(invoked, isFalse); |
| await pumpTest(tester, enabled: true, key: containerKey); |
| expect(focusing, isFalse); |
| expect(hovering, isTrue); |
| await pumpTest(tester, enabled: false, key: containerKey); |
| expect(focusing, isFalse); |
| expect(hovering, isFalse); |
| await gesture.moveTo(Offset.zero); |
| await pumpTest(tester, enabled: true, key: containerKey); |
| expect(hovering, isFalse); |
| expect(focusing, isFalse); |
| }); |
| testWidgets('FocusableActionDetector shows focus highlight appropriately when focused and disabled', (WidgetTester tester) async { |
| FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; |
| final GlobalKey containerKey = GlobalKey(); |
| |
| await pumpTest(tester, enabled: true, key: containerKey); |
| await tester.pump(); |
| expect(focusing, isFalse); |
| |
| await pumpTest(tester, enabled: true, key: containerKey); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| expect(focusing, isTrue); |
| |
| focusing = false; |
| await pumpTest(tester, enabled: false, key: containerKey); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| expect(focusing, isFalse); |
| |
| await pumpTest(tester, enabled: false, key: containerKey); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| expect(focusing, isFalse); |
| |
| // In directional navigation, focus should show, even if disabled. |
| await pumpTest(tester, enabled: false, key: containerKey, directional: true); |
| focusNode.requestFocus(); |
| await tester.pump(); |
| expect(focusing, isTrue); |
| }); |
| }); |
| |
| group('Diagnostics', () { |
| testWidgets('default Intent debugFillProperties', (WidgetTester tester) async { |
| final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
| |
| // ignore: invalid_use_of_protected_member |
| const TestIntent().debugFillProperties(builder); |
| |
| final List<String> description = builder.properties |
| .where((DiagnosticsNode node) { |
| return !node.isFiltered(DiagnosticLevel.info); |
| }) |
| .map((DiagnosticsNode node) => node.toString()) |
| .toList(); |
| |
| expect(description, isEmpty); |
| }); |
| testWidgets('default Actions debugFillProperties', (WidgetTester tester) async { |
| final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
| |
| Actions( |
| actions: const <Type, Action<Intent>>{}, |
| dispatcher: const ActionDispatcher(), |
| child: Container(), |
| ).debugFillProperties(builder); |
| |
| final List<String> description = builder.properties |
| .where((DiagnosticsNode node) { |
| return !node.isFiltered(DiagnosticLevel.info); |
| }) |
| .map((DiagnosticsNode node) => node.toString()) |
| .toList(); |
| |
| expect(description.length, equals(2)); |
| expect(description[0], equalsIgnoringHashCodes('dispatcher: ActionDispatcher#00000')); |
| expect(description[1], equals('actions: {}')); |
| }); |
| testWidgets('Actions implements debugFillProperties', (WidgetTester tester) async { |
| final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
| |
| Actions( |
| key: const ValueKey<String>('foo'), |
| dispatcher: const ActionDispatcher(), |
| actions: <Type, Action<Intent>>{ |
| TestIntent: TestAction(onInvoke: (Intent intent) => null), |
| }, |
| child: Container(key: const ValueKey<String>('baz')), |
| ).debugFillProperties(builder); |
| |
| final List<String> description = builder.properties |
| .where((DiagnosticsNode node) { |
| return !node.isFiltered(DiagnosticLevel.info); |
| }) |
| .map((DiagnosticsNode node) => node.toString()) |
| .toList(); |
| |
| expect(description.length, equals(2)); |
| expect(description[0], equalsIgnoringHashCodes('dispatcher: ActionDispatcher#00000')); |
| expect(description[1], equalsIgnoringHashCodes('actions: {TestIntent: TestAction#00000}')); |
| }, skip: isBrowser); |
| }); |
| } |