// 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';

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 {
    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));
  });
  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!,
        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!,
        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);
      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);
    });
    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);
      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, 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);
      addTearDown(gesture.removePointer);
      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);
      },
    );
  });

  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}'));
    });
  });

  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);
    });
  });
}

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

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

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
  Object? 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
  Object? 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 String actionName }) : super(actionName: actionName);

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

class RedirectOutputAction extends LogInvocationAction {
  RedirectOutputAction({
      required String actionName,
      bool enabled = true,
      required this.newLog,
  }) : super(actionName: actionName, enabled: enabled);

  final List<String> newLog;

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