// 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/material.dart';
import 'package:flutter/src/gestures/monodrag.dart';
import 'package:flutter_test/flutter_test.dart';

import 'two_dimensional_utils.dart';

Widget? _testChildBuilder(BuildContext context, ChildVicinity vicinity) {
  return SizedBox(
    height: 200,
    width: 200,
    child: Center(child: Text('C${vicinity.xIndex}:R${vicinity.yIndex}')),
  );
}

void main() {
  group('TwoDimensionalScrollView',() {
    testWidgets('asserts the axis directions do not conflict with one another', (WidgetTester tester) async {
      final List<Object> exceptions = <Object>[];
      final FlutterExceptionHandler? oldHandler = FlutterError.onError;
      FlutterError.onError = (FlutterErrorDetails details) {
        exceptions.add(details.exception);
      };
      // Horizontal wrong
      late final TwoDimensionalChildBuilderDelegate delegate1;
      addTearDown(() => delegate1.dispose());
      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          delegate: delegate1 = TwoDimensionalChildBuilderDelegate(builder: (_, __) => null),
          horizontalDetails: const ScrollableDetails.vertical(),
          // Horizontal has default const ScrollableDetails.horizontal()
        ),
      ));

      // Vertical wrong
      late final TwoDimensionalChildBuilderDelegate delegate2;
      addTearDown(() => delegate2.dispose());
      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          delegate: delegate2 = TwoDimensionalChildBuilderDelegate(builder: (_, __) => null),
          verticalDetails: const ScrollableDetails.horizontal(),
          // Horizontal has default const ScrollableDetails.horizontal()
        ),
      ));

      // Both wrong
      late final TwoDimensionalChildBuilderDelegate delegate3;
      addTearDown(() => delegate3.dispose());
      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          delegate: delegate3 = TwoDimensionalChildBuilderDelegate(builder: (_, __) => null),
          verticalDetails: const ScrollableDetails.horizontal(),
          horizontalDetails: const ScrollableDetails.vertical(),
        ),
      ));

      FlutterError.onError = oldHandler;
      expect(exceptions.length, 3);
      for (final Object exception in exceptions) {
        expect(exception, isAssertionError);
        expect((exception as AssertionError).message, contains('are not Axis'));
      }
    }, variant: TargetPlatformVariant.all());

    testWidgets('ScrollableDetails.controller can set initial scroll positions, modify within bounds', (WidgetTester tester) async {
      final ScrollController verticalController = ScrollController(initialScrollOffset: 100);
      addTearDown(verticalController.dispose);
      final ScrollController horizontalController = ScrollController(initialScrollOffset: 50);
      addTearDown(horizontalController.dispose);
      late final TwoDimensionalChildBuilderDelegate delegate;
      addTearDown(() => delegate.dispose());

      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          verticalDetails: ScrollableDetails.vertical(controller: verticalController),
          horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
          delegate: delegate = TwoDimensionalChildBuilderDelegate(
            builder: _testChildBuilder,
            maxXIndex: 99,
            maxYIndex: 99,
          ),
        ),
      ));
      await tester.pumpAndSettle();

      expect(verticalController.position.pixels, 100);
      expect(verticalController.position.maxScrollExtent, 19400);
      expect(horizontalController.position.pixels, 50);
      expect(horizontalController.position.maxScrollExtent, 19200);

      verticalController.jumpTo(verticalController.position.maxScrollExtent);
      horizontalController.jumpTo(horizontalController.position.maxScrollExtent);
      await tester.pump();

      expect(verticalController.position.pixels, 19400);
      expect(horizontalController.position.pixels, 19200);

      // Out of bounds
      verticalController.jumpTo(verticalController.position.maxScrollExtent + 100);
      horizontalController.jumpTo(horizontalController.position.maxScrollExtent + 100);
      // Account for varying scroll physics for different platforms (overscroll)
      await tester.pumpAndSettle();

      expect(verticalController.position.pixels, 19400);
      expect(horizontalController.position.pixels, 19200);
    }, variant: TargetPlatformVariant.all());

    testWidgets('Properly assigns the PrimaryScrollController to the main axis on the correct platform', (WidgetTester tester) async {
      late ScrollController controller;
      Widget buildForPrimaryScrollController({
        bool? explicitPrimary,
        Axis mainAxis = Axis.vertical,
        bool addControllerConflict = false,
      }) {
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        return MaterialApp(
          home: PrimaryScrollController(
            controller: controller,
            child: SimpleBuilderTableView(
              mainAxis: mainAxis,
              primary: explicitPrimary,
              verticalDetails: ScrollableDetails.vertical(
                controller: addControllerConflict && mainAxis == Axis.vertical
                  ? verticalController
                  : null
              ),
              horizontalDetails: ScrollableDetails.horizontal(
                controller: addControllerConflict && mainAxis == Axis.horizontal
                  ? horizontalController
                  : null
              ),
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                builder: _testChildBuilder,
                maxXIndex: 99,
                maxYIndex: 99,
              ),
            ),
          ),
        );
      }

      // Horizontal default - horizontal never automatically adopts PSC
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        mainAxis: Axis.horizontal,
      ));
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isFalse);
      }

      // Horizontal explicitly true
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        mainAxis: Axis.horizontal,
        explicitPrimary: true,
      ));
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
        // Primary explicitly true is always adopted.
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isTrue);
          expect(controller.position.axis, Axis.horizontal);
      }

      // Horizontal explicitly false
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        mainAxis: Axis.horizontal,
        explicitPrimary: false,
      ));
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
      // Primary explicitly false is never adopted.
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isFalse);
      }

      // Vertical default
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController());
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
      // Mobile platforms inherit the PSC without explicitly setting
      // primary
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
          expect(controller.hasClients, isTrue);
          expect(controller.position.axis, Axis.vertical);
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isFalse);
      }

      // Vertical explicitly true
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        explicitPrimary: true,
      ));
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
        // Primary explicitly true is always adopted.
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isTrue);
          expect(controller.position.axis, Axis.vertical);
      }

      // Vertical explicitly false
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        explicitPrimary: false,
      ));
      await tester.pumpAndSettle();

      switch (defaultTargetPlatform) {
      // Primary explicitly false is never adopted.
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(controller.hasClients, isFalse);
      }

      // Assertions
      final List<Object> exceptions = <Object>[];
      final FlutterExceptionHandler? oldHandler = FlutterError.onError;
      FlutterError.onError = (FlutterErrorDetails details) {
        exceptions.add(details.exception);
      };
      // Vertical asserts ScrollableDetails.controller has not been provided if
      // primary is explicitly set
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        explicitPrimary: true,
        addControllerConflict: true,
      ));
      expect(exceptions.length, 1);
      expect(exceptions[0], isAssertionError);
      expect(
        (exceptions[0] as AssertionError).message,
        contains('TwoDimensionalScrollView.primary was explicitly set to true'),
      );
      exceptions.clear();

      // Horizontal asserts ScrollableDetails.controller has not been provided
      // if primary is explicitly set true
      controller = ScrollController();
      addTearDown(controller.dispose);
      await tester.pumpWidget(buildForPrimaryScrollController(
        mainAxis: Axis.horizontal,
        explicitPrimary: true,
        addControllerConflict: true,
      ));
      expect(exceptions.length, 1);
      expect(exceptions[0], isAssertionError);
      expect(
        (exceptions[0] as AssertionError).message,
        contains('TwoDimensionalScrollView.primary was explicitly set to true'),
      );
      FlutterError.onError = oldHandler;
    }, variant: TargetPlatformVariant.all());

    testWidgets('TwoDimensionalScrollable receives the correct details from TwoDimensionalScrollView', (WidgetTester tester) async {
      late BuildContext capturedContext;
      // Default
      late final TwoDimensionalChildBuilderDelegate delegate1;
      addTearDown(() => delegate1.dispose());
      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          delegate: delegate1 = TwoDimensionalChildBuilderDelegate(
            builder: (BuildContext context, ChildVicinity vicinity) {
              capturedContext = context;
              return Text(vicinity.toString());
            },
          ),
        ),
      ));
      await tester.pumpAndSettle();
      TwoDimensionalScrollableState scrollable = TwoDimensionalScrollable.of(
        capturedContext,
      );
      expect(scrollable.widget.verticalDetails.direction, AxisDirection.down);
      expect(scrollable.widget.horizontalDetails.direction, AxisDirection.right);
      expect(scrollable.widget.diagonalDragBehavior, DiagonalDragBehavior.none);
      expect(scrollable.widget.dragStartBehavior, DragStartBehavior.start);

      // Customized
      late final TwoDimensionalChildBuilderDelegate delegate2;
      addTearDown(() => delegate2.dispose());
      await tester.pumpWidget(MaterialApp(
        home: SimpleBuilderTableView(
          verticalDetails: const ScrollableDetails.vertical(reverse: true),
          horizontalDetails: const ScrollableDetails.horizontal(reverse: true),
          diagonalDragBehavior: DiagonalDragBehavior.weightedContinuous,
          dragStartBehavior: DragStartBehavior.down,
          delegate: delegate2 = TwoDimensionalChildBuilderDelegate(
            builder: _testChildBuilder,
          ),
        ),
      ));
      await tester.pumpAndSettle();
      scrollable = TwoDimensionalScrollable.of(capturedContext);
      expect(scrollable.widget.verticalDetails.direction, AxisDirection.up);
      expect(scrollable.widget.horizontalDetails.direction, AxisDirection.left);
      expect(scrollable.widget.diagonalDragBehavior, DiagonalDragBehavior.weightedContinuous);
      expect(scrollable.widget.dragStartBehavior, DragStartBehavior.down);
    }, variant: TargetPlatformVariant.all());

    testWidgets('TwoDimensionalScrollable with hitTestBehavior.translucent lets widgets underneath catch the hit', (WidgetTester tester) async {
      bool tapped = false;
      final Key key = UniqueKey();
      late final TwoDimensionalChildBuilderDelegate delegate;
      addTearDown(() => delegate.dispose());
      await tester.pumpWidget(MaterialApp(
        home: Stack(
          children: <Widget>[
            Positioned.fill(
              child: GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () => tapped = true,
                child: SizedBox(key: key, height: 300),
              ),
            ),
            SimpleBuilderTableView(
              hitTestBehavior: HitTestBehavior.translucent,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                builder: (BuildContext context, ChildVicinity vicinity) {
                  return const SizedBox(width: 50, height: 50);
                },
              ),
            ),
          ],
        ),
      ));
      await tester.pumpAndSettle();
      await tester.tapAt(tester.getCenter(find.byKey(key)));
      expect(tapped, isTrue);
    }, variant: TargetPlatformVariant.all());

    testWidgets('Interrupt fling with tap stops scrolling', (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/133529
      final List<String> log = <String>[];
      final ScrollController verticalController = ScrollController();
      addTearDown(verticalController.dispose);
      final ScrollController horizontalController = ScrollController();
      addTearDown(horizontalController.dispose);
      late final TwoDimensionalChildBuilderDelegate delegate;
      addTearDown(() => delegate.dispose());

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: SimpleBuilderTableView(
            verticalDetails: ScrollableDetails.vertical(controller: verticalController),
            horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
            diagonalDragBehavior: DiagonalDragBehavior.free,
            delegate: delegate = TwoDimensionalChildBuilderDelegate(
              maxXIndex: 100,
              maxYIndex: 100,
              builder: (BuildContext context, ChildVicinity vicinity) {
                return GestureDetector(
                  onTapUp: (TapUpDetails details) {
                    log.add('Tapped: $vicinity');
                  },
                  child: Text('$vicinity'),
                );
              },
            ),
          ),
        ),
      );

      await tester.pumpAndSettle();
      expect(log, equals(<String>[]));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Tap once
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Fling the scrollview to get it scrolling, verify that no tap occurs.
      await tester.fling(find.byType(TwoDimensionalScrollable), const Offset(0.0, -200.0), 2000.0);
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, greaterThan(170.0));
      double unchangedOffset = verticalController.position.pixels;
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity!.isScrolling, isTrue);
      expect(horizontalController.position.activity!.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, greaterThan(1500));
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Tap to stop the scroll movement, this should stop the fling but not tap anything
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, unchangedOffset);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Another tap.
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, <String>['Tapped: (xIndex: 0, yIndex: 0)', 'Tapped: (xIndex: 0, yIndex: 0)']);
      expect(verticalController.position.pixels, unchangedOffset);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      log.clear();
      verticalController.jumpTo(0.0);
      await tester.pump();
      // Fling off in the other direction now ----------------------------------
      expect(log, equals(<String>[]));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Tap once
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Fling the scrollview to get it scrolling, verify that no tap occurs.
      await tester.fling(find.byType(TwoDimensionalScrollable), const Offset(-200.0, 0.0), 2000.0);
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(horizontalController.position.pixels, greaterThan(170.0));
      unchangedOffset = horizontalController.position.pixels;
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.activity!.isScrolling, isTrue);
      expect(verticalController.position.activity!.isScrolling, isFalse);
      expect(horizontalController.position.activity!.velocity, greaterThan(1500));
      expect(verticalController.position.activity!.velocity, 0.0);

      // Tap to stop the scroll movement, this should stop the fling but not tap anything
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(horizontalController.position.pixels, unchangedOffset);
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity!.velocity, 0.0);
      expect(verticalController.position.activity!.velocity, 0.0);

      // Another tap.
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, <String>['Tapped: (xIndex: 0, yIndex: 0)', 'Tapped: (xIndex: 0, yIndex: 0)']);
      expect(horizontalController.position.pixels, unchangedOffset);
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity!.velocity, 0.0);
      expect(verticalController.position.activity!.velocity, 0.0);
    }, variant: TargetPlatformVariant.all());

    testWidgets('Fling, wait to stop and tap', (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/133529
      final List<String> log = <String>[];
      final ScrollController verticalController = ScrollController();
      addTearDown(verticalController.dispose);
      final ScrollController horizontalController = ScrollController();
      addTearDown(horizontalController.dispose);
      late final TwoDimensionalChildBuilderDelegate delegate;
      addTearDown(() => delegate.dispose());

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: SimpleBuilderTableView(
            verticalDetails: ScrollableDetails.vertical(controller: verticalController),
            horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
            diagonalDragBehavior: DiagonalDragBehavior.free,
            delegate: delegate = TwoDimensionalChildBuilderDelegate(
              maxXIndex: 100,
              maxYIndex: 100,
              builder: (BuildContext context, ChildVicinity vicinity) {
                return GestureDetector(
                  onTapUp: (TapUpDetails details) {
                    log.add('Tapped: $vicinity');
                  },
                  child: Text('$vicinity'),
                );
              },
            ),
          ),
        ),
      );

      await tester.pumpAndSettle();
      expect(log, equals(<String>[]));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Tap once
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, 0.0);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Fling the scrollview to get it scrolling, verify that no tap occurs.
      await tester.fling(find.byType(TwoDimensionalScrollable), const Offset(0.0, -200.0), 2000.0);
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, greaterThan(170.0));
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity!.isScrolling, isTrue);
      expect(horizontalController.position.activity!.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, greaterThan(1500));
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Wait for the fling to finish.
      await tester.pumpAndSettle();
      expect(log, equals(<String>['Tapped: (xIndex: 0, yIndex: 0)']));
      expect(verticalController.position.pixels, greaterThan(800.0));
      final double unchangedOffset = verticalController.position.pixels;
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity!.velocity, 0.0);
      expect(horizontalController.position.activity!.velocity, 0.0);

      // Another tap.
      await tester.tap(find.byType(TwoDimensionalScrollable));
      await tester.pump(const Duration(milliseconds: 50));
      expect(log, <String>['Tapped: (xIndex: 0, yIndex: 0)', 'Tapped: (xIndex: 0, yIndex: 4)']);
      expect(horizontalController.position.pixels, 0.0);
      expect(verticalController.position.pixels, unchangedOffset);
      expect(horizontalController.position.activity?.isScrolling, isFalse);
      expect(verticalController.position.activity?.isScrolling, isFalse);
      expect(horizontalController.position.activity!.velocity, 0.0);
      expect(verticalController.position.activity!.velocity, 0.0);
    });

    group('Can drag horizontally when there is not enough vertical content', () {
      testWidgets('DiagonalDragBehavior.free', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.free,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 20,
                maxYIndex: 1,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 0.0);
        expect(horizontalController.position.maxScrollExtent, 3400.0);
        // Fling vertically, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling horizontally, the horizontal position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, greaterThan(840.0));
      });

      testWidgets('DiagonalDragBehavior.weightedEvent', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.weightedEvent,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 20,
                maxYIndex: 1,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 0.0);
        expect(horizontalController.position.maxScrollExtent, 3400.0);
        // Fling vertically, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling horizontally, the horizontal position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, greaterThan(840.0));
      });

      testWidgets('DiagonalDragBehavior.weightedContinuous', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.weightedContinuous,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 20,
                maxYIndex: 1,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 0.0);
        expect(horizontalController.position.maxScrollExtent, 3400.0);
        // Fling vertically, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling horizontally, the horizontal position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, greaterThan(840.0));
      });
    });

    group('Can drag vertically when there is not enough horizontal content', () {
      testWidgets('DiagonalDragBehavior.free', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.free,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 1,
                maxYIndex: 20,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 3600.0);
        expect(horizontalController.position.maxScrollExtent, 0.0);
        // Fling horizontally, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling vertically, the vertical position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, greaterThan(840.0));
        expect(horizontalController.position.pixels, 0.0);
      });

      testWidgets('DiagonalDragBehavior.weightedEvent', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.weightedEvent,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 1,
                maxYIndex: 20,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 3600.0);
        expect(horizontalController.position.maxScrollExtent, 0.0);
        // Fling horizontally, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling vertically, the vertical position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, greaterThan(840.0));
        expect(horizontalController.position.pixels, 0.0);
      });

      testWidgets('DiagonalDragBehavior.weightedContinuous', (WidgetTester tester) async {
        // Regression test for https://github.com/flutter/flutter/issues/144982
        final ScrollController verticalController = ScrollController();
        addTearDown(verticalController.dispose);
        final ScrollController horizontalController = ScrollController();
        addTearDown(horizontalController.dispose);
        late final TwoDimensionalChildBuilderDelegate delegate;
        addTearDown(() => delegate.dispose());

        await tester.pumpWidget(
          Directionality(
            textDirection: TextDirection.ltr,
            child: SimpleBuilderTableView(
              verticalDetails: ScrollableDetails.vertical(controller: verticalController),
              horizontalDetails: ScrollableDetails.horizontal(controller: horizontalController),
              diagonalDragBehavior: DiagonalDragBehavior.weightedContinuous,
              delegate: delegate = TwoDimensionalChildBuilderDelegate(
                maxXIndex: 1,
                maxYIndex: 20,
                builder: _testChildBuilder,
              ),
            ),
          ),
        );

        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        expect(verticalController.position.maxScrollExtent, 3600.0);
        expect(horizontalController.position.maxScrollExtent, 0.0);
        // Fling horizontally, nothing should happen.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(-200.0, 0.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, 0.0);
        expect(horizontalController.position.pixels, 0.0);
        // Fling vertically, the vertical position should change.
        await tester.fling(
          find.byType(TwoDimensionalScrollable),
          const Offset(0.0, -200.0),
          2000.0,
        );
        await tester.pumpAndSettle();
        expect(verticalController.position.pixels, greaterThan(840.0));
        expect(horizontalController.position.pixels, 0.0);
      });
    });
  });
}
