// 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_test/flutter_test.dart';

void main() {
  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 default dispatcher and maybeInvoke', (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.maybeInvoke(
        containerKey.currentContext!,
        const TestIntent(),
      );
      expect(result, isTrue);
      expect(invoked, isTrue);
    });
    testWidgets('maybeInvoke returns null when no action is found', (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.maybeInvoke(
        containerKey.currentContext!,
        const DoNothingIntent(),
      );
      expect(result, isNull);
      expect(invoked, isFalse);
    });
    testWidgets('invoke throws when no action is found', (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.maybeInvoke(
        containerKey.currentContext!,
        const DoNothingIntent(),
      );
      expect(result, isNull);
      expect(invoked, isFalse);
    });
    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!);
      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.maybeFind<DoNothingIntent>(containerKey.currentContext!), isNull);

      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.maybeFind<DoNothingIntent>(containerKey.currentContext!), 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: const <ShortcutActivator, Intent>{
                  SingleActivator(LogicalKeyboardKey.enter): intent,
                },
                actions: <Type, Action<Intent>>{
                  TestIntent: testAction,
                },
                onShowHoverHighlight: (bool value) => hovering = value,
                onShowFocusHighlight: (bool value) => focusing = value,
                child: SizedBox(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);
      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));
      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);
    });
    testWidgets('Actions.invoke returns the value of Action.invoke', (WidgetTester tester) async {
      final GlobalKey containerKey = GlobalKey();
      final Object sentinel = Object();
      bool invoked = false;
      const TestIntent intent = TestIntent();
      final Action<Intent> testAction = TestAction(
        onInvoke: (Intent intent) {
          invoked = true;
          return sentinel;
        },
      );

      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(identical(result, sentinel), isTrue);
      expect(invoked, isTrue);
    });
    testWidgets('ContextAction can return null', (WidgetTester tester) async {
      final GlobalKey containerKey = GlobalKey();
      const TestIntent intent = TestIntent();
      final TestContextAction testAction = TestContextAction();

      await tester.pumpWidget(
        Actions(
          dispatcher: TestDispatcher1(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, isNull);
      expect(invokedIntent, equals(intent));
      expect(invokedAction, equals(testAction));
      expect(invokedDispatcher.runtimeType, equals(TestDispatcher1));
      expect(testAction.capturedContexts.single, containerKey.currentContext);
    });
    testWidgets('Disabled actions stop propagation to an ancestor', (WidgetTester tester) async {
      final GlobalKey containerKey = GlobalKey();
      bool invoked = false;
      const TestIntent intent = TestIntent();
      final TestAction enabledTestAction = TestAction(
        onInvoke: (Intent intent) {
          invoked = true;
          return invoked;
        },
      );
      enabledTestAction.enabled = true;
      final TestAction disabledTestAction = TestAction(
        onInvoke: (Intent intent) {
          invoked = true;
          return invoked;
        },
      );
      disabledTestAction.enabled = false;

      await tester.pumpWidget(
        Actions(
          dispatcher: TestDispatcher1(postInvoke: collect),
          actions: <Type, Action<Intent>>{
            TestIntent: enabledTestAction,
          },
          child: Actions(
            dispatcher: TestDispatcher(postInvoke: collect),
            actions: <Type, Action<Intent>>{
              TestIntent: disabledTestAction,
            },
            child: Container(key: containerKey),
          ),
        ),
      );

      await tester.pump();
      final Object? result = Actions.invoke<TestIntent>(
        containerKey.currentContext!,
        intent,
      );
      expect(result, isNull);
      expect(invoked, isFalse);
      expect(invokedIntent, isNull);
      expect(invokedAction, isNull);
      expect(invokedDispatcher, isNull);
    });
  });

  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.maybeInvoke(
        containerKey.currentContext!,
        const TestIntent(),
      );
      expect(enabled1, isFalse);
      expect(result, isNull);
      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.maybeInvoke<TestIntent>(
        containerKey.currentContext!,
        const SecondTestIntent(),
      );
      expect(enabledChanged, isNull);
      expect(enabled2, isFalse);
      expect(result, isNull);
      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();
    late bool invoked;
    late bool hovering;
    late bool focusing;
    late FocusNode focusNode;
    late Action<Intent> testAction;

    Future<void> pumpTest(
        WidgetTester tester, {
          bool enabled = true,
          bool directional = false,
          bool supplyCallbacks = true,
          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: const <ShortcutActivator, Intent>{
                  SingleActivator(LogicalKeyboardKey.enter): intent,
                },
                actions: <Type, Action<Intent>>{
                  TestIntent: testAction,
                },
                onShowHoverHighlight: supplyCallbacks ? (bool value) => hovering = value : null,
                onShowFocusHighlight: supplyCallbacks ? (bool value) => focusing = value : null,
                child: SizedBox(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, key: containerKey);
      focusNode.requestFocus();
      await tester.pump();
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      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, 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, 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, key: containerKey);
      await tester.pump();
      expect(focusing, isFalse);

      await pumpTest(tester, 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);
    });
    testWidgets('FocusableActionDetector can be used without callbacks', (WidgetTester tester) async {
      FocusManager.instance.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
      final GlobalKey containerKey = GlobalKey();

      await pumpTest(tester, key: containerKey, supplyCallbacks: false);
      focusNode.requestFocus();
      await tester.pump();
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.moveTo(tester.getCenter(find.byKey(containerKey)));
      await tester.pump();
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      expect(hovering, isFalse);
      expect(focusing, isFalse);
      expect(invoked, isTrue);

      invoked = false;
      await pumpTest(tester, enabled: false, key: containerKey, supplyCallbacks: false);
      expect(hovering, isFalse);
      expect(focusing, isFalse);
      await tester.sendKeyEvent(LogicalKeyboardKey.enter);
      await tester.pump();
      expect(invoked, isFalse);
      await pumpTest(tester, key: containerKey, supplyCallbacks: false);
      expect(focusing, isFalse);
      expect(hovering, isFalse);
      await pumpTest(tester, enabled: false, key: containerKey, supplyCallbacks: false);
      expect(focusing, isFalse);
      expect(hovering, isFalse);
      await gesture.moveTo(Offset.zero);
      await pumpTest(tester, key: containerKey, supplyCallbacks: false);
      expect(hovering, isFalse);
      expect(focusing, isFalse);
    });

    testWidgets(
      'FocusableActionDetector can prevent its descendants from being focusable',
      (WidgetTester tester) async {
        final FocusNode buttonNode = FocusNode(debugLabel: 'Test');

        await tester.pumpWidget(
          MaterialApp(
            home: FocusableActionDetector(
              child: MaterialButton(
                focusNode: buttonNode,
                child: const Text('Test'),
                onPressed: () {},
              ),
            ),
          ),
        );

        // Button is focusable
        expect(buttonNode.hasFocus, isFalse);
        buttonNode.requestFocus();
        await tester.pump();
        expect(buttonNode.hasFocus, isTrue);

        await tester.pumpWidget(
          MaterialApp(
            home: FocusableActionDetector(
              descendantsAreFocusable: false,
              child: MaterialButton(
                focusNode: buttonNode,
                child: const Text('Test'),
                onPressed: () {},
              ),
            ),
          ),
        );

        // Button is NOT focusable
        expect(buttonNode.hasFocus, isFalse);
        buttonNode.requestFocus();
        await tester.pump();
        expect(buttonNode.hasFocus, isFalse);
      },
    );

    testWidgets(
      'FocusableActionDetector can prevent its descendants from being traversable',
          (WidgetTester tester) async {
        final FocusNode buttonNode1 = FocusNode(debugLabel: 'Button Node 1');
        final FocusNode buttonNode2 = FocusNode(debugLabel: 'Button Node 2');

        await tester.pumpWidget(
          MaterialApp(
            home: FocusableActionDetector(
              child: Column(
                children: <Widget>[
                  MaterialButton(
                    focusNode: buttonNode1,
                    child: const Text('Node 1'),
                    onPressed: () {},
                  ),
                  MaterialButton(
                    focusNode: buttonNode2,
                    child: const Text('Node 2'),
                    onPressed: () {},
                  ),
                ],
              ),
            ),
          ),
        );

        buttonNode1.requestFocus();
        await tester.pump();
        expect(buttonNode1.hasFocus, isTrue);
        expect(buttonNode2.hasFocus, isFalse);
        primaryFocus!.nextFocus();
        await tester.pump();
        expect(buttonNode1.hasFocus, isFalse);
        expect(buttonNode2.hasFocus, isTrue);

        await tester.pumpWidget(
          MaterialApp(
            home: FocusableActionDetector(
              descendantsAreTraversable: false,
              child: Column(
                children: <Widget>[
                  MaterialButton(
                    focusNode: buttonNode1,
                    child: const Text('Node 1'),
                    onPressed: () {},
                  ),
                  MaterialButton(
                    focusNode: buttonNode2,
                    child: const Text('Node 2'),
                    onPressed: () {},
                  ),
                ],
              ),
            ),
          ),
        );

        buttonNode1.requestFocus();
        await tester.pump();
        expect(buttonNode1.hasFocus, isTrue);
        expect(buttonNode2.hasFocus, isFalse);
        primaryFocus!.nextFocus();
        await tester.pump();
        expect(buttonNode1.hasFocus, isTrue);
        expect(buttonNode2.hasFocus, isFalse);
      },
    );
  });

  group('Action subclasses', () {
    testWidgets('CallbackAction passes correct intent when invoked.', (WidgetTester tester) async {
      late Intent passedIntent;
      final TestAction action = TestAction(onInvoke: (Intent intent) {
        passedIntent = intent;
        return true;
      });
      const TestIntent intent = TestIntent();
      action._testInvoke(intent);
      expect(passedIntent, equals(intent));
    });
    testWidgets('VoidCallbackAction', (WidgetTester tester) async {
      bool called = false;
      void testCallback() {
        called = true;
      }
      final VoidCallbackAction action = VoidCallbackAction();
      final VoidCallbackIntent intent = VoidCallbackIntent(testCallback);
      action.invoke(intent);
      expect(called, 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,
        equalsIgnoringHashCodes(<String>[
          'dispatcher: ActionDispatcher#00000',
          '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,
        equalsIgnoringHashCodes(<String>[
          'dispatcher: ActionDispatcher#00000',
          'actions: {TestIntent: TestAction#00000}',
        ]),
      );
    });
  });

  group('Action overriding', () {
    final List<String> invocations = <String>[];
    BuildContext? invokingContext;

    tearDown(() {
      invocations.clear();
      invokingContext = null;
    });

    testWidgets('Basic usage', (WidgetTester tester) async {
      late BuildContext invokingContext2;
      late BuildContext invokingContext3;
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent : Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  invokingContext2 = context2;
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent : Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2'), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        invokingContext3 = context3;
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);

      invocations.clear();
      // Invoke from a different (higher) context.
      Actions.invoke(invokingContext3, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invoke',
        'action1.invokeAsOverride-post-super',
      ]);

      invocations.clear();
      // Invoke from a different (higher) context.
      Actions.invoke(invokingContext2, LogIntent(log: invocations));
      expect(invocations, <String>['action1.invoke']);
    });

    testWidgets('Does not break after use', (WidgetTester tester) async {
      late BuildContext invokingContext2;
      late BuildContext invokingContext3;
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  invokingContext2 = context2;
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2'), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        invokingContext3 = context3;
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      // Invoke a bunch of times and verify it still produces the same result.
      final List<BuildContext> randomContexts = <BuildContext>[
        invokingContext!,
        invokingContext2,
        invokingContext!,
        invokingContext3,
        invokingContext3,
        invokingContext3,
        invokingContext2,
      ];

      for (final BuildContext randomContext in randomContexts) {
        Actions.invoke(randomContext, LogIntent(log: invocations));
      }

      invocations.clear();
      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);
    });

    testWidgets('Does not override if not overridable', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> { LogIntent : LogInvocationAction(actionName: 'action2') },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
      ]);
    });

    testWidgets('The final override controls isEnabled', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2', enabled: false), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);

      invocations.clear();
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1', enabled: false), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2'), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[]);
    });

    testWidgets('The override can choose to defer isActionEnabled to the overridable', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationButDeferIsEnabledAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2', enabled: false), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      // Nothing since the final override defers its isActionEnabled state to action2,
      // which is disabled.
      expect(invocations, <String>[]);

      invocations.clear();
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationButDeferIsEnabledAction(actionName: 'action2'), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3', enabled: false), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      // The final override (action1) is enabled so all 3 actions are enabled.
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);
    });

    testWidgets('Throws on infinite recursions', (WidgetTester tester) async {
      late StateSetter setState;
      BuildContext? action2LookupContext;
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: StatefulBuilder(
                builder: (BuildContext context2, StateSetter stateSetter) {
                  setState = stateSetter;
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      if (action2LookupContext != null) LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2'), context: action2LookupContext!),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      // Let action2 look up its override using a context below itself, so it
      // will find action3 as its override.
      expect(tester.takeException(), isNull);
      setState(() {
        action2LookupContext = invokingContext;
      });

      await tester.pump();
      expect(tester.takeException(), isNull);

      Object? exception;
      try {
        Actions.invoke(invokingContext!, LogIntent(log: invocations));
      } catch (e) {
        exception = e;
      }
      expect(exception?.toString(), contains('debugAssertIsEnabledMutuallyRecursive'));
    });

    testWidgets('Throws on invoking invalid override', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context) {
            return Actions(
              actions: <Type, Action<Intent>> { LogIntent : TestContextAction() },
              child: Builder(
                builder: (BuildContext context) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context),
                    },
                    child: Builder(
                      builder: (BuildContext context1) {
                        invokingContext = context1;
                        return const SizedBox();
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Object? exception;
      try {
        Actions.invoke(invokingContext!, LogIntent(log: invocations));
      } catch (e) {
        exception = e;
      }
      expect(
        exception?.toString(),
        contains('cannot be handled by an Action of runtime type TestContextAction.'),
      );
    });

    testWidgets('Make an overridable action overridable', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2'), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(
                              defaultAction: Action<LogIntent>.overridable(
                                defaultAction: Action<LogIntent>.overridable(
                                  defaultAction: LogInvocationAction(actionName: 'action3'),
                                  context: context1,
                                ),
                                context: context2,
                              ),
                              context: context3,
                            ),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);
    });

    testWidgets('Overriding Actions can change the intent', (WidgetTester tester) async {
      final List<String> newLogChannel = <String>[];
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: RedirectOutputAction(actionName: 'action2', newLog: newLogChannel), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action1.invokeAsOverride-post-super',
      ]);
      expect(newLogChannel, <String>[
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
      ]);
    });

    testWidgets('Override non-context overridable Actions with a ContextAction', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                // The default Action is a ContextAction subclass.
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationContextAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action2', enabled: false), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);

      // Action1 is a ContextAction and action2 & action3 are not.
      // They should not lose information.
      expect(LogInvocationContextAction.invokeContext, isNotNull);
      expect(LogInvocationContextAction.invokeContext, invokingContext);
    });

    testWidgets('Override a ContextAction with a regular Action', (WidgetTester tester) async {
      await tester.pumpWidget(
        Builder(
          builder: (BuildContext context1) {
            return Actions(
              actions: <Type, Action<Intent>> {
                LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action1'), context: context1),
              },
              child: Builder(
                builder: (BuildContext context2) {
                  return Actions(
                    actions: <Type, Action<Intent>> {
                      LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationContextAction(actionName: 'action2', enabled: false), context: context2),
                    },
                    child: Builder(
                      builder: (BuildContext context3) {
                        return Actions(
                          actions: <Type, Action<Intent>> {
                            LogIntent: Action<LogIntent>.overridable(defaultAction: LogInvocationAction(actionName: 'action3'), context: context3),
                          },
                          child: Builder(
                            builder: (BuildContext context4) {
                              invokingContext = context4;
                              return const SizedBox();
                            },
                          ),
                        );
                      },
                    ),
                  );
                },
              ),
            );
          },
        ),
      );

      Actions.invoke(invokingContext!, LogIntent(log: invocations));
      expect(invocations, <String>[
        'action1.invokeAsOverride-pre-super',
        'action2.invokeAsOverride-pre-super',
        'action3.invoke',
        'action2.invokeAsOverride-post-super',
        'action1.invokeAsOverride-post-super',
      ]);

      // Action2 is a ContextAction and action1 & action2 are regular actions.
      // Invoking action2 from action3 should still supply a non-null
      // BuildContext.
      expect(LogInvocationContextAction.invokeContext, isNotNull);
      expect(LogInvocationContextAction.invokeContext, invokingContext);
    });
  });
}

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({super.postInvoke});
}

