// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';

class StateMarker extends StatefulWidget {
  const StateMarker({super.key, this.child});

  final Widget? child;

  @override
  StateMarkerState createState() => StateMarkerState();
}

class StateMarkerState extends State<StateMarker> {
  late String marker;

  @override
  Widget build(BuildContext context) {
    return widget.child ?? Container();
  }
}

void main() {
  group('ThemeMode getters', () {
    test('ThemeMode.system', () {
      expect(ThemeMode.system.isSystem, isTrue);
      expect(ThemeMode.system.isLight, isFalse);
      expect(ThemeMode.system.isDark, isFalse);
    });

    test('ThemeMode.light', () {
      expect(ThemeMode.light.isSystem, isFalse);
      expect(ThemeMode.light.isLight, isTrue);
      expect(ThemeMode.light.isDark, isFalse);
    });

    test('ThemeMode.dark', () {
      expect(ThemeMode.dark.isSystem, isFalse);
      expect(ThemeMode.dark.isLight, isFalse);
      expect(ThemeMode.dark.isDark, isTrue);
    });
  });

  testWidgets('Can nest apps', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: MaterialApp(home: Text('Home sweet home'))));

    expect(find.text('Home sweet home'), findsOneWidget);
  });

  testWidgets('Focus handling', (WidgetTester tester) async {
    final focusNode = FocusNode();
    addTearDown(focusNode.dispose);

    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Center(child: TextField(focusNode: focusNode, autofocus: true)),
        ),
      ),
    );

    expect(focusNode.hasFocus, isTrue);
  });

  testWidgets('Can place app inside FocusScope', (WidgetTester tester) async {
    final focusScopeNode = FocusScopeNode();
    addTearDown(focusScopeNode.dispose);

    await tester.pumpWidget(
      FocusScope(
        autofocus: true,
        node: focusScopeNode,
        child: const MaterialApp(home: Text('Home')),
      ),
    );

    expect(find.text('Home'), findsOneWidget);
  });

  testWidgets('Can show grid without losing sync', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: StateMarker()));

    final StateMarkerState state1 = tester.state(find.byType(StateMarker));
    state1.marker = 'original';

    await tester.pumpWidget(const MaterialApp(debugShowMaterialGrid: true, home: StateMarker()));

    final StateMarkerState state2 = tester.state(find.byType(StateMarker));
    expect(state1, equals(state2));
    expect(state2.marker, equals('original'));
  });

  testWidgets('Do not rebuild page during a route transition', (WidgetTester tester) async {
    var buildCounter = 0;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Material(
              child: ElevatedButton(
                child: const Text('X'),
                onPressed: () {
                  Navigator.of(context).pushNamed('/next');
                },
              ),
            );
          },
        ),
        routes: <String, WidgetBuilder>{
          '/next': (BuildContext context) {
            return Builder(
              builder: (BuildContext context) {
                ++buildCounter;
                return const Text('Y');
              },
            );
          },
        },
      ),
    );

    expect(buildCounter, 0);
    await tester.tap(find.text('X'));
    expect(buildCounter, 0);
    await tester.pump();
    expect(buildCounter, 1);
    await tester.pump(const Duration(milliseconds: 10));
    expect(buildCounter, 1);
    await tester.pump(const Duration(milliseconds: 10));
    expect(buildCounter, 1);
    await tester.pump(const Duration(milliseconds: 10));
    expect(buildCounter, 1);
    await tester.pump(const Duration(milliseconds: 10));
    expect(buildCounter, 1);
    await tester.pump(const Duration(seconds: 1));
    expect(buildCounter, 1);
    expect(find.text('Y'), findsOneWidget);
  });

  testWidgets('Do rebuild the home page if it changes', (WidgetTester tester) async {
    var buildCounter = 0;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            ++buildCounter;
            return const Text('A');
          },
        ),
      ),
    );
    expect(buildCounter, 1);
    expect(find.text('A'), findsOneWidget);
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            ++buildCounter;
            return const Text('B');
          },
        ),
      ),
    );
    expect(buildCounter, 2);
    expect(find.text('B'), findsOneWidget);
  });

  testWidgets('Do not rebuild the home page if it does not actually change', (
    WidgetTester tester,
  ) async {
    var buildCounter = 0;
    final Widget home = Builder(
      builder: (BuildContext context) {
        ++buildCounter;
        return const Placeholder();
      },
    );
    await tester.pumpWidget(MaterialApp(home: home));
    expect(buildCounter, 1);
    await tester.pumpWidget(MaterialApp(home: home));
    expect(buildCounter, 1);
  });

  testWidgets('Do rebuild pages that come from the routes table if the MaterialApp changes', (
    WidgetTester tester,
  ) async {
    var buildCounter = 0;
    final routes = <String, WidgetBuilder>{
      '/': (BuildContext context) {
        ++buildCounter;
        return const Placeholder();
      },
    };
    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(buildCounter, 1);
    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(buildCounter, 2);
  });

  testWidgets('Cannot pop the initial route', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(home: Text('Home')));

    expect(find.text('Home'), findsOneWidget);

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    final bool result = await navigator.maybePop();

    expect(result, isFalse);

    expect(find.text('Home'), findsOneWidget);
  });

  testWidgets('Default initialRoute', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        routes: <String, WidgetBuilder>{'/': (BuildContext context) => const Text('route "/"')},
      ),
    );

    expect(find.text('route "/"'), findsOneWidget);
  });

  testWidgets('One-step initial route', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        initialRoute: '/a',
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => const Text('route "/"'),
          '/a': (BuildContext context) => const Text('route "/a"'),
          '/a/b': (BuildContext context) => const Text('route "/a/b"'),
          '/b': (BuildContext context) => const Text('route "/b"'),
        },
      ),
    );

    expect(find.text('route "/"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a"'), findsOneWidget);
    expect(find.text('route "/a/b"', skipOffstage: false), findsNothing);
    expect(find.text('route "/b"', skipOffstage: false), findsNothing);
  });

  testWidgets('Return value from pop is correct', (WidgetTester tester) async {
    late Future<Object?> result;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Material(
              child: ElevatedButton(
                child: const Text('X'),
                onPressed: () async {
                  result = Navigator.of(context).pushNamed<Object?>('/a');
                },
              ),
            );
          },
        ),
        routes: <String, WidgetBuilder>{
          '/a': (BuildContext context) {
            return Material(
              child: ElevatedButton(
                child: const Text('Y'),
                onPressed: () {
                  Navigator.of(context).pop('all done');
                },
              ),
            );
          },
        },
      ),
    );
    await tester.tap(find.text('X'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(find.text('Y'), findsOneWidget);
    await tester.tap(find.text('Y'));
    await tester.pump();

    expect(await result, equals('all done'));
  });

  testWidgets('Two-step initial route', (WidgetTester tester) async {
    final routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => const Text('route "/"'),
      '/a': (BuildContext context) => const Text('route "/a"'),
      '/a/b': (BuildContext context) => const Text('route "/a/b"'),
      '/b': (BuildContext context) => const Text('route "/b"'),
    };

    await tester.pumpWidget(MaterialApp(initialRoute: '/a/b', routes: routes));
    expect(find.text('route "/"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a/b"'), findsOneWidget);
    expect(find.text('route "/b"', skipOffstage: false), findsNothing);
  });

  testWidgets('Initial route with missing step', (WidgetTester tester) async {
    final routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => const Text('route "/"'),
      '/a': (BuildContext context) => const Text('route "/a"'),
      '/a/b': (BuildContext context) => const Text('route "/a/b"'),
      '/b': (BuildContext context) => const Text('route "/b"'),
    };

    await tester.pumpWidget(MaterialApp(initialRoute: '/a/b/c', routes: routes));
    final dynamic exception = tester.takeException();
    expect(exception, isA<String>());
    if (exception is String) {
      expect(exception.startsWith('Could not navigate to initial route.'), isTrue);
      expect(find.text('route "/"'), findsOneWidget);
      expect(find.text('route "/a"'), findsNothing);
      expect(find.text('route "/a/b"'), findsNothing);
      expect(find.text('route "/b"'), findsNothing);
    }
  });

  testWidgets('Make sure initialRoute is only used the first time', (WidgetTester tester) async {
    final routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => const Text('route "/"'),
      '/a': (BuildContext context) => const Text('route "/a"'),
      '/b': (BuildContext context) => const Text('route "/b"'),
    };

    await tester.pumpWidget(MaterialApp(initialRoute: '/a', routes: routes));
    expect(find.text('route "/"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a"'), findsOneWidget);
    expect(find.text('route "/b"', skipOffstage: false), findsNothing);

    // changing initialRoute has no effect
    await tester.pumpWidget(MaterialApp(initialRoute: '/b', routes: routes));
    expect(find.text('route "/"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a"'), findsOneWidget);
    expect(find.text('route "/b"', skipOffstage: false), findsNothing);

    // removing it has no effect
    await tester.pumpWidget(MaterialApp(routes: routes));
    expect(find.text('route "/"', skipOffstage: false), findsOneWidget);
    expect(find.text('route "/a"'), findsOneWidget);
    expect(find.text('route "/b"', skipOffstage: false), findsNothing);
  });

  testWidgets(
    'onGenerateRoute / onUnknownRoute',
    experimentalLeakTesting: LeakTesting.settings
        .withIgnoredAll(), // leaking by design because of exception
    (WidgetTester tester) async {
      final log = <String>[];
      await tester.pumpWidget(
        MaterialApp(
          onGenerateRoute: (RouteSettings settings) {
            log.add('onGenerateRoute ${settings.name}');
            return null;
          },
          onUnknownRoute: (RouteSettings settings) {
            log.add('onUnknownRoute ${settings.name}');
            return null;
          },
        ),
      );
      expect(tester.takeException(), isFlutterError);
      expect(log, <String>['onGenerateRoute /', 'onUnknownRoute /']);
    },
  );

  testWidgets('MaterialApp with builder and no route information works.', (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/18904
    await tester.pumpWidget(
      MaterialApp(
        builder: (BuildContext context, Widget? child) {
          return const SizedBox();
        },
      ),
    );
  });

  testWidgets("WidgetsApp doesn't rebuild routes when MediaQuery updates", (
    WidgetTester tester,
  ) async {
    // Regression test for https://github.com/flutter/flutter/issues/37878
    addTearDown(tester.platformDispatcher.clearAllTestValues);
    addTearDown(tester.view.reset);

    var routeBuildCount = 0;
    var dependentBuildCount = 0;

    await tester.pumpWidget(
      WidgetsApp(
        color: const Color.fromARGB(255, 255, 255, 255),
        onGenerateRoute: (_) {
          return PageRouteBuilder<void>(
            pageBuilder: (_, _, _) {
              routeBuildCount++;
              return Builder(
                builder: (BuildContext context) {
                  dependentBuildCount++;
                  MediaQuery.of(context);
                  return Container();
                },
              );
            },
          );
        },
      ),
    );

    expect(routeBuildCount, equals(1));
    expect(dependentBuildCount, equals(1));

    // didChangeMetrics
    tester.view.physicalSize = const Size(42, 42);

    await tester.pump();

    expect(routeBuildCount, equals(1));
    expect(dependentBuildCount, equals(2));

    // didChangeTextScaleFactor
    tester.platformDispatcher.textScaleFactorTestValue = 42;

    await tester.pump();

    expect(routeBuildCount, equals(1));
    expect(dependentBuildCount, equals(3));

    // didChangePlatformBrightness
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

    await tester.pump();

    expect(routeBuildCount, equals(1));
    expect(dependentBuildCount, equals(4));

    // didChangeAccessibilityFeatures
    tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;

    await tester.pumpAndSettle();

    expect(routeBuildCount, equals(1));
    expect(dependentBuildCount, equals(5));
  });

  testWidgets('Can get text scale from media query', (WidgetTester tester) async {
    TextScaler? textScaler;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            textScaler = MediaQuery.textScalerOf(context);
            return Container();
          },
        ),
      ),
    );
    expect(textScaler, isSystemTextScaler(withScaleFactor: 1.0));
  });

  testWidgets('MaterialApp.navigatorKey', (WidgetTester tester) async {
    final key = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(navigatorKey: key, color: const Color(0xFF112233), home: const Placeholder()),
    );
    expect(key.currentState, isA<NavigatorState>());
    await tester.pumpWidget(const MaterialApp(color: Color(0xFF112233), home: Placeholder()));
    expect(key.currentState, isNull);
    await tester.pumpWidget(
      MaterialApp(navigatorKey: key, color: const Color(0xFF112233), home: const Placeholder()),
    );
    expect(key.currentState, isA<NavigatorState>());
  });

  testWidgets('Has default material and cupertino localizations', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Column(
              children: <Widget>[
                Text(MaterialLocalizations.of(context).selectAllButtonLabel),
                Text(CupertinoLocalizations.of(context).selectAllButtonLabel),
              ],
            );
          },
        ),
      ),
    );

    // Default US "select all" text.
    expect(find.text('Select all'), findsOneWidget);
    // Default Cupertino US "select all" text.
    expect(find.text('Select All'), findsOneWidget);
  });

  testWidgets('MaterialApp uses regular theme when themeMode is light', (
    WidgetTester tester,
  ) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    // Mock the test to explicitly report a light platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;

    late ThemeData appliedTheme;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        themeMode: ThemeMode.light,
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );
    expect(appliedTheme.brightness, Brightness.light);

    // Mock the test to explicitly report a dark platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        themeMode: ThemeMode.light,
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );
    expect(appliedTheme.brightness, Brightness.light);
  });

  testWidgets('MaterialApp uses darkTheme when themeMode is dark', (WidgetTester tester) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    // Mock the test to explicitly report a light platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;

    late ThemeData appliedTheme;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        themeMode: ThemeMode.dark,
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );
    expect(appliedTheme.brightness, Brightness.dark);

    // Mock the test to explicitly report a dark platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        themeMode: ThemeMode.dark,
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );
    expect(appliedTheme.brightness, Brightness.dark);
  });

  testWidgets(
    'MaterialApp uses regular theme when themeMode is system and platformBrightness is light',
    (WidgetTester tester) async {
      addTearDown(tester.platformDispatcher.clearAllTestValues);

      // Mock the test to explicitly report a light platformBrightness.
      tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;

      late ThemeData appliedTheme;

      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(brightness: Brightness.light),
          darkTheme: ThemeData(brightness: Brightness.dark),
          home: Builder(
            builder: (BuildContext context) {
              appliedTheme = Theme.of(context);
              return const SizedBox();
            },
          ),
        ),
      );

      expect(appliedTheme.brightness, Brightness.light);
    },
  );

  testWidgets(
    'MaterialApp uses darkTheme when themeMode is system and platformBrightness is dark',
    (WidgetTester tester) async {
      addTearDown(tester.platformDispatcher.clearAllTestValues);

      // Mock the test to explicitly report a dark platformBrightness.
      tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

      late ThemeData appliedTheme;
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(brightness: Brightness.light),
          darkTheme: ThemeData(brightness: Brightness.dark),
          home: Builder(
            builder: (BuildContext context) {
              appliedTheme = Theme.of(context);
              return const SizedBox();
            },
          ),
        ),
      );
      expect(appliedTheme.brightness, Brightness.dark);
    },
  );

  testWidgets(
    'MaterialApp uses light theme when platformBrightness is dark but no dark theme is provided',
    (WidgetTester tester) async {
      addTearDown(tester.platformDispatcher.clearAllTestValues);

      // Mock the test to explicitly report a dark platformBrightness.
      tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

      late ThemeData appliedTheme;

      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(brightness: Brightness.light),
          home: Builder(
            builder: (BuildContext context) {
              appliedTheme = Theme.of(context);
              return const SizedBox();
            },
          ),
        ),
      );

      expect(appliedTheme.brightness, Brightness.light);
    },
  );

  testWidgets(
    'MaterialApp uses fallback light theme when platformBrightness is dark but no theme is provided at all',
    (WidgetTester tester) async {
      addTearDown(tester.platformDispatcher.clearAllTestValues);

      // Mock the test to explicitly report a dark platformBrightness.
      tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

      late ThemeData appliedTheme;

      await tester.pumpWidget(
        MaterialApp(
          home: Builder(
            builder: (BuildContext context) {
              appliedTheme = Theme.of(context);
              return const SizedBox();
            },
          ),
        ),
      );

      expect(appliedTheme.brightness, Brightness.light);
    },
  );

  testWidgets(
    'MaterialApp uses fallback light theme when platformBrightness is light and a dark theme is provided',
    (WidgetTester tester) async {
      addTearDown(tester.platformDispatcher.clearAllTestValues);

      // Mock the test to explicitly report a dark platformBrightness.
      tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;

      late ThemeData appliedTheme;

      await tester.pumpWidget(
        MaterialApp(
          darkTheme: ThemeData(brightness: Brightness.dark),
          home: Builder(
            builder: (BuildContext context) {
              appliedTheme = Theme.of(context);
              return const SizedBox();
            },
          ),
        ),
      );

      expect(appliedTheme.brightness, Brightness.light);
    },
  );

  testWidgets('MaterialApp uses dark theme when platformBrightness is dark', (
    WidgetTester tester,
  ) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    // Mock the test to explicitly report a dark platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;

    late ThemeData appliedTheme;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );

    expect(appliedTheme.brightness, Brightness.dark);
  });

  testWidgets('MaterialApp uses high contrast theme when appropriate', (WidgetTester tester) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;
    tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;

    late ThemeData appliedTheme;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(primaryColor: Colors.lightBlue),
        highContrastTheme: ThemeData(primaryColor: Colors.blue),
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );

    expect(appliedTheme.primaryColor, Colors.blue);
  });

  testWidgets('MaterialApp uses high contrast dark theme when appropriate', (
    WidgetTester tester,
  ) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
    tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;

    late ThemeData appliedTheme;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(primaryColor: Colors.lightBlue),
        darkTheme: ThemeData(primaryColor: Colors.lightGreen),
        highContrastTheme: ThemeData(primaryColor: Colors.blue),
        highContrastDarkTheme: ThemeData(primaryColor: Colors.green),
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );

    expect(appliedTheme.primaryColor, Colors.green);
  });

  testWidgets('MaterialApp uses dark theme when no high contrast dark theme is provided', (
    WidgetTester tester,
  ) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
    tester.platformDispatcher.accessibilityFeaturesTestValue = FakeAccessibilityFeatures.allOn;

    late ThemeData appliedTheme;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(primaryColor: Colors.lightBlue),
        darkTheme: ThemeData(primaryColor: Colors.lightGreen),
        home: Builder(
          builder: (BuildContext context) {
            appliedTheme = Theme.of(context);
            return const SizedBox();
          },
        ),
      ),
    );

    expect(appliedTheme.primaryColor, Colors.lightGreen);
  });

  testWidgets('MaterialApp animates theme changes', (WidgetTester tester) async {
    final lightTheme = ThemeData();
    final darkTheme = ThemeData.dark();
    await tester.pumpWidget(
      MaterialApp(
        theme: lightTheme,
        darkTheme: darkTheme,
        themeMode: ThemeMode.light,
        home: Builder(
          builder: (BuildContext context) {
            return const Scaffold();
          },
        ),
      ),
    );
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      lightTheme.scaffoldBackgroundColor,
    );

    // Change to dark theme
    await tester.pumpWidget(
      MaterialApp(
        darkTheme: ThemeData.dark(),
        themeMode: ThemeMode.dark,
        home: Builder(
          builder: (BuildContext context) {
            return const Scaffold();
          },
        ),
      ),
    );

    // Wait half kThemeAnimationDuration = 200ms.
    await tester.pump(const Duration(milliseconds: 100));

    // Default curve is linear so background should be half way between
    // the two colors.
    final Color halfBGColor = Color.lerp(
      lightTheme.scaffoldBackgroundColor,
      darkTheme.scaffoldBackgroundColor,
      0.5,
    )!;
    expect(tester.widget<Material>(find.byType(Material)).color, halfBGColor);
  });

  testWidgets('MaterialApp theme animation can be turned off', (WidgetTester tester) async {
    final lightTheme = ThemeData();
    final darkTheme = ThemeData.dark();
    var scaffoldRebuilds = 0;

    final Widget scaffold = Builder(
      builder: (BuildContext context) {
        scaffoldRebuilds++;
        // Use Theme.of() to ensure we are building when the theme changes.
        return Scaffold(backgroundColor: Theme.of(context).scaffoldBackgroundColor);
      },
    );

    await tester.pumpWidget(
      MaterialApp(
        theme: lightTheme,
        darkTheme: darkTheme,
        themeMode: ThemeMode.light,
        themeAnimationDuration: Duration.zero,
        home: scaffold,
      ),
    );
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      lightTheme.scaffoldBackgroundColor,
    );
    expect(scaffoldRebuilds, 1);

    // Change to dark theme
    await tester.pumpWidget(
      MaterialApp(
        darkTheme: ThemeData.dark(),
        themeMode: ThemeMode.dark,
        themeAnimationDuration: Duration.zero,
        home: scaffold,
      ),
    );

    // Wait for any animation to finish.
    await tester.pumpAndSettle();
    expect(tester.widget<Material>(find.byType(Material)).color, darkTheme.scaffoldBackgroundColor);
    expect(scaffoldRebuilds, 2);
  });

  testWidgets('MaterialApp switches themes when the platformBrightness changes.', (
    WidgetTester tester,
  ) async {
    addTearDown(tester.platformDispatcher.clearAllTestValues);

    // Mock the test to explicitly report a light platformBrightness.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.light;

    ThemeData? themeBeforeBrightnessChange;
    ThemeData? themeAfterBrightnessChange;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        darkTheme: ThemeData(brightness: Brightness.dark),
        home: Builder(
          builder: (BuildContext context) {
            if (themeBeforeBrightnessChange == null) {
              themeBeforeBrightnessChange = Theme.of(context);
            } else {
              themeAfterBrightnessChange = Theme.of(context);
            }
            return const SizedBox();
          },
        ),
      ),
    );

    // Switch the platformBrightness from light to dark and pump the widget tree
    // to process changes.
    tester.platformDispatcher.platformBrightnessTestValue = Brightness.dark;
    await tester.pumpAndSettle();

    expect(themeBeforeBrightnessChange!.brightness, Brightness.light);
    expect(themeAfterBrightnessChange!.brightness, Brightness.dark);
  });

  testWidgets('Material2 - MaterialApp provides default overscroll color', (
    WidgetTester tester,
  ) async {
    Future<void> slowDrag(WidgetTester tester, Offset start, Offset offset) async {
      final TestGesture gesture = await tester.startGesture(start);
      for (var index = 0; index < 10; index += 1) {
        await gesture.moveBy(offset);
        await tester.pump(const Duration(milliseconds: 20));
      }
      await gesture.up();
    }

    // The overscroll color should be a transparent version of the colorScheme's
    // secondary color.
    const secondaryColor = Color(0xff008800);
    final Color glowSecondaryColor = secondaryColor.withOpacity(0.05);
    final theme = ThemeData.from(
      useMaterial3: false,
      colorScheme: const ColorScheme.light().copyWith(secondary: secondaryColor),
    );
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: const SingleChildScrollView(child: SizedBox(height: 2000.0)),
      ),
    );

    final RenderObject painter = tester.renderObject(find.byType(CustomPaint).first);
    await slowDrag(tester, const Offset(200.0, 200.0), const Offset(0.0, 5.0));
    expect(painter, paints..circle(color: glowSecondaryColor));
  });

  testWidgets('MaterialApp can customize initial routes', (WidgetTester tester) async {
    final navigatorKey = GlobalKey<NavigatorState>();
    await tester.pumpWidget(
      MaterialApp(
        navigatorKey: navigatorKey,
        onGenerateInitialRoutes: (String initialRoute) {
          expect(initialRoute, '/abc');
          return <Route<void>>[
            PageRouteBuilder<void>(
              pageBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                  ) {
                    return const Text('non-regular page one');
                  },
            ),
            PageRouteBuilder<void>(
              pageBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                  ) {
                    return const Text('non-regular page two');
                  },
            ),
          ];
        },
        initialRoute: '/abc',
        routes: <String, WidgetBuilder>{
          '/': (BuildContext context) => const Text('regular page one'),
          '/abc': (BuildContext context) => const Text('regular page two'),
        },
      ),
    );
    expect(find.text('non-regular page two'), findsOneWidget);
    expect(find.text('non-regular page one'), findsNothing);
    expect(find.text('regular page one'), findsNothing);
    expect(find.text('regular page two'), findsNothing);
    navigatorKey.currentState!.pop();
    await tester.pumpAndSettle();
    expect(find.text('non-regular page two'), findsNothing);
    expect(find.text('non-regular page one'), findsOneWidget);
    expect(find.text('regular page one'), findsNothing);
    expect(find.text('regular page two'), findsNothing);
  });

  testWidgets('MaterialApp does create HeroController with the MaterialRectArcTween', (
    WidgetTester tester,
  ) async {
    final HeroController controller = MaterialApp.createMaterialHeroController();
    addTearDown(controller.dispose);
    final Tween<Rect?> tween = controller.createRectTween!(
      const Rect.fromLTRB(0.0, 0.0, 10.0, 10.0),
      const Rect.fromLTRB(0.0, 0.0, 20.0, 20.0),
    );
    expect(tween, isA<MaterialRectArcTween>());
  });

  testWidgets('MaterialApp.navigatorKey can be updated', (WidgetTester tester) async {
    final key1 = GlobalKey<NavigatorState>();
    await tester.pumpWidget(MaterialApp(navigatorKey: key1, home: const Placeholder()));
    expect(key1.currentState, isA<NavigatorState>());
    final key2 = GlobalKey<NavigatorState>();
    await tester.pumpWidget(MaterialApp(navigatorKey: key2, home: const Placeholder()));
    expect(key2.currentState, isA<NavigatorState>());
    expect(key1.currentState, isNull);
  });

  testWidgets('MaterialApp.router works', (WidgetTester tester) async {
    final provider = PlatformRouteInformationProvider(
      initialRouteInformation: RouteInformation(uri: Uri.parse('initial')),
    );
    addTearDown(provider.dispose);
    final delegate = SimpleNavigatorRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.uri.toString());
      },
      onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
        delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
        return route.didPop(result);
      },
    );
    addTearDown(delegate.dispose);
    await tester.pumpWidget(
      MaterialApp.router(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
      ),
    );
    expect(find.text('initial'), findsOneWidget);

    // Simulate android back button intent.
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await tester.binding.defaultBinaryMessenger.handlePlatformMessage(
      'flutter/navigation',
      message,
      (_) {},
    );
    await tester.pumpAndSettle();
    expect(find.text('popped'), findsOneWidget);
  });

  testWidgets('MaterialApp.router works with onNavigationNotification', (
    WidgetTester tester,
  ) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/139903.
    final provider = PlatformRouteInformationProvider(
      initialRouteInformation: RouteInformation(uri: Uri.parse('initial')),
    );
    addTearDown(provider.dispose);
    final delegate = SimpleNavigatorRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.uri.toString());
      },
      onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
        delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
        return route.didPop(result);
      },
    );
    addTearDown(delegate.dispose);

    var navigationCount = 0;

    await tester.pumpWidget(
      MaterialApp.router(
        routeInformationProvider: provider,
        routeInformationParser: SimpleRouteInformationParser(),
        routerDelegate: delegate,
        onNavigationNotification: (NavigationNotification? notification) {
          navigationCount += 1;
          return true;
        },
      ),
    );
    expect(find.text('initial'), findsOneWidget);

    expect(navigationCount, greaterThan(0));
    final navigationCountAfterBuild = navigationCount;

    // Simulate android back button intent.
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await tester.binding.defaultBinaryMessenger.handlePlatformMessage(
      'flutter/navigation',
      message,
      (_) {},
    );
    await tester.pumpAndSettle();
    expect(find.text('popped'), findsOneWidget);

    expect(navigationCount, greaterThan(navigationCountAfterBuild));
  });

  testWidgets('MaterialApp.router route information parser is optional', (
    WidgetTester tester,
  ) async {
    final delegate = SimpleNavigatorRouterDelegate(
      builder: (BuildContext context, RouteInformation information) {
        return Text(information.uri.toString());
      },
      onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
        delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
        return route.didPop(result);
      },
    );
    addTearDown(delegate.dispose);
    delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
    await tester.pumpWidget(MaterialApp.router(routerDelegate: delegate));
    expect(find.text('initial'), findsOneWidget);

    // Simulate android back button intent.
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await tester.binding.defaultBinaryMessenger.handlePlatformMessage(
      'flutter/navigation',
      message,
      (_) {},
    );
    await tester.pumpAndSettle();
    expect(find.text('popped'), findsOneWidget);
  });

  testWidgets(
    'MaterialApp.router throw if route information provider is provided but no route information parser',
    (WidgetTester tester) async {
      final delegate = SimpleNavigatorRouterDelegate(
        builder: (BuildContext context, RouteInformation information) {
          return Text(information.uri.toString());
        },
        onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
          delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
          return route.didPop(result);
        },
      );
      addTearDown(delegate.dispose);
      delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
      final provider = PlatformRouteInformationProvider(
        initialRouteInformation: RouteInformation(uri: Uri.parse('initial')),
      );
      await tester.pumpWidget(
        MaterialApp.router(routeInformationProvider: provider, routerDelegate: delegate),
      );
      expect(tester.takeException(), isAssertionError);
      provider.dispose();
    },
  );

  testWidgets(
    'MaterialApp.router throw if route configuration is provided along with other delegate',
    (WidgetTester tester) async {
      final delegate = SimpleNavigatorRouterDelegate(
        builder: (BuildContext context, RouteInformation information) {
          return Text(information.uri.toString());
        },
        onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
          delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
          return route.didPop(result);
        },
      );
      addTearDown(delegate.dispose);
      delegate.routeInformation = RouteInformation(uri: Uri.parse('initial'));
      final routerConfig = RouterConfig<RouteInformation>(routerDelegate: delegate);
      await tester.pumpWidget(
        MaterialApp.router(routerDelegate: delegate, routerConfig: routerConfig),
      );
      expect(tester.takeException(), isAssertionError);
    },
  );

  testWidgets('MaterialApp.router router config works', (WidgetTester tester) async {
    late SimpleNavigatorRouterDelegate routerDelegate;
    addTearDown(() => routerDelegate.dispose());
    late PlatformRouteInformationProvider provider;
    addTearDown(() => provider.dispose());
    final routerConfig = RouterConfig<RouteInformation>(
      routeInformationProvider: provider = PlatformRouteInformationProvider(
        initialRouteInformation: RouteInformation(uri: Uri.parse('initial')),
      ),
      routeInformationParser: SimpleRouteInformationParser(),
      routerDelegate: routerDelegate = SimpleNavigatorRouterDelegate(
        builder: (BuildContext context, RouteInformation information) {
          return Text(information.uri.toString());
        },
        onPopPage: (Route<void> route, void result, SimpleNavigatorRouterDelegate delegate) {
          delegate.routeInformation = RouteInformation(uri: Uri.parse('popped'));
          return route.didPop(result);
        },
      ),
      backButtonDispatcher: RootBackButtonDispatcher(),
    );
    await tester.pumpWidget(MaterialApp.router(routerConfig: routerConfig));
    expect(find.text('initial'), findsOneWidget);

    // Simulate android back button intent.
    final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
    await tester.binding.defaultBinaryMessenger.handlePlatformMessage(
      'flutter/navigation',
      message,
      (_) {},
    );
    await tester.pumpAndSettle();
    expect(find.text('popped'), findsOneWidget);
  });

  testWidgets('MaterialApp.builder can build app without a Navigator', (WidgetTester tester) async {
    Widget? builderChild;
    await tester.pumpWidget(
      MaterialApp(
        builder: (BuildContext context, Widget? child) {
          builderChild = child;
          return Container();
        },
      ),
    );
    expect(builderChild, isNull);
  });

  testWidgets('MaterialApp has correct default ScrollBehavior', (WidgetTester tester) async {
    late BuildContext capturedContext;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            capturedContext = context;
            return const Placeholder();
          },
        ),
      ),
    );
    expect(ScrollConfiguration.of(capturedContext).runtimeType, MaterialScrollBehavior);
  });

  testWidgets('MaterialApp has correct default KeyboardDismissBehavior', (
    WidgetTester tester,
  ) async {
    late BuildContext capturedContext;
    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            capturedContext = context;
            return const Placeholder();
          },
        ),
      ),
    );

    expect(
      ScrollConfiguration.of(capturedContext).getKeyboardDismissBehavior(capturedContext),
      ScrollViewKeyboardDismissBehavior.manual,
    );
  });

  testWidgets('MaterialApp can override default KeyboardDismissBehavior', (
    WidgetTester tester,
  ) async {
    late BuildContext capturedContext;
    await tester.pumpWidget(
      MaterialApp(
        scrollBehavior: const MaterialScrollBehavior().copyWith(
          keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
        ),
        home: Builder(
          builder: (BuildContext context) {
            capturedContext = context;
            return const Placeholder();
          },
        ),
      ),
    );

    expect(
      ScrollConfiguration.of(capturedContext).getKeyboardDismissBehavior(capturedContext),
      ScrollViewKeyboardDismissBehavior.onDrag,
    );
  });

  testWidgets('A ScrollBehavior can be set for MaterialApp', (WidgetTester tester) async {
    late BuildContext capturedContext;
    await tester.pumpWidget(
      MaterialApp(
        scrollBehavior: const MockScrollBehavior(),
        home: Builder(
          builder: (BuildContext context) {
            capturedContext = context;
            return const Placeholder();
          },
        ),
      ),
    );
    final ScrollBehavior scrollBehavior = ScrollConfiguration.of(capturedContext);
    expect(scrollBehavior.runtimeType, MockScrollBehavior);
    expect(
      scrollBehavior.getScrollPhysics(capturedContext).runtimeType,
      NeverScrollableScrollPhysics,
    );
  });

  testWidgets(
    'Material2 - ScrollBehavior default android overscroll indicator',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          theme: ThemeData(useMaterial3: false),
          scrollBehavior: const MaterialScrollBehavior(),
          home: ListView(
            children: const <Widget>[SizedBox(height: 1000.0, width: 1000.0, child: Text('Test'))],
          ),
        ),
      );

      expect(find.byType(StretchingOverscrollIndicator), findsNothing);
      expect(find.byType(GlowingOverscrollIndicator), findsOneWidget);
    },
    variant: TargetPlatformVariant.only(TargetPlatform.android),
  );

  testWidgets(
    'Material3 - ScrollBehavior default android overscroll indicator',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          scrollBehavior: const MaterialScrollBehavior(),
          home: ListView(
            children: const <Widget>[SizedBox(height: 1000.0, width: 1000.0, child: Text('Test'))],
          ),
        ),
      );

      expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
      expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    },
    variant: TargetPlatformVariant.only(TargetPlatform.android),
  );

  testWidgets(
    'MaterialScrollBehavior default stretch android overscroll indicator',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: ListView(
            children: const <Widget>[SizedBox(height: 1000.0, width: 1000.0, child: Text('Test'))],
          ),
        ),
      );

      expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
      expect(find.byType(GlowingOverscrollIndicator), findsNothing);
    },
    variant: TargetPlatformVariant.only(TargetPlatform.android),
  );

  testWidgets(
    'Overscroll indicator can be set by theme',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          // The current default is M3 and stretch overscroll, setting via the theme should override.
          theme: ThemeData().copyWith(useMaterial3: false),
          home: ListView(
            children: const <Widget>[SizedBox(height: 1000.0, width: 1000.0, child: Text('Test'))],
          ),
        ),
      );

      expect(find.byType(GlowingOverscrollIndicator), findsOneWidget);
      expect(find.byType(StretchingOverscrollIndicator), findsNothing);
    },
    variant: TargetPlatformVariant.only(TargetPlatform.android),
  );

  testWidgets(
    'Material3 - ListView clip behavior updates overscroll indicator clip behavior',
    (WidgetTester tester) async {
      Widget buildFrame(Clip clipBehavior) {
        return MaterialApp(
          home: Column(
            children: <Widget>[
              SizedBox(
                height: 300,
                child: ListView.builder(
                  itemCount: 20,
                  clipBehavior: clipBehavior,
                  itemBuilder: (BuildContext context, int index) {
                    return Padding(
                      padding: const EdgeInsets.all(10.0),
                      child: Text('Index $index'),
                    );
                  },
                ),
              ),
              Opacity(opacity: 0.5, child: Container(color: const Color(0xD0FF0000), height: 100)),
            ],
          ),
        );
      }

      // Test default clip behavior.
      await tester.pumpWidget(buildFrame(Clip.hardEdge));

      expect(find.byType(StretchingOverscrollIndicator), findsOneWidget);
      expect(find.byType(GlowingOverscrollIndicator), findsNothing);
      expect(find.text('Index 1'), findsOneWidget);

      RenderClipRect renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
      // Currently not clipping
      expect(renderClip.clipBehavior, equals(Clip.none));

      TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('Index 1')));
      // Overscroll the start.
      await gesture.moveBy(const Offset(0.0, 200.0));
      await tester.pumpAndSettle();
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(0));
      renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
      // Now clipping
      expect(renderClip.clipBehavior, equals(Clip.hardEdge));

      await gesture.up();
      await tester.pumpAndSettle();

      // Test custom clip behavior.
      await tester.pumpWidget(buildFrame(Clip.none));

      renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
      // Currently not clipping
      expect(renderClip.clipBehavior, equals(Clip.none));

      gesture = await tester.startGesture(tester.getCenter(find.text('Index 1')));
      // Overscroll the start.
      await gesture.moveBy(const Offset(0.0, 200.0));
      await tester.pumpAndSettle();
      expect(find.text('Index 1'), findsOneWidget);
      expect(tester.getCenter(find.text('Index 1')).dy, greaterThan(0));
      renderClip = tester.allRenderObjects.whereType<RenderClipRect>().first;
      // Now clipping
      expect(renderClip.clipBehavior, equals(Clip.none));

      await gesture.up();
      await tester.pumpAndSettle();
    },
    variant: TargetPlatformVariant.only(TargetPlatform.android),
  );

  testWidgets(
    'When `useInheritedMediaQuery` is true an existing MediaQuery is used if one is available',
    (WidgetTester tester) async {
      late BuildContext capturedContext;
      final uniqueKey = UniqueKey();
      await tester.pumpWidget(
        MediaQuery(
          key: uniqueKey,
          data: const MediaQueryData(),
          child: MaterialApp(
            useInheritedMediaQuery: true,
            builder: (BuildContext context, Widget? child) {
              capturedContext = context;
              return const Placeholder();
            },
            color: const Color(0xFF123456),
          ),
        ),
      );
      expect(capturedContext.dependOnInheritedWidgetOfExactType<MediaQuery>()?.key, uniqueKey);
    },
  );

  testWidgets(
    'Assert in buildScrollbar that controller != null when using it (vertical)',
    (WidgetTester tester) async {
      const ScrollBehavior defaultBehavior = MaterialScrollBehavior();
      late BuildContext capturedContext;

      await tester.pumpWidget(
        MaterialApp(
          home: ScrollConfiguration(
            // Avoid the default ones here.
            behavior: const MaterialScrollBehavior().copyWith(scrollbars: false),
            child: SingleChildScrollView(
              child: Builder(
                builder: (BuildContext context) {
                  capturedContext = context;
                  return Container(height: 1000.0);
                },
              ),
            ),
          ),
        ),
      );

      const details = ScrollableDetails(direction: AxisDirection.down);
      final Widget child = Container();

      switch (defaultTargetPlatform) {
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
          // Does not throw if we aren't using it.
          defaultBehavior.buildScrollbar(capturedContext, child, details);
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          expect(
            () {
              defaultBehavior.buildScrollbar(capturedContext, child, details);
            },
            throwsA(
              isA<AssertionError>().having(
                (AssertionError error) => error.toString(),
                'description',
                contains('details.controller != null'),
              ),
            ),
          );
      }
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets(
    'Assert in buildScrollbar that controller != null when using it (horizontal)',
    (WidgetTester tester) async {
      const ScrollBehavior defaultBehavior = MaterialScrollBehavior();
      late BuildContext capturedContext;

      await tester.pumpWidget(
        MaterialApp(
          home: ScrollConfiguration(
            // Avoid the default ones here.
            behavior: const MaterialScrollBehavior().copyWith(scrollbars: false),
            child: SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Builder(
                builder: (BuildContext context) {
                  capturedContext = context;
                  return Container(height: 1000.0);
                },
              ),
            ),
          ),
        ),
      );

      const details = ScrollableDetails(direction: AxisDirection.left);
      final Widget child = Container();

      switch (defaultTargetPlatform) {
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.iOS:
        case TargetPlatform.linux:
        case TargetPlatform.macOS:
        case TargetPlatform.windows:
          // Does not throw if we aren't using it.
          // Horizontal axis gets no scrollbars for all platforms.
          defaultBehavior.buildScrollbar(capturedContext, child, details);
      }
    },
    variant: TargetPlatformVariant.all(),
  );

  testWidgets('Override theme animation using AnimationStyle', (WidgetTester tester) async {
    final lightTheme = ThemeData();
    final darkTheme = ThemeData.dark();

    Widget buildWidget({ThemeMode themeMode = ThemeMode.light, AnimationStyle? animationStyle}) {
      return MaterialApp(
        theme: lightTheme,
        darkTheme: darkTheme,
        themeMode: themeMode,
        themeAnimationStyle: animationStyle,
        home: const Scaffold(body: Text('body')),
      );
    }

    // Test the initial Scaffold background color.
    await tester.pumpWidget(buildWidget());

    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(lightTheme.colorScheme.surface),
    );

    // Test the Scaffold background color animation from light to dark theme.
    await tester.pumpWidget(buildWidget(themeMode: ThemeMode.dark));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50)); // Advance animation by 50 milliseconds.

    // Scaffold background color is slightly updated.
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(const Color(0xffc3bdc5)),
    );

    // Let the animation finish.
    await tester.pumpAndSettle();

    // Scaffold background color is fully updated to dark theme.
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(darkTheme.colorScheme.surface),
    );

    // Reset to light theme to compare the Scaffold background color animation
    // with the default animation curve.
    await tester.pumpWidget(buildWidget());
    await tester.pumpAndSettle();

    // Switch to dark theme with overridden animation curve.
    await tester.pumpWidget(
      buildWidget(
        themeMode: ThemeMode.dark,
        animationStyle: const AnimationStyle(curve: Curves.easeIn),
      ),
    );
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));

    // Scaffold background color is slightly updated but with a different
    // color than the default animation curve.
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(const Color(0xffe7e1e9)),
    );

    // Let the animation finish.
    await tester.pumpAndSettle();

    // Scaffold background color is fully updated to dark theme.
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(darkTheme.colorScheme.surface),
    );

    // Switch from dark to light theme with overridden animation duration.
    await tester.pumpWidget(buildWidget(animationStyle: AnimationStyle.noAnimation));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 1));

    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isNot(darkTheme.colorScheme.surface),
    );
    expect(
      tester.widget<Material>(find.byType(Material)).color,
      isSameColorAs(lightTheme.colorScheme.surface),
    );
  });

  testWidgets('AnimationStyle.noAnimation removes AnimatedTheme from the tree', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(const MaterialApp(themeAnimationStyle: AnimationStyle()));

    expect(find.byType(AnimatedTheme), findsOneWidget);
    expect(find.byType(Theme), findsOneWidget);

    await tester.pumpWidget(const MaterialApp(themeAnimationStyle: AnimationStyle.noAnimation));

    expect(find.byType(AnimatedTheme), findsNothing);
    expect(find.byType(Theme), findsOneWidget);
  });

  // Regression test for https://github.com/flutter/flutter/issues/137875.
  testWidgets('MaterialApp works in an unconstrained environment', (WidgetTester tester) async {
    await tester.pumpWidget(
      const UnconstrainedBox(child: MaterialApp(home: SizedBox(width: 123, height: 456))),
    );

    expect(tester.getSize(find.byType(MaterialApp)), const Size(123, 456));
  });

  // Regression test for https://github.com/flutter/flutter/issues/156959.
  testWidgets(
    'MaterialApp with builder works when themeAnimationStyle is AnimationStyle.noAnimation',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          themeAnimationStyle: AnimationStyle.noAnimation,
          builder: (BuildContext context, Widget? child) {
            return const Text('Works');
          },
        ),
      );
      expect(find.text('Works'), findsOne);
    },
  );

  testWidgets('MaterialApp does not crash at zero area', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Center(
        child: SizedBox.shrink(child: MaterialApp(home: Text('X'))),
      ),
    );
    expect(tester.getSize(find.byType(MaterialApp)), Size.zero);
  });
}

