// 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 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart' show DragStartBehavior;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/rendering_tester.dart' show TestClipPaintingContext;

class _CustomPhysics extends ClampingScrollPhysics {
  const _CustomPhysics({ super.parent });

  @override
  _CustomPhysics applyTo(ScrollPhysics? ancestor) {
    return _CustomPhysics(parent: buildParent(ancestor));
  }

  @override
  Simulation createBallisticSimulation(ScrollMetrics position, double dragVelocity) {
    return ScrollSpringSimulation(spring, 1000.0, 1000.0, 1000.0);
  }
}

Widget buildTest({
  ScrollController? controller,
  String title = 'TTTTTTTT',
  Key? key,
  bool expanded = true,
}) {
  return Localizations(
    locale: const Locale('en', 'US'),
    delegates: const <LocalizationsDelegate<dynamic>>[
      DefaultMaterialLocalizations.delegate,
      DefaultWidgetsLocalizations.delegate,
    ],
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: MediaQuery(
        data: const MediaQueryData(),
        child: Scaffold(
          drawerDragStartBehavior: DragStartBehavior.down,
          body: DefaultTabController(
            length: 4,
            child: NestedScrollView(
              key: key,
              dragStartBehavior: DragStartBehavior.down,
              controller: controller,
              headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                return <Widget>[
                  SliverAppBar(
                    title: Text(title),
                    pinned: true,
                    expandedHeight: expanded ? 200.0 : 0.0,
                    forceElevated: innerBoxIsScrolled,
                    bottom: const TabBar(
                      tabs: <Tab>[
                        Tab(text: 'AA'),
                        Tab(text: 'BB'),
                        Tab(text: 'CC'),
                        Tab(text: 'DD'),
                      ],
                    ),
                  ),
                ];
              },
              body: TabBarView(
                children: <Widget>[
                  ListView(
                    children: const <Widget>[
                      SizedBox(
                        height: 300.0,
                        child: Text('aaa1'),
                      ),
                      SizedBox(
                        height: 200.0,
                        child: Text('aaa2'),
                      ),
                      SizedBox(
                        height: 100.0,
                        child: Text('aaa3'),
                      ),
                      SizedBox(
                        height: 50.0,
                        child: Text('aaa4'),
                      ),
                    ],
                  ),
                  ListView(
                    dragStartBehavior: DragStartBehavior.down,
                    children: const <Widget>[
                      SizedBox(
                        height: 100.0,
                        child: Text('bbb1'),
                      ),
                    ],
                  ),
                  const Center(child: Text('ccc1')),
                  ListView(
                    dragStartBehavior: DragStartBehavior.down,
                    children: const <Widget>[
                      SizedBox(
                        height: 10000.0,
                        child: Text('ddd1'),
                      ),
                    ],
                  ),
                ],
              ),
            ),
          ),
        ),
      ),
    ),
  );
}

