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

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_test/flutter_test.dart';

class TestLocalizations {
  TestLocalizations(this.locale, this.prefix);

  final Locale locale;
  final String? prefix;

  static Future<TestLocalizations> loadSync(Locale locale, String? prefix) {
    return SynchronousFuture<TestLocalizations>(TestLocalizations(locale, prefix));
  }

  static Future<TestLocalizations> loadAsync(Locale locale, String? prefix) {
    return Future<TestLocalizations>.delayed(
      const Duration(milliseconds: 100),
      () => TestLocalizations(locale, prefix),
    );
  }

  static TestLocalizations of(BuildContext context) {
    return Localizations.of<TestLocalizations>(context, TestLocalizations)!;
  }

  String get message => '${prefix ?? ""}$locale';
}

class SyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizations> {
  SyncTestLocalizationsDelegate([this.prefix]);

  final String? prefix; // Changing this value triggers a rebuild
  final List<bool> shouldReloadValues = <bool>[];

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<TestLocalizations> load(Locale locale) => TestLocalizations.loadSync(locale, prefix);

  @override
  bool shouldReload(SyncTestLocalizationsDelegate old) {
    shouldReloadValues.add(prefix != old.prefix);
    return prefix != old.prefix;
  }

  @override
  String toString() => '${objectRuntimeType(this, 'SyncTestLocalizationsDelegate')}($prefix)';
}

class AsyncTestLocalizationsDelegate extends LocalizationsDelegate<TestLocalizations> {
  AsyncTestLocalizationsDelegate([this.prefix]);

  final String? prefix; // Changing this value triggers a rebuild
  final List<bool> shouldReloadValues = <bool>[];

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<TestLocalizations> load(Locale locale) => TestLocalizations.loadAsync(locale, prefix);

  @override
  bool shouldReload(AsyncTestLocalizationsDelegate old) {
    shouldReloadValues.add(prefix != old.prefix);
    return prefix != old.prefix;
  }

  @override
  String toString() => '${objectRuntimeType(this, 'AsyncTestLocalizationsDelegate')}($prefix)';
}

class MoreLocalizations {
  MoreLocalizations(this.locale);

  final Locale locale;

  static Future<MoreLocalizations> loadSync(Locale locale) {
    return SynchronousFuture<MoreLocalizations>(MoreLocalizations(locale));
  }

  static Future<MoreLocalizations> loadAsync(Locale locale) {
    return Future<MoreLocalizations>.delayed(
      const Duration(milliseconds: 100),
      () => MoreLocalizations(locale),
    );
  }

  static MoreLocalizations of(BuildContext context) {
    return Localizations.of<MoreLocalizations>(context, MoreLocalizations)!;
  }

  String get message => '$locale';
}

class SyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizations> {
  @override
  Future<MoreLocalizations> load(Locale locale) => MoreLocalizations.loadSync(locale);

  @override
  bool isSupported(Locale locale) => true;

  @override
  bool shouldReload(SyncMoreLocalizationsDelegate old) => false;
}

class AsyncMoreLocalizationsDelegate extends LocalizationsDelegate<MoreLocalizations> {
  @override
  Future<MoreLocalizations> load(Locale locale) => MoreLocalizations.loadAsync(locale);

  @override
  bool isSupported(Locale locale) => true;

  @override
  bool shouldReload(AsyncMoreLocalizationsDelegate old) => false;
}

class OnlyRTLDefaultWidgetsLocalizations extends DefaultWidgetsLocalizations {
  @override
  TextDirection get textDirection => TextDirection.rtl;
}

class OnlyRTLDefaultWidgetsLocalizationsDelegate
    extends LocalizationsDelegate<WidgetsLocalizations> {
  const OnlyRTLDefaultWidgetsLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<WidgetsLocalizations> load(Locale locale) {
    return SynchronousFuture<WidgetsLocalizations>(OnlyRTLDefaultWidgetsLocalizations());
  }

  @override
  bool shouldReload(OnlyRTLDefaultWidgetsLocalizationsDelegate old) => false;
}