class MockScrollBehavior extends ScrollBehavior {
  const MockScrollBehavior();

  @override
  ScrollPhysics getScrollPhysics(BuildContext context) => const NeverScrollableScrollPhysics();
}

typedef SimpleRouterDelegateBuilder =
    Widget Function(BuildContext context, RouteInformation information);
typedef SimpleNavigatorRouterDelegatePopPage<T> =
    bool Function(Route<T> route, T result, SimpleNavigatorRouterDelegate delegate);

class SimpleRouteInformationParser extends RouteInformationParser<RouteInformation> {
  SimpleRouteInformationParser();

  @override
  Future<RouteInformation> parseRouteInformation(RouteInformation information) {
    return SynchronousFuture<RouteInformation>(information);
  }

  @override
  RouteInformation restoreRouteInformation(RouteInformation configuration) {
    return configuration;
  }
}

class SimpleNavigatorRouterDelegate extends RouterDelegate<RouteInformation>
    with PopNavigatorRouterDelegateMixin<RouteInformation>, ChangeNotifier {
  SimpleNavigatorRouterDelegate({required this.builder, required this.onPopPage}) {
    ChangeNotifier.maybeDispatchObjectCreation(this);
  }

  @override
  GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  RouteInformation get routeInformation => _routeInformation;
  late RouteInformation _routeInformation;
  set routeInformation(RouteInformation newValue) {
    _routeInformation = newValue;
    notifyListeners();
  }

  SimpleRouterDelegateBuilder builder;
  SimpleNavigatorRouterDelegatePopPage<void> onPopPage;

  @override
  Future<void> setNewRoutePath(RouteInformation configuration) {
    _routeInformation = configuration;
    return SynchronousFuture<void>(null);
  }

  bool _handlePopPage(Route<void> route, void data) {
    return onPopPage(route, data, this);
  }

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      onPopPage: _handlePopPage,
      pages: <Page<void>>[
        // We need at least two pages for the pop to propagate through.
        // Otherwise, the navigator will bubble the pop to the system navigator.
        const MaterialPage<void>(child: Text('base')),
        MaterialPage<void>(
          key: ValueKey<String>(routeInformation.uri.toString()),
          child: builder(context, routeInformation),
        ),
      ],
    );
  }
}
