// 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/gestures.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  const Offset forcePressOffset = Offset(400.0, 50.0);

  testWidgets('Uncontested scrolls start immediately', (WidgetTester tester) async {
    bool didStartDrag = false;
    double? updatedDragDelta;
    bool didEndDrag = false;

    final Widget widget = GestureDetector(
      onVerticalDragStart: (DragStartDetails details) {
        didStartDrag = true;
      },
      onVerticalDragUpdate: (DragUpdateDetails details) {
        updatedDragDelta = details.primaryDelta;
      },
      onVerticalDragEnd: (DragEndDetails details) {
        didEndDrag = true;
      },
      child: Container(
        color: const Color(0xFF00FF00),
      ),
    );

    await tester.pumpWidget(widget);
    expect(didStartDrag, isFalse);
    expect(updatedDragDelta, isNull);
    expect(didEndDrag, isFalse);

    const Offset firstLocation = Offset(10.0, 10.0);
    final TestGesture gesture = await tester.startGesture(firstLocation, pointer: 7);
    expect(didStartDrag, isTrue);
    didStartDrag = false;
    expect(updatedDragDelta, isNull);
    expect(didEndDrag, isFalse);

    const Offset secondLocation = Offset(10.0, 9.0);
    await gesture.moveTo(secondLocation);
    expect(didStartDrag, isFalse);
    expect(updatedDragDelta, -1.0);
    updatedDragDelta = null;
    expect(didEndDrag, isFalse);

    await gesture.up();
    expect(didStartDrag, isFalse);
    expect(updatedDragDelta, isNull);
    expect(didEndDrag, isTrue);
    didEndDrag = false;

    await tester.pumpWidget(Container());
  });

  testWidgets('Match two scroll gestures in succession', (WidgetTester tester) async {
    int gestureCount = 0;
    double dragDistance = 0.0;

    const Offset downLocation = Offset(10.0, 10.0);
    const Offset upLocation = Offset(10.0, 50.0); // must be far enough to be more than kTouchSlop

    final Widget widget = GestureDetector(
      dragStartBehavior: DragStartBehavior.down,
      onVerticalDragUpdate: (DragUpdateDetails details) { dragDistance += details.primaryDelta ?? 0; },
      onVerticalDragEnd: (DragEndDetails details) { gestureCount += 1; },
      onHorizontalDragUpdate: (DragUpdateDetails details) { fail('gesture should not match'); },
      onHorizontalDragEnd: (DragEndDetails details) { fail('gesture should not match'); },
      child: Container(
        color: const Color(0xFF00FF00),
      ),
    );
    await tester.pumpWidget(widget);

    TestGesture gesture = await tester.startGesture(downLocation, pointer: 7);
    await gesture.moveTo(upLocation);
    await gesture.up();

    gesture = await tester.startGesture(downLocation, pointer: 7);
    await gesture.moveTo(upLocation);
    await gesture.up();

    expect(gestureCount, 2);
    expect(dragDistance, 40.0 * 2.0); // delta between down and up, twice

    await tester.pumpWidget(Container());
  });

  testWidgets("Pan doesn't crash", (WidgetTester tester) async {
    bool didStartPan = false;
    Offset? panDelta;
    bool didEndPan = false;

    await tester.pumpWidget(
      GestureDetector(
        onPanStart: (DragStartDetails details) {
          didStartPan = true;
        },
        onPanUpdate: (DragUpdateDetails details) {
          panDelta = (panDelta ?? Offset.zero) + details.delta;
        },
        onPanEnd: (DragEndDetails details) {
          didEndPan = true;
        },
        child: Container(
          color: const Color(0xFF00FF00),
        ),
      ),
    );

    expect(didStartPan, isFalse);
    expect(panDelta, isNull);
    expect(didEndPan, isFalse);

    await tester.dragFrom(const Offset(10.0, 10.0), const Offset(20.0, 30.0));

    expect(didStartPan, isTrue);
    expect(panDelta!.dx, 20.0);
    expect(panDelta!.dy, 30.0);
    expect(didEndPan, isTrue);
  });

  group('Tap', () {
    final ButtonVariant buttonVariant = ButtonVariant(
      values: <int>[kPrimaryButton, kSecondaryButton, kTertiaryButton],
      descriptions: <int, String>{
        kPrimaryButton: 'primary',
        kSecondaryButton: 'secondary',
        kTertiaryButton: 'tertiary',
      },
    );

    testWidgets('Translucent', (WidgetTester tester) async {
      bool didReceivePointerDown;
      bool didTap;

      Future<void> pumpWidgetTree(HitTestBehavior? behavior) {
        return tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: Stack(
              children: <Widget>[
                Listener(
                  onPointerDown: (_) {
                    didReceivePointerDown = true;
                  },
                  child: Container(
                    width: 100.0,
                    height: 100.0,
                    color: const Color(0xFF00FF00),
                  ),
                ),
                SizedBox(
                  width: 100.0,
                  height: 100.0,
                  child: GestureDetector(
                    onTap: ButtonVariant.button == kPrimaryButton ? () {
                      didTap = true;
                    } : null,
                    onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
                      didTap = true;
                    } : null,
                    onTertiaryTapDown: ButtonVariant.button == kTertiaryButton ? (_) {
                      didTap = true;
                    } : null,
                    behavior: behavior,
                  ),
                ),
              ],
            ),
          ),
        );
      }

      didReceivePointerDown = false;
      didTap = false;
      await pumpWidgetTree(null);
      await tester.tapAt(const Offset(10.0, 10.0), buttons: ButtonVariant.button);
      expect(didReceivePointerDown, isTrue);
      expect(didTap, isTrue);

      didReceivePointerDown = false;
      didTap = false;
      await pumpWidgetTree(HitTestBehavior.deferToChild);
      await tester.tapAt(const Offset(10.0, 10.0), buttons: ButtonVariant.button);
      expect(didReceivePointerDown, isTrue);
      expect(didTap, isFalse);

      didReceivePointerDown = false;
      didTap = false;
      await pumpWidgetTree(HitTestBehavior.opaque);
      await tester.tapAt(const Offset(10.0, 10.0), buttons: ButtonVariant.button);
      expect(didReceivePointerDown, isFalse);
      expect(didTap, isTrue);

      didReceivePointerDown = false;
      didTap = false;
      await pumpWidgetTree(HitTestBehavior.translucent);
      await tester.tapAt(const Offset(10.0, 10.0), buttons: ButtonVariant.button);
      expect(didReceivePointerDown, isTrue);
      expect(didTap, isTrue);
    }, variant: buttonVariant);

    testWidgets('Empty', (WidgetTester tester) async {
      bool didTap = false;
      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onTap: ButtonVariant.button == kPrimaryButton ? () {
              didTap = true;
            } : null,
            onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
              didTap = true;
            } : null,
            onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) {
              didTap = true;
            } : null,
          ),
        ),
      );
      expect(didTap, isFalse);
      await tester.tapAt(const Offset(10.0, 10.0), buttons: ButtonVariant.button);
      expect(didTap, isTrue);
    }, variant: buttonVariant);

    testWidgets('Only container', (WidgetTester tester) async {
      bool didTap = false;
      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onTap: ButtonVariant.button == kPrimaryButton ? () {
              didTap = true;
            } : null,
            onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
              didTap = true;
            } : null,
            onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) {
              didTap = true;
            } : null,
            child: Container(),
          ),
        ),
      );
      expect(didTap, isFalse);
      await tester.tapAt(const Offset(10.0, 10.0));
      expect(didTap, isFalse);
    }, variant: buttonVariant);

    testWidgets('cache render object', (WidgetTester tester) async {
      void inputCallback() { }

      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
            onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
            onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) => inputCallback() : null,
            child: Container(),
          ),
        ),
      );

      final RenderSemanticsGestureHandler renderObj1 = tester.renderObject(find.byType(GestureDetector));

      await tester.pumpWidget(
        Center(
          child: GestureDetector(
            onTap: ButtonVariant.button == kPrimaryButton ? inputCallback : null,
            onSecondaryTap: ButtonVariant.button == kSecondaryButton ? inputCallback : null,
            onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (_) => inputCallback() : null,
            child: Container(),
          ),
        ),
      );

      final RenderSemanticsGestureHandler renderObj2 = tester.renderObject(find.byType(GestureDetector));

      expect(renderObj1, same(renderObj2));
    }, variant: buttonVariant);

    testWidgets('Tap down occurs after kPressTimeout', (WidgetTester tester) async {
      int tapDown = 0;
      int tap = 0;
      int tapCancel = 0;
      int longPress = 0;

      await tester.pumpWidget(
        Container(
          alignment: Alignment.topLeft,
          child: Container(
            alignment: Alignment.center,
            height: 100.0,
            color: const Color(0xFF00FF00),
            child: RawGestureDetector(
              behavior: HitTestBehavior.translucent,
              // Adding long press callbacks here will cause the on*TapDown callbacks to be executed only after
              // kPressTimeout has passed. Without the long press callbacks, there would be no press pointers
              // competing in the arena. Hence, we add them to the arena to test this behavior.
              //
              // We use a raw gesture detector directly here because gesture detector does
              // not expose callbacks for the tertiary variant of long presses, i.e. no onTertiaryLongPress*
              // callbacks are exposed in GestureDetector.
              //
              // The primary and secondary long press callbacks could also be put into the gesture detector below,
              // however, it is clearer when they are all in one place.
              gestures: <Type, GestureRecognizerFactory>{
                LongPressGestureRecognizer: GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
                  () => LongPressGestureRecognizer(),
                  (LongPressGestureRecognizer instance) {
                    instance
                      ..onLongPress = ButtonVariant.button == kPrimaryButton ? () {
                        longPress += 1;
                      } : null
                      ..onSecondaryLongPress = ButtonVariant.button == kSecondaryButton ? () {
                        longPress += 1;
                      } : null
                      ..onTertiaryLongPress = ButtonVariant.button == kTertiaryButton ? () {
                        longPress += 1;
                      } : null;
                  },
                ),
              },
              child: GestureDetector(
                onTapDown: ButtonVariant.button == kPrimaryButton ? (TapDownDetails details) {
                  tapDown += 1;
                } : null,
                onSecondaryTapDown: ButtonVariant.button == kSecondaryButton ? (TapDownDetails details) {
                  tapDown += 1;
                } : null,
                onTertiaryTapDown: ButtonVariant.button == kTertiaryButton ? (TapDownDetails details) {
                  tapDown += 1;
                } : null,
                onTap: ButtonVariant.button == kPrimaryButton ? () {
                  tap += 1;
                } : null,
                onSecondaryTap: ButtonVariant.button == kSecondaryButton ? () {
                  tap += 1;
                } : null,
                onTertiaryTapUp: ButtonVariant.button == kTertiaryButton ? (TapUpDetails details) {
                  tap += 1;
                } : null,
                onTapCancel: ButtonVariant.button == kPrimaryButton ? () {
                  tapCancel += 1;
                } : null,
                onSecondaryTapCancel: ButtonVariant.button == kSecondaryButton ? () {
                  tapCancel += 1;
                } : null,
                onTertiaryTapCancel: ButtonVariant.button == kTertiaryButton ? () {
                  tapCancel += 1;
                } : null,
              ),
            ),
          ),
        ),
      );

      // Pointer is dragged from the center of the 800x100 gesture detector
      // to a point (400,300) below it. This should never call onTap.
      Future<void> dragOut(Duration timeout) async {
        final TestGesture gesture =
        await tester.startGesture(const Offset(400.0, 50.0), buttons: ButtonVariant.button);
        // If the timeout is less than kPressTimeout the recognizer will not
        // trigger any callbacks. If the timeout is greater than kLongPressTimeout
        // then onTapDown, onLongPress, and onCancel will be called.
        await tester.pump(timeout);
        await gesture.moveTo(const Offset(400.0, 300.0));
        await gesture.up();
      }

      await dragOut(kPressTimeout * 0.5); // generates nothing
      expect(tapDown, 0);
      expect(tapCancel, 0);
      expect(tap, 0);
      expect(longPress, 0);

      await dragOut(kPressTimeout); // generates tapDown, tapCancel
      expect(tapDown, 1);
      expect(tapCancel, 1);
      expect(tap, 0);
      expect(longPress, 0);

      await dragOut(kLongPressTimeout); // generates tapDown, longPress, tapCancel
      expect(tapDown, 2);
      expect(tapCancel, 2);
      expect(tap, 0);
      expect(longPress, 1);
    }, variant: buttonVariant);

    testWidgets('Long Press Up Callback called after long press', (WidgetTester tester) async {
      int longPressUp = 0;

      await tester.pumpWidget(
        Container(
          alignment: Alignment.topLeft,
          child: Container(
            alignment: Alignment.center,
            height: 100.0,
            color: const Color(0xFF00FF00),
            child: RawGestureDetector(
              // We use a raw gesture detector directly here because gesture detector does
              // not expose callbacks for the tertiary variant of long presses, i.e. no onTertiaryLongPress*
              // callbacks are exposed in GestureDetector, and we want to test all three variants.
              //
              // The primary and secondary long press callbacks could also be put into the gesture detector below,
              // however, it is more convenient to have them all in one place.
              gestures: <Type, GestureRecognizerFactory>{
                LongPressGestureRecognizer: GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
                      () => LongPressGestureRecognizer(),
                      (LongPressGestureRecognizer instance) {
                    instance
                      ..onLongPressUp = ButtonVariant.button == kPrimaryButton ? () {
                        longPressUp += 1;
                      } : null
                      ..onSecondaryLongPressUp = ButtonVariant.button == kSecondaryButton ? () {
                        longPressUp += 1;
                      } : null
                      ..onTertiaryLongPressUp = ButtonVariant.button == kTertiaryButton ? () {
                        longPressUp += 1;
                      } : null;
                  },
                ),
              },
            ),
          ),
        ),
      );

      Future<void> longPress(Duration timeout) async {
        final TestGesture gesture = await tester.startGesture(const Offset(400.0, 50.0), buttons: ButtonVariant.button);
        await tester.pump(timeout);
        await gesture.up();
      }

      await longPress(kLongPressTimeout + const Duration(seconds: 1)); // To make sure the time for long press has occurred
      expect(longPressUp, 1);
    }, variant: buttonVariant);
  });

  testWidgets('Primary and secondary long press callbacks should work together in GestureDetector', (WidgetTester tester) async {
    bool primaryLongPress = false, secondaryLongPress = false;

    await tester.pumpWidget(
      Container(
        alignment: Alignment.topLeft,
        child: Container(
          alignment: Alignment.center,
          height: 100.0,
          color: const Color(0xFF00FF00),
          child: GestureDetector(
            onLongPress: () {
              primaryLongPress = true;
            },
            onSecondaryLongPress: () {
              secondaryLongPress = true;
            },
          ),
        ),
      ),
    );

    Future<void> longPress(Duration timeout, int buttons) async {
      final TestGesture gesture = await tester.startGesture(const Offset(400.0, 50.0), buttons: buttons);
      await tester.pump(timeout);
      await gesture.up();
    }

    // Adding a second to make sure the time for long press has occurred.
    await longPress(kLongPressTimeout + const Duration(seconds: 1), kPrimaryButton);
    expect(primaryLongPress, isTrue);

    await longPress(kLongPressTimeout + const Duration(seconds: 1), kSecondaryButton);
    expect(secondaryLongPress, isTrue);
  });

  testWidgets('Force Press Callback called after force press', (WidgetTester tester) async {
    int forcePressStart = 0;
    int forcePressPeaked = 0;
    int forcePressUpdate = 0;
    int forcePressEnded = 0;

    await tester.pumpWidget(
      Container(
        alignment: Alignment.topLeft,
        child: Container(
          alignment: Alignment.center,
          height: 100.0,
          color: const Color(0xFF00FF00),
          child: GestureDetector(
            onForcePressStart: (_) => forcePressStart += 1,
            onForcePressEnd: (_) => forcePressEnded += 1,
            onForcePressPeak: (_) => forcePressPeaked += 1,
            onForcePressUpdate: (_) => forcePressUpdate += 1,
          ),
        ),
      ),
    );
    final int pointerValue = tester.nextPointer;

    final TestGesture gesture = await tester.createGesture();
    await gesture.downWithCustomEvent(
      forcePressOffset,
      PointerDownEvent(
        pointer: pointerValue,
        position: forcePressOffset,
        pressure: 0.0,
        pressureMax: 6.0,
        pressureMin: 0.0,
      ),
    );

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.3,
      pressureMin: 0,
    ));

    expect(forcePressStart, 0);
    expect(forcePressPeaked, 0);
    expect(forcePressUpdate, 0);
    expect(forcePressEnded, 0);

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.5,
      pressureMin: 0,
    ));

    expect(forcePressStart, 1);
    expect(forcePressPeaked, 0);
    expect(forcePressUpdate, 1);
    expect(forcePressEnded, 0);

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.6,
      pressureMin: 0,
    ));
    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.7,
      pressureMin: 0,
    ));
    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.2,
      pressureMin: 0,
    ));
    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.3,
      pressureMin: 0,
    ));

    expect(forcePressStart, 1);
    expect(forcePressPeaked, 0);
    expect(forcePressUpdate, 5);
    expect(forcePressEnded, 0);

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.9,
      pressureMin: 0,
    ));

    expect(forcePressStart, 1);
    expect(forcePressPeaked, 1);
    expect(forcePressUpdate, 6);
    expect(forcePressEnded, 0);

    await gesture.up();

    expect(forcePressStart, 1);
    expect(forcePressPeaked, 1);
    expect(forcePressUpdate, 6);
    expect(forcePressEnded, 1);
  });

  testWidgets('Force Press Callback not called if long press triggered before force press', (WidgetTester tester) async {
    int forcePressStart = 0;
    int longPressTimes = 0;

    await tester.pumpWidget(
      Container(
        alignment: Alignment.topLeft,
        child: Container(
          alignment: Alignment.center,
          height: 100.0,
          color: const Color(0xFF00FF00),
          child: GestureDetector(
            onForcePressStart: (_) => forcePressStart += 1,
            onLongPress: () => longPressTimes += 1,
          ),
        ),
      ),
    );

    final int pointerValue = tester.nextPointer;
    const double maxPressure = 6.0;

    final TestGesture gesture = await tester.createGesture();

    await gesture.downWithCustomEvent(
      forcePressOffset,
      PointerDownEvent(
        pointer: pointerValue,
        position: forcePressOffset,
        pressure: 0.0,
        pressureMax: maxPressure,
        pressureMin: 0.0,
      ),
    );

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      position: const Offset(400.0, 50.0),
      pressure: 0.3,
      pressureMin: 0,
      pressureMax: maxPressure,
    ));

    expect(forcePressStart, 0);
    expect(longPressTimes, 0);

    // Trigger the long press.
    await tester.pump(kLongPressTimeout + const Duration(seconds: 1));

    expect(longPressTimes, 1);
    expect(forcePressStart, 0);

    // Failed attempt to trigger the force press.
    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      position: const Offset(400.0, 50.0),
      pressure: 0.5,
      pressureMin: 0,
      pressureMax: maxPressure,
    ));

    expect(longPressTimes, 1);
    expect(forcePressStart, 0);
  });

  testWidgets('Force Press Callback not called if drag triggered before force press', (WidgetTester tester) async {
    int forcePressStart = 0;
    int horizontalDragStart = 0;

    await tester.pumpWidget(
      Container(
        alignment: Alignment.topLeft,
        child: Container(
          alignment: Alignment.center,
          height: 100.0,
          color: const Color(0xFF00FF00),
          child: GestureDetector(
            onForcePressStart: (_) => forcePressStart += 1,
            onHorizontalDragStart: (_) => horizontalDragStart += 1,
          ),
        ),
      ),
    );

    final int pointerValue = tester.nextPointer;

    final TestGesture gesture = await tester.createGesture();

    await gesture.downWithCustomEvent(
      forcePressOffset,
      PointerDownEvent(
        pointer: pointerValue,
        position: forcePressOffset,
        pressure: 0.0,
        pressureMax: 6.0,
        pressureMin: 0.0,
      ),
    );

    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.3,
      pressureMin: 0,
    ));

    expect(forcePressStart, 0);
    expect(horizontalDragStart, 0);

    // Trigger horizontal drag.
    await gesture.moveBy(const Offset(100, 0));

    expect(horizontalDragStart, 1);
    expect(forcePressStart, 0);

    // Failed attempt to trigger the force press.
    await gesture.updateWithCustomEvent(PointerMoveEvent(
      pointer: pointerValue,
      pressure: 0.5,
      pressureMin: 0,
    ));

    expect(horizontalDragStart, 1);
    expect(forcePressStart, 0);
  });

  group("RawGestureDetectorState's debugFillProperties", () {
    testWidgets('when default', (WidgetTester tester) async {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(RawGestureDetector(
        key: key,
      ));
      key.currentState!.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

      expect(description, <String>[
        'gestures: <none>',
      ]);
    });

    testWidgets('should show gestures, custom semantics and behavior', (WidgetTester tester) async {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(RawGestureDetector(
        key: key,
        behavior: HitTestBehavior.deferToChild,
        gestures: <Type, GestureRecognizerFactory>{
          TapGestureRecognizer: GestureRecognizerFactoryWithHandlers<TapGestureRecognizer>(
            () => TapGestureRecognizer(),
            (TapGestureRecognizer recognizer) {
              recognizer.onTap = () {};
            },
          ),
          LongPressGestureRecognizer: GestureRecognizerFactoryWithHandlers<LongPressGestureRecognizer>(
            () => LongPressGestureRecognizer(),
            (LongPressGestureRecognizer recognizer) {
              recognizer.onLongPress = () {};
            },
          ),
        },
        semantics: _EmptySemanticsGestureDelegate(),
        child: Container(),
      ));
      key.currentState!.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

      expect(description, <String>[
        'gestures: tap, long press',
        'semantics: _EmptySemanticsGestureDelegate()',
        'behavior: deferToChild',
      ]);
    });

    testWidgets('should not show semantics when excludeFromSemantics is true', (WidgetTester tester) async {
      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      final GlobalKey key = GlobalKey();
      await tester.pumpWidget(RawGestureDetector(
        key: key,
        semantics: _EmptySemanticsGestureDelegate(),
        excludeFromSemantics: true,
        child: Container(),
      ));
      key.currentState!.debugFillProperties(builder);

      final List<String> description = builder.properties
        .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
        .map((DiagnosticsNode node) => node.toString())
        .toList();

      expect(description, <String>[
        'gestures: <none>',
        'excludeFromSemantics: true',
      ]);
    });

    group('error control test', () {
      test('constructor redundant pan and scale', () {
        late FlutterError error;
        try {
          GestureDetector(onScaleStart: (_) {}, onPanStart: (_) {});
        } on FlutterError catch (e) {
          error = e;
        } finally {
          expect(
            error.toStringDeep(),
            'FlutterError\n'
            '   Incorrect GestureDetector arguments.\n'
            '   Having both a pan gesture recognizer and a scale gesture\n'
            '   recognizer is redundant; scale is a superset of pan.\n'
            '   Just use the scale gesture recognizer.\n',
          );
          expect(error.diagnostics.last.level, DiagnosticLevel.hint);
          expect(
            error.diagnostics.last.toStringDeep(),
            equalsIgnoringHashCodes(
              'Just use the scale gesture recognizer.\n',
            ),
          );
        }
      });

      test('constructor duplicate drag recognizer', () {
        late FlutterError error;
        try {
          GestureDetector(
            onVerticalDragStart: (_) {},
            onHorizontalDragStart: (_) {},
            onPanStart: (_) {},
          );
        } on FlutterError catch (e) {
          error = e;
        } finally {
          expect(
            error.toStringDeep(),
            'FlutterError\n'
            '   Incorrect GestureDetector arguments.\n'
            '   Simultaneously having a vertical drag gesture recognizer, a\n'
            '   horizontal drag gesture recognizer, and a pan gesture recognizer\n'
            '   will result in the pan gesture recognizer being ignored, since\n'
            '   the other two will catch all drags.\n',
          );
        }
      });

      testWidgets('replaceGestureRecognizers not during layout', (WidgetTester tester) async {
        final GlobalKey<RawGestureDetectorState> key = GlobalKey<RawGestureDetectorState>();
        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: RawGestureDetector(
              key: key,
              child: const Text('Text'),
            ),
          ),
        );
        late FlutterError error;
        try {
          key.currentState!.replaceGestureRecognizers(<Type, GestureRecognizerFactory>{});
        } on FlutterError catch (e) {
          error = e;
        } finally {
          expect(error.diagnostics.last.level, DiagnosticLevel.hint);
          expect(
            error.diagnostics.last.toStringDeep(),
            equalsIgnoringHashCodes(
              'To set the gesture recognizers at other times, trigger a new\n'
              'build using setState() and provide the new gesture recognizers as\n'
              'constructor arguments to the corresponding RawGestureDetector or\n'
              'GestureDetector object.\n',
            ),
          );
          expect(
            error.toStringDeep(),
            'FlutterError\n'
            '   Unexpected call to replaceGestureRecognizers() method of\n'
            '   RawGestureDetectorState.\n'
            '   The replaceGestureRecognizers() method can only be called during\n'
            '   the layout phase.\n'
            '   To set the gesture recognizers at other times, trigger a new\n'
            '   build using setState() and provide the new gesture recognizers as\n'
            '   constructor arguments to the corresponding RawGestureDetector or\n'
            '   GestureDetector object.\n',
          );
        }
      });
    });
  });
}

class _EmptySemanticsGestureDelegate extends SemanticsGestureDelegate {
  @override
  void assignSemantics(RenderSemanticsGestureHandler renderObject) {
  }
}

/// A [TestVariant] that runs tests multiple times with different buttons.
class ButtonVariant extends TestVariant<int> {
  const ButtonVariant({
    required this.values,
    required this.descriptions,
  }) : assert(values.length != 0);

  @override
  final List<int> values;

  final Map<int, String> descriptions;

  static int button = 0;

  @override
  String describeValue(int value) {
    assert(descriptions.containsKey(value), 'Unknown button');
    return descriptions[value]!;
  }

  @override
  Future<int> setUp(int value) async {
    final int oldValue = button;
    button = value;
    return oldValue;
  }

  @override
  Future<void> tearDown(int value, int memento) async {
    button = memento;
  }
}