class TestContextAction extends ContextAction<TestIntent> {
  List<BuildContext?> capturedContexts = <BuildContext?>[];

  @override
  void invoke(covariant TestIntent intent, [BuildContext? context]) {
    capturedContexts.add(context);
  }
}

class LogIntent extends Intent {
  const LogIntent({ required this.log });

  final List<String> log;
}

class LogInvocationAction extends Action<LogIntent> {
  LogInvocationAction({ required this.actionName, this.enabled = true });

  final String actionName;

  final bool enabled;

  @override
  bool get isActionEnabled => enabled;

  @override
  void invoke(LogIntent intent) {
    final Action<LogIntent>? callingAction = this.callingAction;
    if (callingAction == null) {
      intent.log.add('$actionName.invoke');
    } else {
      intent.log.add('$actionName.invokeAsOverride-pre-super');
      callingAction.invoke(intent);
      intent.log.add('$actionName.invokeAsOverride-post-super');
    }
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(StringProperty('actionName', actionName));
  }
}

class LogInvocationContextAction extends ContextAction<LogIntent> {
  LogInvocationContextAction({ required this.actionName, this.enabled = true });

  static BuildContext? invokeContext;

  final String actionName;

  final bool enabled;

  @override
  bool get isActionEnabled => enabled;

  @override
  void invoke(LogIntent intent, [BuildContext? context]) {
    invokeContext = context;
    final Action<LogIntent>? callingAction = this.callingAction;
    if (callingAction == null) {
      intent.log.add('$actionName.invoke');
    } else {
      intent.log.add('$actionName.invokeAsOverride-pre-super');
      callingAction.invoke(intent);
      intent.log.add('$actionName.invokeAsOverride-post-super');
    }
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(StringProperty('actionName', actionName));
  }
}

class LogInvocationButDeferIsEnabledAction extends LogInvocationAction {
  LogInvocationButDeferIsEnabledAction({ required super.actionName });

  // Defer `isActionEnabled` to the overridable action.
  @override
  bool get isActionEnabled => callingAction?.isActionEnabled ?? false;
}

class RedirectOutputAction extends LogInvocationAction {
  RedirectOutputAction({
      required super.actionName,
      super.enabled,
      required this.newLog,
  });

  final List<String> newLog;

  @override
  void invoke(LogIntent intent) => super.invoke(LogIntent(log: newLog));
}