Widget buildFrame({
  Locale? locale,
  Iterable<LocalizationsDelegate<dynamic>>? delegates,
  required WidgetBuilder buildContent,
  LocaleResolutionCallback? localeResolutionCallback,
  List<Locale> supportedLocales = const <Locale>[Locale('en', 'US'), Locale('en', 'GB')],
}) {
  return WidgetsApp(
    color: const Color(0xFFFFFFFF),
    locale: locale,
    localizationsDelegates: delegates,
    localeResolutionCallback: localeResolutionCallback,
    supportedLocales: supportedLocales,
    onGenerateRoute: (RouteSettings settings) {
      return PageRouteBuilder<void>(
        pageBuilder: (BuildContext context, Animation<double> _, Animation<double> _) {
          return buildContent(context);
        },
      );
    },
  );
}

class SyncLoadTest extends StatefulWidget {
  const SyncLoadTest({super.key});

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

class SyncLoadTestState extends State<SyncLoadTest> {
  @override
  Widget build(BuildContext context) {
    return Text(TestLocalizations.of(context).message, textDirection: TextDirection.rtl);
  }
}

void main() {
  testWidgets('Localizations.localeFor in a WidgetsApp with system locale', (
    WidgetTester tester,
  ) async {
    late BuildContext pageContext;

    await tester.pumpWidget(
      buildFrame(
        buildContent: (BuildContext context) {
          pageContext = context;
          return const Text('Hello World', textDirection: TextDirection.ltr);
        },
      ),
    );

    await tester.binding.setLocale('en', 'GB');
    await tester.pump();
    expect(Localizations.localeOf(pageContext), const Locale('en', 'GB'));

    await tester.binding.setLocale('en', 'US');
    await tester.pump();
    expect(Localizations.localeOf(pageContext), const Locale('en', 'US'));
  });

  testWidgets('Localizations.localeFor in a WidgetsApp with an explicit locale', (
    WidgetTester tester,
  ) async {
    const locale = Locale('en', 'US');
    late BuildContext pageContext;

    await tester.pumpWidget(
      buildFrame(
        locale: locale,
        buildContent: (BuildContext context) {
          pageContext = context;
          return const Text('Hello World');
        },
      ),
    );

    expect(Localizations.localeOf(pageContext), locale);

    await tester.binding.setLocale('en', 'GB');
    await tester.pump();

    // The WidgetApp's explicit locale overrides the system's locale.
    expect(Localizations.localeOf(pageContext), locale);
  });

  testWidgets('Synchronously loaded localizations in a WidgetsApp', (WidgetTester tester) async {
    final delegates = <LocalizationsDelegate<dynamic>>[
      SyncTestLocalizationsDelegate(),
      DefaultWidgetsLocalizations.delegate,
    ];

    Future<void> pumpTest(Locale locale) async {
      await tester.pumpWidget(
        Localizations(locale: locale, delegates: delegates, child: const SyncLoadTest()),
      );
    }

    await pumpTest(const Locale('en', 'US'));
    expect(find.text('en_US'), findsOneWidget);

    await pumpTest(const Locale('en', 'GB'));
    await tester.pump();
    expect(find.text('en_GB'), findsOneWidget);

    await pumpTest(const Locale('en', 'US'));
    await tester.pump();
    expect(find.text('en_US'), findsOneWidget);
  });

  testWidgets('Asynchronously loaded localizations in a WidgetsApp', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[AsyncTestLocalizationsDelegate()],
        buildContent: (BuildContext context) {
          return Text(TestLocalizations.of(context).message);
        },
      ),
    );
    await tester.pump(
      const Duration(milliseconds: 50),
    ); // TestLocalizations.loadAsync() takes 100ms
    expect(find.text('en_US'), findsNothing); // TestLocalizations hasn't been loaded yet