void main() {
  testWidgets('ScrollDirection test', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/107101
    final List<ScrollDirection> receivedResult = <ScrollDirection>[];
    const List<ScrollDirection> expectedReverseResult = <ScrollDirection>[ScrollDirection.reverse, ScrollDirection.idle];
    const List<ScrollDirection> expectedForwardResult = <ScrollDirection>[ScrollDirection.forward, ScrollDirection.idle];

    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: NotificationListener<UserScrollNotification>(
          onNotification: (UserScrollNotification notification) {
            if (notification.depth != 1) {
              return true;
            }
            receivedResult.add(notification.direction);
            return true;
          },
          child: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[
              const SliverAppBar(
                expandedHeight: 250.0,
                pinned: true,
              ),
            ],
            body: ListView.builder(
              padding: const EdgeInsets.all(8),
              itemCount: 30,
              itemBuilder: (BuildContext context, int index) {
                return SizedBox(
                  height: 50,
                  child: Center(child: Text('Item $index')),
                );
              },
            ),
          ),
        ),
      ),
    ));

    // Fling down to trigger ballistic activity
    await tester.fling(find.text('Item 3'), const Offset(0.0, -250.0), 10000.0);
    await tester.pumpAndSettle();

    expect(receivedResult, expectedReverseResult);

    receivedResult.clear();

    // Drag forward, without ballistic activity
    await tester.drag(find.text('Item 29'), const Offset(0.0, 20.0));
    await tester.pump();

    expect(receivedResult, expectedForwardResult);
  });

  testWidgets('NestedScrollView respects clipBehavior', (WidgetTester tester) async {
    Widget build(NestedScrollView nestedScrollView) {
      return Localizations(
        locale: const Locale('en', 'US'),
        delegates: const <LocalizationsDelegate<dynamic>>[
          DefaultMaterialLocalizations.delegate,
          DefaultWidgetsLocalizations.delegate,
        ],
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: nestedScrollView,
          ),
        ),
      );
    }

    await tester.pumpWidget(build(
      NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[const SliverAppBar()],
        body: Container(height: 2000.0),
      ),
    ));

    // 1st, check that the render object has received the default clip behavior.
    final RenderNestedScrollViewViewport renderObject = tester.allRenderObjects.whereType<RenderNestedScrollViewViewport>().first;
    expect(renderObject.clipBehavior, equals(Clip.hardEdge));

    // 2nd, check that the painting context has received the default clip behavior.
    final TestClipPaintingContext context = TestClipPaintingContext();
    renderObject.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.hardEdge));

    // 3rd, pump a new widget to check that the render object can update its clip behavior.
    await tester.pumpWidget(build(
        NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[const SliverAppBar()],
          body: Container(height: 2000.0),
          clipBehavior: Clip.antiAlias,
        ),
    ));
    expect(renderObject.clipBehavior, equals(Clip.antiAlias));

    // 4th, check that a non-default clip behavior can be sent to the painting context.
    renderObject.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.antiAlias));
  });

  testWidgets('NestedScrollView overscroll and release and hold', (WidgetTester tester) async {
    await tester.pumpWidget(buildTest());
    expect(find.text('aaa2'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 250));
    final Offset point1 = tester.getCenter(find.text('aaa1'));
    if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS) {
      await tester.dragFrom(point1, const Offset(0.0, 400.0));
    }
    else {
      await tester.dragFrom(point1, const Offset(0.0, 200.0));
    }
    await tester.pump();
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );
    await tester.flingFrom(point1, const Offset(0.0, -80.0), 50000.0);
    await tester.pump(const Duration(milliseconds: 20));
    final Offset point2 = tester.getCenter(find.text('aaa1'));
    expect(point2.dy, greaterThan(point1.dy));
    expect(tester.renderObject<RenderBox>(find.byType(AppBar)).size.height, 200.0);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('NestedScrollView overscroll and release and hold', (WidgetTester tester) async {
    await tester.pumpWidget(buildTest());
    expect(find.text('aaa2'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 250));
    final Offset point = tester.getCenter(find.text('aaa1'));
    if (debugDefaultTargetPlatformOverride == TargetPlatform.macOS) {
      await tester.flingFrom(point, const Offset(0.0, 200.0), 15000.0);
    }
    else {
      await tester.flingFrom(point, const Offset(0.0, 200.0), 5000.0);
    }
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('aaa2'), findsNothing);
    final TestGesture gesture1 = await tester.startGesture(point);
    await tester.pump(const Duration(milliseconds: 5000));
    expect(find.text('aaa2'), findsNothing);
    await gesture1.moveBy(const Offset(0.0, 50.0));
    await tester.pump(const Duration(milliseconds: 10));
    await tester.pump(const Duration(milliseconds: 10));
    expect(find.text('aaa2'), findsNothing);
    await tester.pump(const Duration(milliseconds: 1000));
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('NestedScrollView overscroll and release', (WidgetTester tester) async {
    await tester.pumpWidget(buildTest());
    expect(find.text('aaa2'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 500));
    final TestGesture gesture1 = await tester.startGesture(
      tester.getCenter(find.text('aaa1')),
    );
    await gesture1.moveBy(const Offset(0.0, 200.0));
    await tester.pumpAndSettle();
    expect(find.text('aaa2'), findsNothing);
    await tester.pump(const Duration(seconds: 1));
    await gesture1.up();
    await tester.pumpAndSettle();
    expect(find.text('aaa2'), findsOneWidget);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('NestedScrollView', (WidgetTester tester) async {
    await tester.pumpWidget(buildTest());
    expect(find.text('aaa2'), findsOneWidget);
    expect(find.text('aaa3'), findsNothing);
    expect(find.text('bbb1'), findsNothing);
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );

    await tester.drag(find.text('AA'), const Offset(0.0, -20.0));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      180.0,
    );

    await tester.drag(find.text('AA'), const Offset(0.0, -20.0));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      160.0,
    );

    await tester.drag(find.text('AA'), const Offset(0.0, -20.0));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      140.0,
    );

    expect(find.text('aaa4'), findsNothing);
    await tester.pump(const Duration(milliseconds: 250));
    await tester.fling(find.text('AA'), const Offset(0.0, -50.0), 10000.0);
    await tester.pumpAndSettle(const Duration(milliseconds: 250));
    expect(find.text('aaa4'), findsOneWidget);

    final double minHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
    expect(minHeight, lessThan(140.0));

    await tester.pump(const Duration(milliseconds: 250));
    await tester.tap(find.text('BB'));
    await tester.pumpAndSettle(const Duration(milliseconds: 250));
    expect(find.text('aaa4'), findsNothing);
    expect(find.text('bbb1'), findsOneWidget);

    await tester.pump(const Duration(milliseconds: 250));
    await tester.tap(find.text('CC'));
    await tester.pumpAndSettle(const Duration(milliseconds: 250));
    expect(find.text('bbb1'), findsNothing);
    expect(find.text('ccc1'), findsOneWidget);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      minHeight,
    );

    await tester.pump(const Duration(milliseconds: 250));
    await tester.fling(find.text('AA'), const Offset(0.0, 50.0), 10000.0);
    await tester.pumpAndSettle(const Duration(milliseconds: 250));
    expect(find.text('ccc1'), findsOneWidget);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );
  });

  testWidgets('NestedScrollView with a ScrollController', (WidgetTester tester) async {
    final ScrollController controller = ScrollController(
      initialScrollOffset: 50.0,
    );

    late double scrollOffset;
    controller.addListener(() {
      scrollOffset = controller.offset;
    });

    await tester.pumpWidget(buildTest(controller: controller));
    expect(controller.position.minScrollExtent, 0.0);
    expect(controller.position.pixels, 50.0);
    expect(controller.position.maxScrollExtent, 200.0);

    // The appbar's expandedHeight - initialScrollOffset = 150.
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      150.0,
    );

    // Fully expand the appbar by scrolling (no animation) to 0.0.
    controller.jumpTo(0.0);
    await tester.pumpAndSettle();
    expect(scrollOffset, 0.0);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );

    // Scroll back to 50.0 animating over 100ms.
    controller.animateTo(
      50.0,
      duration: const Duration(milliseconds: 100),
      curve: Curves.linear,
    );
    await tester.pump();
    await tester.pump();
    expect(scrollOffset, 0.0);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );
    await tester.pump(const Duration(milliseconds: 50)); // 50ms - halfway to scroll offset = 50.0.
    expect(scrollOffset, 25.0);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      175.0,
    );
    await tester.pump(const Duration(milliseconds: 50)); // 100ms - all the way to scroll offset = 50.0.
    expect(scrollOffset, 50.0);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      150.0,
    );

    // Scroll to the end, (we're not scrolling to the end of the list that contains aaa1,
    // just to the end of the outer scrollview). Verify that the first item in each tab
    // is still visible.
    controller.jumpTo(controller.position.maxScrollExtent);
    await tester.pumpAndSettle();
    expect(scrollOffset, 200.0);
    expect(find.text('aaa1'), findsOneWidget);

    await tester.tap(find.text('BB'));
    await tester.pumpAndSettle();
    expect(find.text('bbb1'), findsOneWidget);

    await tester.tap(find.text('CC'));
    await tester.pumpAndSettle();
    expect(find.text('ccc1'), findsOneWidget);

    await tester.tap(find.text('DD'));
    await tester.pumpAndSettle();
    expect(find.text('ddd1'), findsOneWidget);
  });

  testWidgets('Three NestedScrollViews with one ScrollController', (WidgetTester tester) async {
    final TrackingScrollController controller = TrackingScrollController();
    expect(controller.mostRecentlyUpdatedPosition, isNull);
    expect(controller.initialScrollOffset, 0.0);

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: PageView(
        children: <Widget>[
          buildTest(controller: controller, title: 'Page0'),
          buildTest(controller: controller, title: 'Page1'),
          buildTest(controller: controller, title: 'Page2'),
        ],
      ),
    ));

    // Initially Page0 is visible and Page0's appbar is fully expanded (height = 200.0).
    expect(find.text('Page0'), findsOneWidget);
    expect(find.text('Page1'), findsNothing);
    expect(find.text('Page2'), findsNothing);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );

    // A scroll collapses Page0's appbar to 150.0.
    controller.jumpTo(50.0);
    await tester.pumpAndSettle();
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      150.0,
    );

    // Fling to Page1. Page1's appbar height is the same as the appbar for Page0.
    await tester.fling(find.text('Page0'), const Offset(-100.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(find.text('Page0'), findsNothing);
    expect(find.text('Page1'), findsOneWidget);
    expect(find.text('Page2'), findsNothing);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      150.0,
    );

    // Expand Page1's appbar and then fling to Page2. Page2's appbar appears
    // fully expanded.
    controller.jumpTo(0.0);
    await tester.pumpAndSettle();
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );
    await tester.fling(find.text('Page1'), const Offset(-100.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(find.text('Page0'), findsNothing);
    expect(find.text('Page1'), findsNothing);
    expect(find.text('Page2'), findsOneWidget);
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );
  });

  testWidgets('NestedScrollViews with custom physics', (WidgetTester tester) async {
    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: Localizations(
        locale: const Locale('en', 'US'),
        delegates: const <LocalizationsDelegate<dynamic>>[
          DefaultMaterialLocalizations.delegate,
          DefaultWidgetsLocalizations.delegate,
        ],
        child: MediaQuery(
          data: const MediaQueryData(),
          child: NestedScrollView(
            physics: const _CustomPhysics(),
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                const SliverAppBar(
                  floating: true,
                  title: Text('AA'),
                ),
              ];
            },
            body: Container(),
          ),
        ),
      ),
    ));
    expect(find.text('AA'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 500));
    final Offset point1 = tester.getCenter(find.text('AA'));
    await tester.dragFrom(point1, const Offset(0.0, 200.0));
    await tester.pump(const Duration(milliseconds: 20));
    final Offset point2 = tester.getCenter(find.text(
      'AA',
      skipOffstage: false,
    ));
    expect(point1.dy, greaterThan(point2.dy));
  });

  testWidgets('NestedScrollView and internal scrolling', (WidgetTester tester) async {
    debugDisableShadows = false;
    const List<String> tabs = <String>['Hello', 'World'];
    int buildCount = 0;
    await tester.pumpWidget(
      MaterialApp(home: Material(child:
        // THE FOLLOWING SECTION IS FROM THE NestedScrollView DOCUMENTATION
        // (EXCEPT FOR THE CHANGES TO THE buildCount COUNTER)
        DefaultTabController(
          length: tabs.length, // This is the number of tabs.
          child: NestedScrollView(
            dragStartBehavior: DragStartBehavior.down,
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              buildCount += 1; // THIS LINE IS NOT IN THE ORIGINAL -- ADDED FOR TEST
              // These are the slivers that show up in the "outer" scroll view.
              return <Widget>[
                SliverOverlapAbsorber(
                  // This widget takes the overlapping behavior of the
                  // SliverAppBar, and redirects it to the SliverOverlapInjector
                  // below. If it is missing, then it is possible for the nested
                  // "inner" scroll view below to end up under the SliverAppBar
                  // even when the inner scroll view thinks it has not been
                  // scrolled. This is not necessary if the
                  // "headerSliverBuilder" only builds widgets that do not
                  // overlap the next sliver.
                  handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  sliver: SliverAppBar(
                    title: const Text('Books'), // This is the title in the app bar.
                    pinned: true,
                    expandedHeight: 150.0,
                    // The "forceElevated" property causes the SliverAppBar to
                    // show a shadow. The "innerBoxIsScrolled" parameter is true
                    // when the inner scroll view is scrolled beyond its "zero"
                    // point, i.e. when it appears to be scrolled below the
                    // SliverAppBar. Without this, there are cases where the
                    // shadow would appear or not appear inappropriately,
                    // because the SliverAppBar is not actually aware of the
                    // precise position of the inner scroll views.
                    forceElevated: innerBoxIsScrolled,
                    bottom: TabBar(
                      // These are the widgets to put in each tab in the tab
                      // bar.
                      tabs: tabs.map<Widget>((String name) => Tab(text: name)).toList(),
                      dragStartBehavior: DragStartBehavior.down,
                    ),
                  ),
                ),
              ];
            },
            body: TabBarView(
              dragStartBehavior: DragStartBehavior.down,
              // These are the contents of the tab views, below the tabs.
              children: tabs.map<Widget>((String name) {
                return SafeArea(
                  top: false,
                  bottom: false,
                  child: Builder(
                    // This Builder is needed to provide a BuildContext that is
                    // "inside" the NestedScrollView, so that
                    // sliverOverlapAbsorberHandleFor() can find the
                    // NestedScrollView.
                    builder: (BuildContext context) {
                      return CustomScrollView(
                        // The "controller" and "primary" members should be left
                        // unset, so that the NestedScrollView can control this
                        // inner scroll view.
                        // If the "controller" property is set, then this scroll
                        // view will not be associated with the
                        // NestedScrollView. The PageStorageKey should be unique
                        // to this ScrollView; it allows the list to remember
                        // its scroll position when the tab view is not on the
                        // screen.
                        key: PageStorageKey<String>(name),
                        dragStartBehavior: DragStartBehavior.down,
                        slivers: <Widget>[
                          SliverOverlapInjector(
                            // This is the flip side of the
                            // SliverOverlapAbsorber above.
                            handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                          ),
                          SliverPadding(
                            padding: const EdgeInsets.all(8.0),
                            // In this example, the inner scroll view has
                            // fixed-height list items, hence the use of
                            // SliverFixedExtentList. However, one could use any
                            // sliver widget here, e.g. SliverList or
                            // SliverGrid.
                            sliver: SliverFixedExtentList(
                              // The items in this example are fixed to 48
                              // pixels high. This matches the Material Design
                              // spec for ListTile widgets.
                              itemExtent: 48.0,
                              delegate: SliverChildBuilderDelegate(
                                (BuildContext context, int index) {
                                  // This builder is called for each child.
                                  // In this example, we just number each list
                                  // item.
                                  return ListTile(
                                    title: Text('Item $index'),
                                  );
                                },
                                // The childCount of the
                                // SliverChildBuilderDelegate specifies how many
                                // children this inner list has. In this
                                // example, each tab has a list of exactly 30
                                // items, but this is arbitrary.
                                childCount: 30,
                              ),
                            ),
                          ),
                        ],
                      );
                    },
                  ),
                );
              }).toList(),
            ),
          ),
        ),
        // END
      )),
    );

    Object? dfsFindPhysicalLayer(RenderObject object) {
      expect(object, isNotNull);
      if (object is RenderPhysicalModel || object is RenderPhysicalShape) {
        return object;
      }
      final List<RenderObject> children = <RenderObject>[];
      object.visitChildren(children.add);
      for (final RenderObject child in children) {
        final Object? result = dfsFindPhysicalLayer(child);
        if (result != null) {
          return result;
        }
      }
      return null;
    }

    final RenderObject nestedScrollViewLayer = find.byType(NestedScrollView).evaluate().first.renderObject!;
    void checkPhysicalLayer({required double elevation}) {
      final dynamic physicalModel = dfsFindPhysicalLayer(nestedScrollViewLayer);
      expect(physicalModel, isNotNull);
      // ignore: avoid_dynamic_calls
      expect(physicalModel.elevation, equals(elevation));
    }

    int expectedBuildCount = 0;
    expectedBuildCount += 1;
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 18'), findsNothing);
    checkPhysicalLayer(elevation: 0);
    // scroll down
    final TestGesture gesture0 = await tester.startGesture(
      tester.getCenter(find.text('Item 2')),
    );
    await gesture0.moveBy(const Offset(0.0, -120.0)); // tiny bit more than the pinned app bar height (56px * 2)
    await tester.pump();
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 18'), findsNothing);
    await gesture0.up();
    await tester.pump(const Duration(milliseconds: 1)); // start shadow animation
    expectedBuildCount += 1;
    expect(buildCount, expectedBuildCount);
    await tester.pump(const Duration(milliseconds: 1)); // during shadow animation
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 0.00018262863159179688);
    await tester.pump(const Duration(seconds: 1)); // end shadow animation
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 4);
    // scroll down
    final TestGesture gesture1 = await tester.startGesture(
      tester.getCenter(find.text('Item 2')),
    );
    await gesture1.moveBy(const Offset(0.0, -800.0));
    await tester.pump();
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 4);
    expect(find.text('Item 2'), findsNothing);
    expect(find.text('Item 18'), findsOneWidget);
    await gesture1.up();
    await tester.pump(const Duration(seconds: 1));
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 4);
    // swipe left to bring in tap on the right
    final TestGesture gesture2 = await tester.startGesture(
      tester.getCenter(find.byType(NestedScrollView)),
    );
    await gesture2.moveBy(const Offset(-400.0, 0.0));
    await tester.pump();
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 18'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 0'), findsOneWidget);
    expect(
      tester.getTopLeft(
        find.ancestor(
          of: find.text('Item 0'),
          matching: find.byType(ListTile),
        ),
      ).dy,
      tester.getBottomLeft(find.byType(AppBar)).dy + 8.0,
    );
    checkPhysicalLayer(elevation: 4);
    await gesture2.up();
    await tester.pump(); // start sideways scroll
    await tester.pump(const Duration(seconds: 1)); // end sideways scroll, triggers shadow going away
    expect(buildCount, expectedBuildCount);
    await tester.pump(const Duration(seconds: 1)); // start shadow going away
    expectedBuildCount += 1;
    expect(buildCount, expectedBuildCount);
    await tester.pump(const Duration(seconds: 1)); // end shadow going away
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 18'), findsNothing);
    expect(find.text('Item 2'), findsOneWidget);
    checkPhysicalLayer(elevation: 0);
    await tester.pump(const Duration(seconds: 1)); // just checking we don't rebuild...
    expect(buildCount, expectedBuildCount);
    // peek left to see it's still in the right place
    final TestGesture gesture3 = await tester.startGesture(
      tester.getCenter(find.byType(NestedScrollView)),
    );
    await gesture3.moveBy(const Offset(400.0, 0.0));
    await tester.pump(); // bring the left page into view
    expect(buildCount, expectedBuildCount);
    await tester.pump(); // shadow comes back starting here
    expectedBuildCount += 1;
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 18'), findsOneWidget);
    expect(find.text('Item 2'), findsOneWidget);
    checkPhysicalLayer(elevation: 0);
    await tester.pump(const Duration(seconds: 1)); // shadow finishes coming back
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 4);
    await gesture3.moveBy(const Offset(-400.0, 0.0));
    await gesture3.up();
    await tester.pump(); // left tab view goes away
    expect(buildCount, expectedBuildCount);
    await tester.pump(); // shadow goes away starting here
    expectedBuildCount += 1;
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 4);
    await tester.pump(const Duration(seconds: 1)); // shadow finishes going away
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 0);
    // scroll back up
    final TestGesture gesture4 = await tester.startGesture(
      tester.getCenter(find.byType(NestedScrollView)),
    );
    await gesture4.moveBy(const Offset(0.0, 200.0)); // expands the appbar again
    await tester.pump();
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 2'), findsOneWidget);
    expect(find.text('Item 18'), findsNothing);
    checkPhysicalLayer(elevation: 0);
    await gesture4.up();
    await tester.pump(const Duration(seconds: 1));
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 0);
    // peek left to see it's now back at zero
    final TestGesture gesture5 = await tester.startGesture(
      tester.getCenter(find.byType(NestedScrollView)),
    );
    await gesture5.moveBy(const Offset(400.0, 0.0));
    await tester.pump(); // bring the left page into view
    await tester.pump(); // shadow would come back starting here, but there's no shadow to show
    expect(buildCount, expectedBuildCount);
    expect(find.text('Item 18'), findsNothing);
    expect(find.text('Item 2'), findsNWidgets(2));
    checkPhysicalLayer(elevation: 0);
    await tester.pump(const Duration(seconds: 1)); // shadow would be finished coming back
    checkPhysicalLayer(elevation: 0);
    await gesture5.up();
    await tester.pump(); // right tab view goes away
    await tester.pumpAndSettle();
    expect(buildCount, expectedBuildCount);
    checkPhysicalLayer(elevation: 0);
    debugDisableShadows = true;
  });

  testWidgets('NestedScrollView and bouncing', (WidgetTester tester) async {
    // This verifies that overscroll bouncing works correctly on iOS. For
    // example, this checks that if you pull to overscroll, friction is applied;
    // it also makes sure that if you scroll back the other way, the scroll
    // positions of the inner and outer list don't have a discontinuity.
    const Key key1 = ValueKey<int>(1);
    const Key key2 = ValueKey<int>(2);
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: DefaultTabController(
            length: 1,
            child: NestedScrollView(
              dragStartBehavior: DragStartBehavior.down,
              headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                return <Widget>[
                  const SliverPersistentHeader(
                    delegate: TestHeader(key: key1),
                  ),
                ];
              },
              body: const SingleChildScrollView(
                dragStartBehavior: DragStartBehavior.down,
                child: SizedBox(
                  height: 1000.0,
                  child: Placeholder(key: key2),
                ),
              ),
            ),
          ),
        ),
      ),
    );
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    expect(
      tester.getRect(find.byKey(key2)),
      const Rect.fromLTWH(0.0, 100.0, 800.0, 1000.0),
    );
    final TestGesture gesture = await tester.startGesture(
      const Offset(10.0, 10.0),
    );
    await gesture.moveBy(const Offset(0.0, -10.0)); // scroll up
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, -10.0, 800.0, 100.0),
    );
    expect(
      tester.getRect(find.byKey(key2)),
      const Rect.fromLTWH(0.0, 90.0, 800.0, 1000.0),
    );
    await gesture.moveBy(const Offset(0.0, 10.0)); // scroll back to origin
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    expect(
      tester.getRect(find.byKey(key2)),
      const Rect.fromLTWH(0.0, 100.0, 800.0, 1000.0),
    );
    await gesture.moveBy(const Offset(0.0, 10.0)); // overscroll
    await gesture.moveBy(const Offset(0.0, 10.0)); // overscroll
    await gesture.moveBy(const Offset(0.0, 10.0)); // overscroll
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    expect(tester.getRect(find.byKey(key2)).top, greaterThan(100.0));
    expect(tester.getRect(find.byKey(key2)).top, lessThan(130.0));
    await gesture.moveBy(const Offset(0.0, -1.0)); // scroll back a little
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    expect(tester.getRect(find.byKey(key2)).top, greaterThan(100.0));
    expect(tester.getRect(find.byKey(key2)).top, lessThan(129.0));
    await gesture.moveBy(const Offset(0.0, -10.0)); // scroll back a lot
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    await gesture.moveBy(const Offset(0.0, 20.0)); // overscroll again
    await tester.pump();
    expect(
      tester.getRect(find.byKey(key1)),
      const Rect.fromLTWH(0.0, 0.0, 800.0, 100.0),
    );
    await gesture.up();
    debugDefaultTargetPlatformOverride = null;
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  group('NestedScrollViewState exposes inner and outer controllers', () {
    testWidgets('Scrolling by less than the outer extent does not scroll the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(
        key: globalKey,
        expanded: false,
      ));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 104.0);
      final double scrollExtent = appBarHeight - 50.0;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is not an expanded AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, 54.0);
      // the inner scroll controller should not have scrolled.
      expect(globalKey.currentState!.innerController.offset, 0.0);
    });

    testWidgets('Scrolling by exactly the outer extent does not scroll the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(
        key: globalKey,
        expanded: false,
      ));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 104.0);
      final double scrollExtent = appBarHeight;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is not an expanded AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, 104.0);
      // the inner scroll controller should not have scrolled.
      expect(globalKey.currentState!.innerController.offset, 0.0);
    });

    testWidgets('Scrolling by greater than the outer extent scrolls the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(
        key: globalKey,
        expanded: false,
      ));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 104.0);
      final double scrollExtent = appBarHeight + 50.0;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is not an expanded AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, appBarHeight);
      // the inner scroll controller should have scrolled equivalent to the
      // difference between the applied scrollExtent and the outer extent.
      expect(
        globalKey.currentState!.innerController.offset,
        scrollExtent - appBarHeight,
      );
    });

    testWidgets('Inertia-cancel event does not modify either position.', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(
        key: globalKey,
        expanded: false,
      ));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 104.0);
      final double scrollExtent = appBarHeight + 50.0;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is not an expanded AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, appBarHeight);
      // the inner scroll controller should have scrolled equivalent to the
      // difference between the applied scrollExtent and the outer extent.
      expect(
        globalKey.currentState!.innerController.offset,
        scrollExtent - appBarHeight,
      );

      final TestPointer testPointer = TestPointer(3, ui.PointerDeviceKind.trackpad);
      await tester.sendEventToBinding(testPointer.addPointer(
        location: Offset(0.0, appBarHeight + 1.0)
      ));
      await tester.sendEventToBinding(testPointer.scrollInertiaCancel());
      // ensure no change.
      expect(globalKey.currentState!.outerController.offset, appBarHeight);
      expect(
        globalKey.currentState!.innerController.offset,
        scrollExtent - appBarHeight,
      );
    });

    testWidgets('scrolling by less than the expanded outer extent does not scroll the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(key: globalKey));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 200.0);
      final double scrollExtent = appBarHeight - 50.0;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is an expanding AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, 150.0);
      // the inner scroll controller should not have scrolled.
      expect(globalKey.currentState!.innerController.offset, 0.0);
    });

    testWidgets('scrolling by exactly the expanded outer extent does not scroll the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(key: globalKey));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 200.0);
      final double scrollExtent = appBarHeight;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is an expanding AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, 200.0);
      // the inner scroll controller should not have scrolled.
      expect(globalKey.currentState!.innerController.offset, 0.0);
    });

    testWidgets('scrolling by greater than the expanded outer extent scrolls the inner body', (WidgetTester tester) async {
      final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
      await tester.pumpWidget(buildTest(key: globalKey));

      double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      expect(appBarHeight, 200.0);
      final double scrollExtent = appBarHeight + 50.0;
      expect(globalKey.currentState!.outerController.offset, 0.0);
      expect(globalKey.currentState!.innerController.offset, 0.0);

      // The scroll gesture should occur in the inner body, so the whole
      // scroll view is scrolled.
      final TestGesture gesture = await tester.startGesture(Offset(
        0.0,
        appBarHeight + 1.0,
      ));
      await gesture.moveBy(Offset(0.0, -scrollExtent));
      await tester.pump();

      appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;
      // This is an expanding AppBar.
      expect(appBarHeight, 104.0);
      // The outer scroll controller should show an offset of the applied
      // scrollExtent.
      expect(globalKey.currentState!.outerController.offset, 200.0);
      // the inner scroll controller should have scrolled equivalent to the
      // difference between the applied scrollExtent and the outer extent.
      expect(globalKey.currentState!.innerController.offset, 50.0);
    });

    testWidgets(
      'NestedScrollViewState.outerController should correspond to NestedScrollView.controller',
      (WidgetTester tester) async {
        final GlobalKey<NestedScrollViewState> globalKey = GlobalKey();
        final ScrollController scrollController = ScrollController();

        await tester.pumpWidget(buildTest(
          controller: scrollController,
          key: globalKey,
        ));

        // Scroll to compare offsets between controllers.
        final TestGesture gesture = await tester.startGesture(const Offset(
          0.0,
          100.0,
        ));
        await gesture.moveBy(const Offset(0.0, -100.0));
        await tester.pump();

        expect(
          scrollController.offset,
          globalKey.currentState!.outerController.offset,
        );
        expect(
          tester.widget<NestedScrollView>(find.byType(NestedScrollView)).controller!.offset,
          globalKey.currentState!.outerController.offset,
        );
      },
    );

    group('manipulating controllers when', () {
      testWidgets('outer: not scrolled, inner: not scrolled', (WidgetTester tester) async {
        final GlobalKey<NestedScrollViewState> globalKey1 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey1,
          expanded: false,
        ));
        expect(globalKey1.currentState!.outerController.position.pixels, 0.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;

        // Manipulating Inner
        globalKey1.currentState!.innerController.jumpTo(100.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );
        globalKey1.currentState!.innerController.jumpTo(0.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );

        // Reset
        final GlobalKey<NestedScrollViewState> globalKey2 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey2,
          expanded: false,
        ));
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);

        // Manipulating Outer
        globalKey2.currentState!.outerController.jumpTo(100.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
        globalKey2.currentState!.outerController.jumpTo(0.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
      });

      testWidgets('outer: not scrolled, inner: scrolled', (WidgetTester tester) async {
        final GlobalKey<NestedScrollViewState> globalKey1 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey1,
          expanded: false,
        ));
        expect(globalKey1.currentState!.outerController.position.pixels, 0.0);
        globalKey1.currentState!.innerController.position.setPixels(10.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 10.0);
        final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;

        // Manipulating Inner
        globalKey1.currentState!.innerController.jumpTo(100.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );
        globalKey1.currentState!.innerController.jumpTo(0.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );

        // Reset
        final GlobalKey<NestedScrollViewState> globalKey2 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey2,
          expanded: false,
        ));
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
        globalKey2.currentState!.innerController.position.setPixels(10.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 10.0);

        // Manipulating Outer
        globalKey2.currentState!.outerController.jumpTo(100.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
        globalKey2.currentState!.outerController.jumpTo(0.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
      });

      testWidgets('outer: scrolled, inner: not scrolled', (WidgetTester tester) async {
        final GlobalKey<NestedScrollViewState> globalKey1 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey1,
          expanded: false,
        ));
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        globalKey1.currentState!.outerController.position.setPixels(10.0);
        expect(globalKey1.currentState!.outerController.position.pixels, 10.0);
        final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;

        // Manipulating Inner
        globalKey1.currentState!.innerController.jumpTo(100.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );
        globalKey1.currentState!.innerController.jumpTo(0.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );

        // Reset
        final GlobalKey<NestedScrollViewState> globalKey2 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey2,
          expanded: false,
        ));
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        globalKey2.currentState!.outerController.position.setPixels(10.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 10.0);

        // Manipulating Outer
        globalKey2.currentState!.outerController.jumpTo(100.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
        globalKey2.currentState!.outerController.jumpTo(0.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
      });

      testWidgets('outer: scrolled, inner: scrolled', (WidgetTester tester) async {
        final GlobalKey<NestedScrollViewState> globalKey1 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey1,
          expanded: false,
        ));
        globalKey1.currentState!.innerController.position.setPixels(10.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 10.0);
        globalKey1.currentState!.outerController.position.setPixels(10.0);
        expect(globalKey1.currentState!.outerController.position.pixels, 10.0);
        final double appBarHeight = tester.renderObject<RenderBox>(find.byType(AppBar)).size.height;

        // Manipulating Inner
        globalKey1.currentState!.innerController.jumpTo(100.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 100.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );
        globalKey1.currentState!.innerController.jumpTo(0.0);
        expect(globalKey1.currentState!.innerController.position.pixels, 0.0);
        expect(
          globalKey1.currentState!.outerController.position.pixels,
          appBarHeight,
        );

        // Reset
        final GlobalKey<NestedScrollViewState> globalKey2 = GlobalKey();
        await tester.pumpWidget(buildTest(
          key: globalKey2,
          expanded: false,
        ));
        globalKey2.currentState!.innerController.position.setPixels(10.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 10.0);
        globalKey2.currentState!.outerController.position.setPixels(10.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 10.0);

        // Manipulating Outer
        globalKey2.currentState!.outerController.jumpTo(100.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 100.0);
        globalKey2.currentState!.outerController.jumpTo(0.0);
        expect(globalKey2.currentState!.innerController.position.pixels, 0.0);
        expect(globalKey2.currentState!.outerController.position.pixels, 0.0);
      });
    });
  });

  // Regression test for https://github.com/flutter/flutter/issues/39963.
  testWidgets('NestedScrollView with SliverOverlapAbsorber in or out of the first screen', (WidgetTester tester) async {
    await tester.pumpWidget(const _TestLayoutExtentIsNegative(1));
    await tester.pumpWidget(const _TestLayoutExtentIsNegative(10));
  });

  group('NestedScrollView can float outer sliver with inner scroll view:', () {
    Widget buildFloatTest({
      GlobalKey? appBarKey,
      GlobalKey? nestedKey,
      ScrollController? controller,
      bool floating = false,
      bool pinned = false,
      bool snap = false,
      bool nestedFloat = false,
      bool expanded = false,
    }) {
      return MaterialApp(
        home: Scaffold(
          body: NestedScrollView(
            key: nestedKey,
            controller: controller,
            floatHeaderSlivers: nestedFloat,
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                SliverOverlapAbsorber(
                  handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                  sliver: SliverAppBar(
                    key: appBarKey,
                    title: const Text('Test Title'),
                    floating: floating,
                    pinned: pinned,
                    snap: snap,
                    expandedHeight: expanded ? 200.0 : 0.0,
                  ),
                ),
              ];
            },
            body: Builder(
              builder: (BuildContext context) {
                return CustomScrollView(
                  slivers: <Widget>[
                    SliverOverlapInjector(handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
                    SliverFixedExtentList(
                      itemExtent: 50.0,
                      delegate: SliverChildBuilderDelegate(
                        (BuildContext context, int index) => ListTile(title: Text('Item $index')),
                        childCount: 30,
                      ),
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      );
    }

    double verifyGeometry({
      required GlobalKey key,
      required double paintExtent,
      bool extentGreaterThan = false,
      bool extentLessThan = false,
      required bool visible,
    }) {
      final RenderSliver target = key.currentContext!.findRenderObject()! as RenderSliver;
      final SliverGeometry geometry = target.geometry!;
      expect(target.parent, isA<RenderSliverOverlapAbsorber>());
      expect(geometry.visible, visible);
      if (extentGreaterThan) {
        expect(geometry.paintExtent, greaterThan(paintExtent));
      } else if (extentLessThan) {
        expect(geometry.paintExtent, lessThan(paintExtent));
      } else {
        expect(geometry.paintExtent, paintExtent);
      }
      return geometry.paintExtent;
    }

    testWidgets('float', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // We will not scroll back the same amount to indicate that we are
      // floating in before reaching the top of the inner scrollable.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -300.0));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);

      // The outer scrollable should float back in, inner should not change
      await tester.dragFrom(point1, const Offset(0.0, 50.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 50.0, visible: true);

      // Float the rest of the way in.
      await tester.dragFrom(point1, const Offset(0.0, 150.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
    });

    testWidgets('float expanded', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        nestedFloat: true,
        expanded: true,
        appBarKey: appBarKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // We will not scroll back the same amount to indicate that we are
      // floating in before reaching the top of the inner scrollable.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -300.0));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);

      // The outer scrollable should float back in, inner should not change
      // On initial float in, the app bar is collapsed.
      await tester.dragFrom(point1, const Offset(0.0, 50.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 50.0, visible: true);

      // The inner scrollable should receive leftover delta after the outer has
      // been scrolled back in fully.
      await tester.dragFrom(point1, const Offset(0.0, 200.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
    });

    testWidgets('float with pointer signal', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);

      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // We will not scroll back the same amount to indicate that we are
      // floating in before reaching the top of the inner scrollable.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);

      // The outer scrollable should float back in, inner should not change
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -50.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 50.0, visible: true);

      // Float the rest of the way in.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -150.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
    });

    testWidgets('snap with pointer signal', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        snap: true,
        appBarKey: appBarKey,
      ));

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);

      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // We will not scroll back the same amount to indicate that we are
      // snapping in before reaching the top of the inner scrollable.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);

      // The snap animation should be triggered to expand the app bar
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -30.0)));
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away a bit more to trigger the snap close animation.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 30.0)));
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(find.byType(AppBar), findsNothing);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
    });

    testWidgets('float expanded with pointer signal', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        nestedFloat: true,
        expanded: true,
        appBarKey: appBarKey,
      ));

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);

      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // We will not scroll back the same amount to indicate that we are
      // floating in before reaching the top of the inner scrollable.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);

      // The outer scrollable should float back in, inner should not change
      // On initial float in, the app bar is collapsed.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -50.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 50.0, visible: true);

      // The inner scrollable should receive leftover delta after the outer has
      // been scrolled back in fully.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -200.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
    });

    testWidgets('only snap', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      final GlobalKey<NestedScrollViewState> nestedKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        snap: true,
        appBarKey: appBarKey,
        nestedKey: nestedKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll down the list, the app bar should scroll away and no longer be
      // visible.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -300.0));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      // The outer scroll view should be at its full extent, here the size of
      // the app bar.
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      // Animate In

      // Drag the scrollable up and down. The app bar should not snap open, nor
      // should it float in.
      final TestGesture animateInGesture = await tester.startGesture(point1);
      await animateInGesture.moveBy(const Offset(0.0, 100.0)); // Should not float in
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      // Trigger the snap open animation: drag down and release
      await animateInGesture.moveBy(const Offset(0.0, 10.0));
      await animateInGesture.up();

      // Now verify that the appbar is animating open
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      double lastExtent = verifyGeometry(
        key: appBarKey,
        paintExtent: 10.0, // >10.0 since 0.0 + 10.0
        extentGreaterThan: true,
        visible: true,
      );
      // The outer scroll offset should remain unchanged.
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(
        key: appBarKey,
        paintExtent: lastExtent,
        extentGreaterThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      // The animation finishes when the appbar is full height.
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      // Animate Out

      // Trigger the snap close animation: drag up and release
      final TestGesture animateOutGesture = await tester.startGesture(point1);
      await animateOutGesture.moveBy(const Offset(0.0, -10.0));
      await animateOutGesture.up();

      // Now verify that the appbar is animating closed
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      lastExtent = verifyGeometry(
        key: appBarKey,
        paintExtent: 46.0, // <46.0 since 56.0 - 10.0
        extentLessThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(
        key: appBarKey,
        paintExtent: lastExtent,
        extentLessThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 56.0);

      // The animation finishes when the appbar is no longer in view.
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 56.0);
    });

    testWidgets('only snap expanded', (WidgetTester tester) async {
      final GlobalKey appBarKey = GlobalKey();
      final GlobalKey<NestedScrollViewState> nestedKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        snap: true,
        expanded: true,
        appBarKey: appBarKey,
        nestedKey: nestedKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);

      // Scroll down the list, the app bar should scroll away and no longer be
      // visible.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -400.0));
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      // The outer scroll view should be at its full extent, here the size of
      // the app bar.
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      // Animate In

      // Drag the scrollable up and down. The app bar should not snap open, nor
      // should it float in.
      final TestGesture animateInGesture = await tester.startGesture(point1);
      await animateInGesture.moveBy(const Offset(0.0, 100.0)); // Should not float in
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      await animateInGesture.moveBy(const Offset(0.0, -50.0)); // No float out
      await tester.pump();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      // Trigger the snap open animation: drag down and release
      await animateInGesture.moveBy(const Offset(0.0, 10.0));
      await animateInGesture.up();

      // Now verify that the appbar is animating open
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      double lastExtent = verifyGeometry(
        key: appBarKey,
        paintExtent: 10.0, // >10.0 since 0.0 + 10.0
        extentGreaterThan: true,
        visible: true,
      );
      // The outer scroll offset should remain unchanged.
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(
        key: appBarKey,
        paintExtent: lastExtent,
        extentGreaterThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      // The animation finishes when the appbar is full height.
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      // Animate Out

      // Trigger the snap close animation: drag up and release
      final TestGesture animateOutGesture = await tester.startGesture(point1);
      await animateOutGesture.moveBy(const Offset(0.0, -10.0));
      await animateOutGesture.up();

      // Now verify that the appbar is animating closed
      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      lastExtent = verifyGeometry(
        key: appBarKey,
        paintExtent: 190.0, // <190.0 since 200.0 - 10.0
        extentLessThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      await tester.pump();
      await tester.pump(const Duration(milliseconds: 50));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(
        key: appBarKey,
        paintExtent: lastExtent,
        extentLessThan: true,
        visible: true,
      );
      expect(nestedKey.currentState!.outerController.offset, 200.0);

      // The animation finishes when the appbar is no longer in view.
      await tester.pumpAndSettle();
      expect(find.text('Test Title'), findsNothing);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      verifyGeometry(key: appBarKey, paintExtent: 0.0, visible: false);
      expect(nestedKey.currentState!.outerController.offset, 200.0);
    });

    testWidgets('float pinned', (WidgetTester tester) async {
      // This configuration should have the same behavior of a pinned app bar.
      // No floating should happen, and the app bar should persist.
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        pinned: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -300.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      await tester.dragFrom(point1, const Offset(0.0, 50.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      await tester.dragFrom(point1, const Offset(0.0, 150.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
    });

    testWidgets('float pinned expanded', (WidgetTester tester) async {
      // Only the expanded portion (flexible space) of the app bar should float
      // in and out.
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        pinned: true,
        expanded: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // The expanded portion of the app bar should collapse.
      final Offset point1 = tester.getCenter(find.text('Item 5'));
      await tester.dragFrom(point1, const Offset(0.0, -300.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll back some, the app bar should expand.
      await tester.dragFrom(point1, const Offset(0.0, 50.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        106.0, // 56.0 + 50.0
      );
      verifyGeometry(key: appBarKey, paintExtent: 106.0, visible: true);

      // Finish scrolling the rest of the way in.
      await tester.dragFrom(point1, const Offset(0.0, 150.0));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
    });

    testWidgets('float pinned with pointer signal', (WidgetTester tester) async {
      // This configuration should have the same behavior of a pinned app bar.
      // No floating should happen, and the app bar should persist.
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        pinned: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);

      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -50.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -150.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);
    });

    testWidgets('float pinned expanded with pointer signal', (WidgetTester tester) async {
      // Only the expanded portion (flexible space) of the app bar should float
      // in and out.
      final GlobalKey appBarKey = GlobalKey();
      await tester.pumpWidget(buildFloatTest(
        floating: true,
        pinned: true,
        expanded: true,
        nestedFloat: true,
        appBarKey: appBarKey,
      ));

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);

      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);

      // Scroll away the outer scroll view and some of the inner scroll view.
      // The expanded portion of the app bar should collapse.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        56.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 56.0, visible: true);

      // Scroll back some, the app bar should expand.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -50.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsNothing);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        106.0, // 56.0 + 50.0
      );
      verifyGeometry(key: appBarKey, paintExtent: 106.0, visible: true);

      // Finish scrolling the rest of the way in.
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -150.0)));
      await tester.pump();
      expect(find.text('Test Title'), findsOneWidget);
      expect(find.text('Item 1'), findsOneWidget);
      expect(find.text('Item 5'), findsOneWidget);
      expect(
        tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
        200.0,
      );
      verifyGeometry(key: appBarKey, paintExtent: 200.0, visible: true);
    });
  });

  group('Correctly handles 0 velocity inner ballistic scroll activity:', () {
    // Regression tests for https://github.com/flutter/flutter/issues/17096
    Widget buildBallisticTest(ScrollController controller) {
      return MaterialApp(
        home: Scaffold(
          body: NestedScrollView(
            controller: controller,
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              return <Widget>[
                const SliverAppBar(
                  pinned: true,
                  expandedHeight: 200.0,
                ),
              ];
            },
            body: ListView.builder(
              itemCount: 50,
              itemBuilder: (BuildContext context, int index) {
                return Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Text('Item $index'),
                );
              },
            ),
          ),
        ),
      );
    }

    testWidgets('overscroll, hold for 0 velocity, and release', (WidgetTester tester) async {
      // Dragging into an overscroll and holding so that when released, the
      // ballistic scroll activity has a 0 velocity.
      final ScrollController controller = ScrollController();
      await tester.pumpWidget(buildBallisticTest(controller));
      // Last item of the inner scroll view.
      expect(find.text('Item 49'), findsNothing);

      // Scroll to bottom
      await tester.fling(find.text('Item 3'), const Offset(0.0, -50.0), 10000.0);
      await tester.pumpAndSettle();

      // End of list
      expect(find.text('Item 49'), findsOneWidget);
      expect(tester.getCenter(find.text('Item 49')).dy, equals(585.0));

      // Overscroll, dragging like this will release with 0 velocity.
      await tester.drag(find.text('Item 49'), const Offset(0.0, -50.0));
      await tester.pump();
      // If handled correctly, the last item should still be visible and
      // progressing back down to the bottom edge, instead of jumping further
      // up the list and out of view.
      expect(find.text('Item 49'), findsOneWidget);
      await tester.pumpAndSettle();
      expect(tester.getCenter(find.text('Item 49')).dy, equals(585.0));
    }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));

    testWidgets('overscroll, release, and tap', (WidgetTester tester) async {
      // Tapping while an inner ballistic scroll activity is in progress will
      // trigger a secondary ballistic scroll activity with a 0 velocity.
      final ScrollController controller = ScrollController();
      await tester.pumpWidget(buildBallisticTest(controller));
      // Last item of the inner scroll view.
      expect(find.text('Item 49'), findsNothing);

      // Scroll to bottom
      await tester.fling(find.text('Item 3'), const Offset(0.0, -50.0), 10000.0);
      await tester.pumpAndSettle();

      // End of list
      expect(find.text('Item 49'), findsOneWidget);
      expect(tester.getCenter(find.text('Item 49')).dy, equals(585.0));

      // Fling again to trigger first ballistic activity.
      await tester.fling(find.text('Item 48'), const Offset(0.0, -50.0), 10000.0);
      await tester.pump();

      // Tap after releasing the overscroll to trigger secondary inner ballistic
      // scroll activity with 0 velocity.
      await tester.tap(find.text('Item 49'), warnIfMissed: false);
      await tester.pumpAndSettle();

      // If handled correctly, the ballistic scroll activity should finish
      // closing out the overscrolled area, with the last item visible at the
      // bottom.
      expect(find.text('Item 49'), findsOneWidget);
      expect(tester.getCenter(find.text('Item 49')).dy, equals(585.0));
    }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
  });

  // Regression test for https://github.com/flutter/flutter/issues/63978
  testWidgets('Inner _NestedScrollPosition.applyClampedDragUpdate correctly calculates range when in overscroll', (WidgetTester tester) async {
    final GlobalKey<NestedScrollViewState> nestedScrollView = GlobalKey();
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: NestedScrollView(
          key: nestedScrollView,
          headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
            return <Widget>[
              const SliverAppBar(
                expandedHeight: 200,
                title: Text('Test'),
              ),
            ];
          },
          body: ListView.builder(
            itemExtent: 100.0,
            itemBuilder: (BuildContext context, int index) => Container(
              padding: const EdgeInsets.all(10.0),
              child: Material(
                color: index.isEven ? Colors.cyan : Colors.deepOrange,
                child: Center(
                  child: Text(index.toString()),
                ),
              ),
            ),
          ),
        ),
      ),
    ));

    expect(nestedScrollView.currentState!.outerController.position.pixels, 0.0);
    expect(nestedScrollView.currentState!.innerController.position.pixels, 0.0);
    expect(nestedScrollView.currentState!.outerController.position.maxScrollExtent, 200.0);
    final Offset point = tester.getCenter(find.text('1'));
    // Drag slightly into overscroll in the inner position.
    final TestGesture gesture = await tester.startGesture(point);
    await gesture.moveBy(const Offset(0.0, 5.0));
    await tester.pump();
    expect(nestedScrollView.currentState!.outerController.position.pixels, 0.0);
    expect(nestedScrollView.currentState!.innerController.position.pixels, -5.0);
    // Move by a much larger delta than the amount of over scroll, in a very
    // short period of time.
    await gesture.moveBy(const Offset(0.0, -500.0));
    await tester.pump();
    // The overscrolled inner position should have closed, then passed the
    // correct remaining delta to the outer position, and finally any remainder
    // back to the inner position.
    expect(
      nestedScrollView.currentState!.outerController.position.pixels,
      nestedScrollView.currentState!.outerController.position.maxScrollExtent,
    );
    expect(nestedScrollView.currentState!.innerController.position.pixels, 295.0);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('Scroll pointer signal should not cause overscroll.', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    await tester.pumpWidget(buildTest(controller: controller));

    final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
    final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    // Create a hover event so that |testPointer| has a location when generating the scroll.
    testPointer.hover(scrollEventLocation);

    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 20.0)));
    expect(controller.offset, 20);

    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -40.0)));
    expect(controller.offset, 0);

    await tester.tap(find.text('DD'));
    await tester.pumpAndSettle();

    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 1000000.0)));
    expect(find.text('ddd1'), findsOneWidget);
  });

  testWidgets('NestedScrollView basic scroll with pointer signal', (WidgetTester tester) async{
    await tester.pumpWidget(buildTest());
    expect(find.text('aaa2'), findsOneWidget);
    expect(find.text('aaa3'), findsNothing);
    expect(find.text('bbb1'), findsNothing);
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      200.0,
    );

    // Regression test for https://github.com/flutter/flutter/issues/55362
    final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    // The offset is the responsibility of innerPosition.
    testPointer.hover(const Offset(0, 201));

    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 20.0)));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      180.0,
    );

    testPointer.hover(const Offset(0, 179));
    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 20.0)));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      160.0,
    );

    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 20.0)));
    await tester.pump(const Duration(milliseconds: 250));
    expect(
      tester.renderObject<RenderBox>(find.byType(AppBar)).size.height,
      140.0,
    );
  });

  // Related to https://github.com/flutter/flutter/issues/64266
  testWidgets(
    'Holding scroll and Scroll pointer signal will update ScrollDirection.forward / ScrollDirection.reverse',
    (WidgetTester tester) async {
      ScrollDirection? lastUserScrollingDirection;

      final ScrollController controller = ScrollController();
      await tester.pumpWidget(buildTest(controller: controller));

      controller.addListener(() {
        if (controller.position.userScrollDirection != ScrollDirection.idle) {
          lastUserScrollingDirection = controller.position.userScrollDirection;
        }
      });

      await tester.drag(find.byType(NestedScrollView), const Offset(0.0, -20.0), touchSlopY: 0.0);

      expect(lastUserScrollingDirection, ScrollDirection.reverse);

      final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
      final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
      // Create a hover event so that |testPointer| has a location when generating the scroll.
      testPointer.hover(scrollEventLocation);
      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 20.0)));

      expect(lastUserScrollingDirection, ScrollDirection.reverse);

      await tester.drag(find.byType(NestedScrollView), const Offset(0.0, 20.0), touchSlopY: 0.0);

      expect(lastUserScrollingDirection, ScrollDirection.forward);

      await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, -20.0)));

      expect(lastUserScrollingDirection, ScrollDirection.forward);
    },
  );

  // Regression test for https://github.com/flutter/flutter/issues/72257
  testWidgets('NestedScrollView works well when rebuilding during scheduleWarmUpFrame', (WidgetTester tester) async {
    bool? isScrolled;
    final Widget myApp = MaterialApp(
      home: Scaffold(
        body: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Focus(
              onFocusChange: (_) => setState( (){} ),
              child: NestedScrollView(
                headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
                  isScrolled = boxIsScrolled;
                  return <Widget>[
                    const SliverAppBar(
                      expandedHeight: 200,
                      title: Text('Test'),
                    ),
                  ];
                },
                body: CustomScrollView(
                  slivers: <Widget>[
                    SliverList(
                      delegate: SliverChildBuilderDelegate(
                        (BuildContext context, int index) {
                          return const Text('');
                        },
                        childCount: 10,
                      ),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );

    await tester.pumpWidget(myApp, Duration.zero, EnginePhase.build);
    expect(isScrolled, false);
    expect(tester.takeException(), isNull);
  });

  // Regression test of https://github.com/flutter/flutter/issues/74372
  testWidgets('ScrollPosition can be accessed during `_updatePosition()`', (WidgetTester tester) async {
    final ScrollController controller = ScrollController();
    late ScrollPosition position;

    Widget buildFrame({ScrollPhysics? physics}) {
      return Directionality(
        textDirection: TextDirection.ltr,
        child: Localizations(
          locale: const Locale('en', 'US'),
          delegates: const <LocalizationsDelegate<dynamic>>[
            DefaultMaterialLocalizations.delegate,
            DefaultWidgetsLocalizations.delegate,
          ],
          child: MediaQuery(
            data: const MediaQueryData(),
            child: NestedScrollView(
              controller: controller,
              physics: physics,
              headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
                return <Widget>[
                  Builder(
                    builder: (BuildContext context) {
                      position = controller.position;
                      return const SliverAppBar(
                        floating: true,
                        title: Text('AA'),
                      );
                    },
                  ),
                ];
              },
              body: Container(),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame());
    expect(position.pixels, 0.0);

    //Trigger `_updatePosition()`.
    await tester.pumpWidget(buildFrame(physics: const _CustomPhysics()));
    expect(position.pixels, 0.0);
  });

  testWidgets("NestedScrollView doesn't crash due to precision error", (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/63825

    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: NestedScrollView(
          floatHeaderSlivers: true,
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) => <Widget>[
            const SliverAppBar(
              expandedHeight: 250.0,
            ),
          ],
          body: CustomScrollView(
            physics: const BouncingScrollPhysics(),
            slivers: <Widget>[
              SliverPadding(
                padding: const EdgeInsets.all(8.0),
                sliver: SliverFixedExtentList(
                  itemExtent: 48.0,
                  delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                      return ListTile(
                        title: Text('Item $index'),
                      );
                    },
                    childCount: 30,
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    ));

    // Scroll to bottom
    await tester.fling(find.text('Item 3'), const Offset(0.0, -250.0), 10000.0);
    await tester.pumpAndSettle();

    // Fling down for AppBar to show
    await tester.drag(find.text('Item 29'), const Offset(0.0, 250 - 133.7981622869321));

    // Fling up to trigger ballistic activity
    await tester.fling(find.text('Item 25'), const Offset(0.0, -50.0), 4000.0);
    await tester.pumpAndSettle();
  });

  testWidgets('NestedScrollViewCoordinator.pointerScroll dispatches correct scroll notifications', (WidgetTester tester) async {
    int scrollEnded = 0;
    int scrollStarted = 0;
    bool isScrolled = false;

    await tester.pumpWidget(MaterialApp(
      home: NotificationListener<ScrollNotification>(
        onNotification: (ScrollNotification notification) {
          if (notification is ScrollStartNotification) {
            scrollStarted += 1;
          } else if (notification is ScrollEndNotification) {
            scrollEnded += 1;
          }
          return false;
        },
        child: Scaffold(
          body: NestedScrollView(
            headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
              isScrolled = innerBoxIsScrolled;
              return <Widget>[
                const SliverAppBar(
                  expandedHeight: 250.0,
                ),
              ];
            },
            body: CustomScrollView(
              physics: const BouncingScrollPhysics(),
              slivers: <Widget>[
                SliverPadding(
                  padding: const EdgeInsets.all(8.0),
                  sliver: SliverFixedExtentList(
                    itemExtent: 48.0,
                    delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int index) {
                        return ListTile(
                          title: Text('Item $index'),
                        );
                      },
                      childCount: 30,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    ));

    final Offset scrollEventLocation = tester.getCenter(find.byType(NestedScrollView));
    final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
    // Create a hover event so that |testPointer| has a location when generating the scroll.
    testPointer.hover(scrollEventLocation);
    await tester.sendEventToBinding(testPointer.scroll(const Offset(0.0, 300.0)));
    await tester.pumpAndSettle();

    expect(isScrolled, isTrue);
    // There should have been a notification for each nested position (2).
    expect(scrollStarted, 2);
    expect(scrollEnded, 2);
  });

  testWidgets('SliverAppBar.medium collapses in NestedScrollView', (WidgetTester tester) async {
    final GlobalKey<NestedScrollViewState> nestedScrollView = GlobalKey();
    const double collapsedAppBarHeight = 64;
    const double expandedAppBarHeight = 112;

    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: NestedScrollView(
          key: nestedScrollView,
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              SliverOverlapAbsorber(
                handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                sliver: SliverAppBar.medium(
                  title: const Text('AppBar Title'),
                ),
              ),
            ];
          },
          body: Builder(
            builder: (BuildContext context) {
              return CustomScrollView(
                slivers: <Widget>[
                  SliverOverlapInjector(handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
                  SliverFixedExtentList(
                    itemExtent: 50.0,
                    delegate: SliverChildBuilderDelegate(
                      (BuildContext context, int index) => ListTile(title: Text('Item $index')),
                      childCount: 30,
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    ));

    // There are two widgets for the title.
    final Finder expandedTitle = find.text('AppBar Title').last;
    final Finder expandedTitleClip = find.ancestor(
      of: expandedTitle,
      matching: find.byType(ClipRect),
    );

    // Default, fully expanded app bar.
    expect(nestedScrollView.currentState?.outerController.offset, 0);
    expect(nestedScrollView.currentState?.innerController.offset, 0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);

    // Scroll the expanded app bar partially out of view.
    final Offset point1 = tester.getCenter(find.text('Item 5'));
    await tester.dragFrom(point1, const Offset(0.0, -45.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 45.0);
    expect(nestedScrollView.currentState?.innerController.offset, 0.0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight - 45);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight - 45);

    // Scroll so that it is completely collapsed.
    await tester.dragFrom(point1, const Offset(0.0, -555.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 48.0);
    expect(nestedScrollView.currentState?.innerController.offset, 552.0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), collapsedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, 0);

    // Scroll back to fully expanded.
    await tester.dragFrom(point1, const Offset(0.0, 600.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 0);
    expect(nestedScrollView.currentState?.innerController.offset, 0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);
  });

  testWidgets('SliverAppBar.large collapses in NestedScrollView', (WidgetTester tester) async {
    final GlobalKey<NestedScrollViewState> nestedScrollView = GlobalKey();
    const double collapsedAppBarHeight = 64;
    const double expandedAppBarHeight = 152;

    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: NestedScrollView(
          key: nestedScrollView,
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              SliverOverlapAbsorber(
                handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                sliver: SliverAppBar.large(
                  title: const Text('AppBar Title'),
                  forceElevated: innerBoxIsScrolled,
                ),
              ),
            ];
          },
          body: Builder(
            builder: (BuildContext context) {
              return CustomScrollView(
                slivers: <Widget>[
                  SliverOverlapInjector(handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context)),
                  SliverFixedExtentList(
                    itemExtent: 50.0,
                    delegate: SliverChildBuilderDelegate(
                          (BuildContext context, int index) => ListTile(title: Text('Item $index')),
                      childCount: 30,
                    ),
                  ),
                ],
              );
            },
          ),
        ),
      ),
    ));

    // There are two widgets for the title.
    final Finder expandedTitle = find.text('AppBar Title').last;
    final Finder expandedTitleClip = find.ancestor(
      of: expandedTitle,
      matching: find.byType(ClipRect),
    );

    // Default, fully expanded app bar.
    expect(nestedScrollView.currentState?.outerController.offset, 0);
    expect(nestedScrollView.currentState?.innerController.offset, 0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);

    // Scroll the expanded app bar partially out of view.
    final Offset point1 = tester.getCenter(find.text('Item 5'));
    await tester.dragFrom(point1, const Offset(0.0, -45.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 45.0);
    expect(nestedScrollView.currentState?.innerController.offset, 0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight - 45);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight - 45);

    // Scroll so that it is completely collapsed.
    await tester.dragFrom(point1, const Offset(0.0, -555.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 88.0);
    expect(nestedScrollView.currentState?.innerController.offset, 512.0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), collapsedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, 0);

    // Scroll back to fully expanded.
    await tester.dragFrom(point1, const Offset(0.0, 600.0));
    await tester.pump();
    expect(nestedScrollView.currentState?.outerController.offset, 0);
    expect(nestedScrollView.currentState?.innerController.offset, 0);
    expect(find.byType(SliverAppBar), findsOneWidget);
    expect(appBarHeight(tester), expandedAppBarHeight);
    expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight);
  });
}

double appBarHeight(WidgetTester tester) => tester.getSize(find.byType(AppBar, skipOffstage: false)).height;

class TestHeader extends SliverPersistentHeaderDelegate {
  const TestHeader({ this.key });
  final Key? key;
  @override
  double get minExtent => 100.0;
  @override
  double get maxExtent => 100.0;
  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Placeholder(key: key);
  }
  @override
  bool shouldRebuild(TestHeader oldDelegate) => false;
}

class _TestLayoutExtentIsNegative extends StatelessWidget {
  const _TestLayoutExtentIsNegative(this.widgetCountBeforeSliverOverlapAbsorber);
  final int widgetCountBeforeSliverOverlapAbsorber;
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Test'),
        ),
        body: NestedScrollView(
          headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
            return <Widget>[
              ...List<Widget>.generate(widgetCountBeforeSliverOverlapAbsorber, (_) {
                return SliverToBoxAdapter(
                  child: Container(
                    color: Colors.red,
                    height: 200,
                    margin:const EdgeInsets.all(20),
                  ),
                );
              }),
              SliverOverlapAbsorber(
                handle: NestedScrollView.sliverOverlapAbsorberHandleFor(context),
                sliver: SliverAppBar(
                  pinned: true,
                  forceElevated: innerBoxIsScrolled,
                  backgroundColor: Colors.blue[300],
                  title: const SizedBox(
                    height: 50,
                    child: Center(
                      child: Text('Sticky Header'),
                    ),
                  ),
                ),
              ),
            ];
          },
          body: Container(
            height: 2000,
            margin: const EdgeInsets.only(top: 50),
            child: ListView(
              children: List<Widget>.generate(3, (_) {
                return Container(
                  color: Colors.green[200],
                  height: 200,
                  margin: const EdgeInsets.all(20),
                );
              }),
            ),
          ),
        ),
      ),
    );
  }
}