    await tester.pump(const Duration(milliseconds: 50)); // TestLocalizations.loadAsync() completes
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget); // default test locale is US english

    await tester.binding.setLocale('en', 'GB');
    await tester.pump(const Duration(milliseconds: 100));
    await tester.pumpAndSettle();
    expect(find.text('en_GB'), findsOneWidget);

    await tester.binding.setLocale('en', 'US');
    await tester.pump(const Duration(milliseconds: 50));
    // TestLocalizations.loadAsync() hasn't completed yet so the old text
    // localization is still displayed
    expect(find.text('en_GB'), findsOneWidget);
    await tester.pump(const Duration(milliseconds: 50)); // finish the async load
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);
  });

  testWidgets('Localizations with multiple sync delegates', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          SyncTestLocalizationsDelegate(),
          SyncMoreLocalizationsDelegate(),
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    // All localizations were loaded synchronously
    expect(find.text('A: en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);
  });

  testWidgets('Localizations with multiple delegates', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          SyncTestLocalizationsDelegate(),
          AsyncMoreLocalizationsDelegate(), // No resources until this completes
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    await tester.pump(const Duration(milliseconds: 50));
    expect(find.text('A: en_US'), findsNothing); // MoreLocalizations.load() hasn't completed yet
    expect(find.text('B: en_US'), findsNothing);

    await tester.pump(const Duration(milliseconds: 50));
    await tester.pumpAndSettle();

    expect(find.text('A: en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);
  });

  testWidgets('Multiple Localizations', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[SyncTestLocalizationsDelegate()],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Localizations(
                locale: const Locale('en', 'GB'),
                delegates: <LocalizationsDelegate<dynamic>>[
                  SyncTestLocalizationsDelegate(),
                  DefaultWidgetsLocalizations.delegate,
                ],
                // Create a new context within the en_GB Localization
                child: Builder(
                  builder: (BuildContext context) {
                    return Text('B: ${TestLocalizations.of(context).message}');
                  },
                ),
              ),
            ],
          );
        },
      ),
    );

    expect(find.text('A: en_US'), findsOneWidget);
    expect(find.text('B: en_GB'), findsOneWidget);
  });

  // If both the locale and the length and type of a Localizations delegate list
  // stays the same BUT one of its delegate.shouldReload() methods returns true,
  // then the dependent widgets should rebuild.
  testWidgets('Localizations sync delegate shouldReload returns true', (WidgetTester tester) async {
    final originalDelegate = SyncTestLocalizationsDelegate();
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          originalDelegate,
          SyncMoreLocalizationsDelegate(),
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('A: en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);
    expect(originalDelegate.shouldReloadValues, <bool>[]);

    final modifiedDelegate = SyncTestLocalizationsDelegate('---');
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          modifiedDelegate,
          SyncMoreLocalizationsDelegate(),
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('A: ---en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);
    expect(modifiedDelegate.shouldReloadValues, <bool>[true]);
    expect(originalDelegate.shouldReloadValues, <bool>[]);
  });

  testWidgets('Localizations async delegate shouldReload returns true', (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          AsyncTestLocalizationsDelegate(),
          AsyncMoreLocalizationsDelegate(),
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('A: en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);

    final modifiedDelegate = AsyncTestLocalizationsDelegate('---');
    await tester.pumpWidget(
      buildFrame(
        delegates: <LocalizationsDelegate<dynamic>>[
          modifiedDelegate,
          AsyncMoreLocalizationsDelegate(),
        ],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Column(
            children: <Widget>[
              Text('A: ${TestLocalizations.of(context).message}'),
              Text('B: ${MoreLocalizations.of(context).message}'),
            ],
          );
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('A: ---en_US'), findsOneWidget);
    expect(find.text('B: en_US'), findsOneWidget);
    expect(modifiedDelegate.shouldReloadValues, <bool>[true]);
  });

  testWidgets('Directionality tracks system locale', (WidgetTester tester) async {
    late BuildContext pageContext;

    await tester.pumpWidget(
      buildFrame(
        delegates: const <LocalizationsDelegate<dynamic>>[GlobalWidgetsLocalizations.delegate],
        supportedLocales: const <Locale>[Locale('en', 'GB'), Locale('ar', 'EG')],
        buildContent: (BuildContext context) {
          pageContext = context;
          return const Text('Hello World');
        },
      ),
    );

    await tester.binding.setLocale('en', 'GB');
    await tester.pump();
    expect(Directionality.of(pageContext), TextDirection.ltr);

    await tester.binding.setLocale('ar', 'EG');
    await tester.pump();
    expect(Directionality.of(pageContext), TextDirection.rtl);
  });

  testWidgets('localeResolutionCallback override', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        localeResolutionCallback: (Locale? newLocale, Iterable<Locale> supportedLocales) {
          return const Locale('foo', 'BAR');
        },
        buildContent: (BuildContext context) {
          return Text(Localizations.localeOf(context).toString());
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('foo_BAR'), findsOneWidget);

    await tester.binding.setLocale('en', 'GB');
    await tester.pumpAndSettle();
    expect(find.text('foo_BAR'), findsOneWidget);
  });

  testWidgets('supportedLocales and defaultLocaleChangeHandler', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('zh', 'CN'),
          Locale('en', 'GB'),
          Locale('en', 'CA'),
        ],
        buildContent: (BuildContext context) {
          return Text(Localizations.localeOf(context).toString());
        },
      ),
    );

    await tester.pumpAndSettle();
    expect(find.text('en_GB'), findsOneWidget);

    // defaultLocaleChangedHandler prefers exact supported locale match
    await tester.binding.setLocale('en', 'CA');
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);

    // defaultLocaleChangedHandler chooses 1st matching supported locale.languageCode
    await tester.binding.setLocale('en', 'US');
    await tester.pumpAndSettle();
    expect(find.text('en_GB'), findsOneWidget);

    // defaultLocaleChangedHandler: no matching supported locale, so use the 1st one
    await tester.binding.setLocale('da', 'DA');
    await tester.pumpAndSettle();
    expect(find.text('zh_CN'), findsOneWidget);
  });

  testWidgets("Localizations.override widget tracks parent's locale and delegates", (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      buildFrame(
        // Accept whatever locale we're given
        localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) => locale,
        delegates: const <LocalizationsDelegate<dynamic>>[GlobalWidgetsLocalizations.delegate],
        buildContent: (BuildContext context) {
          return Localizations.override(
            context: context,
            child: Builder(
              builder: (BuildContext context) {
                final Locale locale = Localizations.localeOf(context);
                final TextDirection direction = WidgetsLocalizations.of(context).textDirection;
                return Text('$locale $direction');
              },
            ),
          );
        },
      ),
    );

    // Initial WidgetTester locale is `en_US`.
    await tester.pumpAndSettle();
    expect(find.text('en_US TextDirection.ltr'), findsOneWidget);

    await tester.binding.setLocale('en', 'CA');
    await tester.pumpAndSettle();
    expect(find.text('en_CA TextDirection.ltr'), findsOneWidget);

    await tester.binding.setLocale('ar', 'EG');
    await tester.pumpAndSettle();
    expect(find.text('ar_EG TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('da', 'DA');
    await tester.pumpAndSettle();
    expect(find.text('da_DA TextDirection.ltr'), findsOneWidget);
  });

  testWidgets("Localizations.override widget overrides parent's DefaultWidgetLocalizations", (
    WidgetTester tester,
  ) async {
    await tester.pumpWidget(
      buildFrame(
        // Accept whatever locale we're given
        localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) => locale,
        buildContent: (BuildContext context) {
          return Localizations.override(
            context: context,
            delegates: const <OnlyRTLDefaultWidgetsLocalizationsDelegate>[
              // Override: no matter what the locale, textDirection is always RTL.
              OnlyRTLDefaultWidgetsLocalizationsDelegate(),
            ],
            child: Builder(
              builder: (BuildContext context) {
                final Locale locale = Localizations.localeOf(context);
                final TextDirection direction = WidgetsLocalizations.of(context).textDirection;
                return Text('$locale $direction');
              },
            ),
          );
        },
      ),
    );

    // Initial WidgetTester locale is `en_US`.
    await tester.pumpAndSettle();
    expect(find.text('en_US TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('en', 'CA');
    await tester.pumpAndSettle();
    expect(find.text('en_CA TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('ar', 'EG');
    await tester.pumpAndSettle();
    expect(find.text('ar_EG TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('da', 'DA');
    await tester.pumpAndSettle();
    expect(find.text('da_DA TextDirection.rtl'), findsOneWidget);
  });

  testWidgets('WidgetsApp overrides DefaultWidgetLocalizations', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        // Accept whatever locale we're given
        localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) => locale,
        delegates: <OnlyRTLDefaultWidgetsLocalizationsDelegate>[
          const OnlyRTLDefaultWidgetsLocalizationsDelegate(),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          final TextDirection direction = WidgetsLocalizations.of(context).textDirection;
          return Text('$locale $direction');
        },
      ),
    );

    // Initial WidgetTester locale is `en_US`.
    await tester.pumpAndSettle();
    expect(find.text('en_US TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('en', 'CA');
    await tester.pumpAndSettle();
    expect(find.text('en_CA TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('ar', 'EG');
    await tester.pumpAndSettle();
    expect(find.text('ar_EG TextDirection.rtl'), findsOneWidget);

    await tester.binding.setLocale('da', 'DA');
    await tester.pumpAndSettle();
    expect(find.text('da_DA TextDirection.rtl'), findsOneWidget);
  });

  // We provide <Locale>[Locale('en', 'US'), Locale('zh', 'CN')] as ui.window.locales
  // for flutter tester so that the behavior of tests match that of production
  // environments. Here, we test the default locales.
  testWidgets('WidgetsApp DefaultWidgetLocalizations', (WidgetTester tester) async {
    await tester.pumpAndSettle();
    await tester.pumpWidget(
      buildFrame(
        // Accept whatever locale we're given
        localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) => locale,
        delegates: <OnlyRTLDefaultWidgetsLocalizationsDelegate>[
          const OnlyRTLDefaultWidgetsLocalizationsDelegate(),
        ],
        buildContent: (BuildContext context) {
          final Locale locale1 = WidgetsBinding.instance.platformDispatcher.locales.first;
          final Locale locale2 = WidgetsBinding.instance.platformDispatcher.locales[1];
          return Text('$locale1 $locale2');
        },
      ),
    );
    // Initial WidgetTester default locales is `en_US` and `zh_CN`.
    await tester.pumpAndSettle();
    expect(find.text('en_US zh_CN'), findsOneWidget);
  });

  testWidgets('WidgetsApp.locale is resolved against supportedLocales', (
    WidgetTester tester,
  ) async {
    // app locale matches a supportedLocale
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[Locale('zh', 'CN'), Locale('en', 'US')],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Text(Localizations.localeOf(context).toString());
        },
      ),
    );
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    // app locale matches a supportedLocale's language
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[Locale('zh', 'CN'), Locale('en', 'GB')],
        locale: const Locale('en', 'US'),
        buildContent: (BuildContext context) {
          return Text(Localizations.localeOf(context).toString());
        },
      ),
    );
    await tester.pumpAndSettle();
    expect(find.text('en_GB'), findsOneWidget);

    // app locale matches no supportedLocale
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[Locale('zh', 'CN'), Locale('en', 'US')],
        locale: const Locale('ab', 'CD'),
        buildContent: (BuildContext context) {
          return Text(Localizations.localeOf(context).toString());
        },
      ),
    );
    await tester.pumpAndSettle();
    expect(find.text('zh_CN'), findsOneWidget);
  });

  // Example from http://unicode.org/reports/tr35/#LanguageMatching
  testWidgets('WidgetsApp Unicode tr35 1', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[Locale('de'), Locale('fr'), Locale('ja')],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'de', countryCode: 'AT'),
      Locale.fromSubtags(languageCode: 'fr'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('de'), findsOneWidget);
  });

  // Examples from http://unicode.org/reports/tr35/#LanguageMatching
  testWidgets('WidgetsApp Unicode tr35 2', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[Locale('ja', 'JP'), Locale('de'), Locale('zh', 'TW')],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );
    await tester.binding.setLocales(const <Locale>[Locale.fromSubtags(languageCode: 'zh')]);
    await tester.pumpAndSettle();
    expect(find.text('zh_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'de'),
      Locale.fromSubtags(languageCode: 'fr'),
      Locale.fromSubtags(languageCode: 'de', countryCode: 'SW'),
      Locale.fromSubtags(languageCode: 'it'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('de'), findsOneWidget);
  });

  testWidgets('WidgetsApp EdgeCase Chinese', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale.fromSubtags(languageCode: 'zh'),
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'HK'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'de'),
      Locale.fromSubtags(languageCode: 'fr'),
      Locale.fromSubtags(languageCode: 'de', countryCode: 'SW'),
      Locale.fromSubtags(languageCode: 'zh'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh'), findsOneWidget);

    // This behavior is up to the implementer to decide if a perfect scriptCode match
    // is better than a countryCode match.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'CN'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    // languageCode only match is not enough to prevent resolving a perfect match
    // further down the preferredLocales list.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'JP'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    // When no language match, we try for country only, since it is likely users are
    // at least familiar with their country's language. This is a possible case only
    // on iOS, where countryCode can be selected independently from language and script.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', scriptCode: 'Hans', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);
  });

  // Same as 'WidgetsApp EdgeCase Chinese' test except the supportedLocales order is
  // reversed.
  testWidgets('WidgetsApp EdgeCase ReverseChinese', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'HK'),
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
          Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
          Locale.fromSubtags(languageCode: 'zh'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'de'),
      Locale.fromSubtags(languageCode: 'fr'),
      Locale.fromSubtags(languageCode: 'de', countryCode: 'SW'),
      Locale.fromSubtags(languageCode: 'zh'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    // This behavior is up to the implementer to decide if a perfect scriptCode match
    // is better than a countryCode match.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'CN'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);

    // languageCode only match is not enough to prevent resolving a perfect match
    // further down the preferredLocales list.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'JP'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'zh', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
      Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans', countryCode: 'CN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hans_CN'), findsOneWidget);

    // When no language match, we try for country only, since it is likely users are
    // at least familiar with their country's language. This is a possible case only
    // on iOS, where countryCode can be selected independently from language and script.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', scriptCode: 'Hans', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'TW'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_TW'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'HK'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('zh_Hant_HK'), findsOneWidget);
  });

  // Examples from https://developer.android.com/guide/topics/resources/multilingual-support
  testWidgets('WidgetsApp Android', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('en'),
          Locale('de', 'DE'),
          Locale('es', 'ES'),
          Locale('fr', 'FR'),
          Locale('it', 'IT'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'fr', countryCode: 'CH'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('fr_FR'), findsOneWidget);
  });

  // Examples from https://developer.android.com/guide/topics/resources/multilingual-support
  testWidgets('WidgetsApp Android', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('en'),
          Locale('de', 'DE'),
          Locale('es', 'ES'),
          Locale('it', 'IT'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'fr', countryCode: 'CH'),
      Locale.fromSubtags(languageCode: 'it', countryCode: 'CH'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('it_IT'), findsOneWidget);
  });

  testWidgets('WidgetsApp Country-only fallback', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('en', 'US'),
          Locale('de', 'DE'),
          Locale('de', 'AU'),
          Locale('de', 'LU'),
          Locale('de', 'CH'),
          Locale('es', 'ES'),
          Locale('es', 'US'),
          Locale('it', 'IT'),
          Locale('zh', 'CN'),
          Locale('zh', 'TW'),
          Locale('fr', 'FR'),
          Locale('br', 'FR'),
          Locale('pt', 'BR'),
          Locale('pt', 'PT'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'CH'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('de_CH'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'FR'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('fr_FR'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'es', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('es_US'), findsOneWidget);

    // Strongly prefer matching first locale even if next one is perfect.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'pt'),
      Locale.fromSubtags(languageCode: 'pt', countryCode: 'PT'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('pt_PT'), findsOneWidget);

    // Don't country match with any other available match. This behavior is
    // up for reconsideration.
    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'BR'),
      Locale.fromSubtags(languageCode: 'pt'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('pt_BR'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'BR'),
      Locale.fromSubtags(languageCode: 'pt', countryCode: 'PT'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('pt_PT'), findsOneWidget);
  });

  // Simulates a Chinese-default app that supports english in Canada but not
  // French. French-Canadian users should get 'en_CA' instead of Chinese.
  testWidgets('WidgetsApp Multilingual country', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('zh', 'CN'),
          Locale('en', 'CA'),
          Locale('en', 'US'),
          Locale('en', 'AU'),
          Locale('de', 'DE'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'fr', countryCode: 'CA'),
      Locale.fromSubtags(languageCode: 'fr'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);
  });

  testWidgets('WidgetsApp Common cases', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        // Decently well localized app.
        supportedLocales: const <Locale>[
          Locale('en', 'US'),
          Locale('en', 'GB'),
          Locale('en', 'AU'),
          Locale('en', 'CA'),
          Locale('zh', 'CN'),
          Locale('zh', 'TW'),
          Locale('de', 'DE'),
          Locale('de', 'CH'),
          Locale('es', 'MX'),
          Locale('es', 'ES'),
          Locale('es', 'AR'),
          Locale('es', 'CO'),
          Locale('ru', 'RU'),
          Locale('fr', 'FR'),
          Locale('fr', 'CA'),
          Locale('ar', 'SA'),
          Locale('ar', 'EG'),
          Locale('ar', 'IQ'),
          Locale('ar', 'MA'),
          Locale('af'),
          Locale('bg'),
          Locale('nl', 'NL'),
          Locale('pl'),
          Locale('cs'),
          Locale('fa'),
          Locale('el'),
          Locale('he'),
          Locale('hi'),
          Locale('pa'),
          Locale('ta'),
          Locale('id'),
          Locale('it', 'IT'),
          Locale('ja'),
          Locale('ko'),
          Locale('ms'),
          Locale('mn'),
          Locale('pt', 'BR'),
          Locale('pt', 'PT'),
          Locale('sv', 'SE'),
          Locale('th'),
          Locale('tr'),
          Locale('vi'),
        ],
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[Locale.fromSubtags(languageCode: 'en')]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'CA'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'AU'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_AU'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'CH'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('ar_SA'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[Locale.fromSubtags(languageCode: 'ar')]);
    await tester.pumpAndSettle();
    expect(find.text('ar_SA'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ar', countryCode: 'IQ'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('ar_IQ'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'es', countryCode: 'ES'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('es_ES'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[Locale.fromSubtags(languageCode: 'es')]);
    await tester.pumpAndSettle();
    expect(find.text('es_MX'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'pa', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('pa'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'hi', countryCode: 'IN'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('hi'), findsOneWidget);

    // Multiple preferred locales:

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'NZ'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'AU'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'GB'),
      Locale.fromSubtags(languageCode: 'en'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_AU'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'ab'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'NZ'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'AU'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'GB'),
      Locale.fromSubtags(languageCode: 'en'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_AU'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'NZ'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'PH'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'ZA'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'CB'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'CA'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'AU'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'GB'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'da'),
      Locale.fromSubtags(languageCode: 'en'),
      Locale.fromSubtags(languageCode: 'en', countryCode: 'CA'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'da'),
      Locale.fromSubtags(languageCode: 'fo'),
      Locale.fromSubtags(languageCode: 'hr'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'da'),
      Locale.fromSubtags(languageCode: 'fo'),
      Locale.fromSubtags(languageCode: 'hr', countryCode: 'CA'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_CA'), findsOneWidget);
  });

  testWidgets('WidgetsApp invalid preferredLocales', (WidgetTester tester) async {
    await tester.pumpWidget(
      buildFrame(
        supportedLocales: const <Locale>[
          Locale('zh', 'CN'),
          Locale('en', 'CA'),
          Locale('en', 'US'),
          Locale('en', 'AU'),
          Locale('de', 'DE'),
        ],
        localeResolutionCallback: (Locale? locale, Iterable<Locale> supportedLocales) {
          if (locale == null) {
            return const Locale('und', 'US');
          }
          return const Locale('en', 'US');
        },
        buildContent: (BuildContext context) {
          final Locale locale = Localizations.localeOf(context);
          return Text('$locale');
        },
      ),
    );

    await tester.binding.setLocales(const <Locale>[
      Locale.fromSubtags(languageCode: 'en', countryCode: 'US'),
    ]);
    await tester.pumpAndSettle();
    expect(find.text('en_US'), findsOneWidget);

    await tester.binding.setLocales(const <Locale>[]);
    await tester.pumpAndSettle();
    expect(find.text('und_US'), findsOneWidget);
  });
}
