"Fossies" - the Fresh Open Source Software Archive

Member "flutter-3.7.1/packages/flutter/test/material/about_test.dart" (1 Feb 2023, 33643 Bytes) of package /linux/misc/flutter-3.7.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Dart source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "about_test.dart": 3.3.10_vs_3.7.0.

    1 // Copyright 2014 The Flutter Authors. All rights reserved.
    2 // Use of this source code is governed by a BSD-style license that can be
    3 // found in the LICENSE file.
    4 
    5 import 'dart:async';
    6 import 'dart:ui';
    7 
    8 import 'package:flutter/cupertino.dart';
    9 import 'package:flutter/foundation.dart';
   10 import 'package:flutter/material.dart';
   11 import 'package:flutter_test/flutter_test.dart';
   12 
   13 void main() {
   14   tearDown(() {
   15     LicenseRegistry.reset();
   16   });
   17 
   18   testWidgets('Material3 has sentence case labels', (WidgetTester tester) async {
   19     await tester.pumpWidget(MaterialApp(
   20       theme: ThemeData(useMaterial3: true),
   21       builder: (BuildContext context, Widget? child) {
   22         return MediaQuery(
   23           // Display has a vertical hinge down the middle
   24           data: const MediaQueryData(
   25             size: Size(800, 600),
   26             displayFeatures: <DisplayFeature>[
   27               DisplayFeature(
   28                 bounds: Rect.fromLTRB(390, 0, 410, 600),
   29                 type: DisplayFeatureType.hinge,
   30                 state: DisplayFeatureState.unknown,
   31               ),
   32             ],
   33           ),
   34           child: child!,
   35         );
   36       },
   37       home: Builder(
   38         builder: (BuildContext context) => ElevatedButton(
   39           onPressed: () {
   40             showAboutDialog(
   41               context: context,
   42               useRootNavigator: false,
   43               applicationName: 'A',
   44             );
   45           },
   46           child: const Text('Show About Dialog'),
   47         ),
   48       ),
   49     ));
   50 
   51     // Open the dialog.
   52     await tester.tap(find.byType(ElevatedButton));
   53     await tester.pumpAndSettle();
   54     expect(find.text('Close'), findsOneWidget);
   55     expect(find.text('View licenses'), findsOneWidget);
   56   });
   57 
   58   testWidgets('AboutListTile control test', (WidgetTester tester) async {
   59     const FlutterLogo logo = FlutterLogo();
   60 
   61     await tester.pumpWidget(
   62       MaterialApp(
   63         title: 'Pirate app',
   64         home: Scaffold(
   65           appBar: AppBar(
   66             title: const Text('Home'),
   67           ),
   68           drawer: Drawer(
   69             child: ListView(
   70               children: const <Widget>[
   71                 AboutListTile(
   72                   applicationVersion: '0.1.2',
   73                   applicationIcon: logo,
   74                   applicationLegalese: 'I am the very model of a modern major general.',
   75                   aboutBoxChildren: <Widget>[
   76                     Text('About box'),
   77                   ],
   78                 ),
   79               ],
   80             ),
   81           ),
   82         ),
   83       ),
   84     );
   85 
   86     expect(find.text('About Pirate app'), findsNothing);
   87     expect(find.text('0.1.2'), findsNothing);
   88     expect(find.byWidget(logo), findsNothing);
   89     expect(
   90       find.text('I am the very model of a modern major general.'),
   91       findsNothing,
   92     );
   93     expect(find.text('About box'), findsNothing);
   94 
   95     await tester.tap(find.byType(IconButton));
   96     await tester.pumpAndSettle();
   97 
   98     expect(find.text('About Pirate app'), findsOneWidget);
   99     expect(find.text('0.1.2'), findsNothing);
  100     expect(find.byWidget(logo), findsNothing);
  101     expect(
  102       find.text('I am the very model of a modern major general.'),
  103       findsNothing,
  104     );
  105     expect(find.text('About box'), findsNothing);
  106 
  107     await tester.tap(find.text('About Pirate app'));
  108     await tester.pumpAndSettle();
  109 
  110     expect(find.text('About Pirate app'), findsOneWidget);
  111     expect(find.text('0.1.2'), findsOneWidget);
  112     expect(find.byWidget(logo), findsOneWidget);
  113     expect(
  114       find.text('I am the very model of a modern major general.'),
  115       findsOneWidget,
  116     );
  117     expect(find.text('About box'), findsOneWidget);
  118 
  119     LicenseRegistry.addLicense(() {
  120       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  121         const LicenseEntryWithLineBreaks(<String>['Pirate package '], 'Pirate license'),
  122       ]);
  123     });
  124 
  125     await tester.tap(find.text('VIEW LICENSES'));
  126     await tester.pumpAndSettle();
  127 
  128     expect(find.text('Pirate app'), findsOneWidget);
  129     expect(find.text('0.1.2'), findsOneWidget);
  130     expect(find.byWidget(logo), findsOneWidget);
  131     expect(
  132       find.text('I am the very model of a modern major general.'),
  133       findsOneWidget,
  134     );
  135     await tester.tap(find.text('Pirate package '));
  136     await tester.pumpAndSettle();
  137     expect(find.text('Pirate license'), findsOneWidget);
  138   });
  139 
  140   testWidgets('About box logic defaults to executable name for app name', (WidgetTester tester) async {
  141     await tester.pumpWidget(
  142       const MaterialApp(
  143         title: 'flutter_tester',
  144         home: Material(child: AboutListTile()),
  145       ),
  146     );
  147     expect(find.text('About flutter_tester'), findsOneWidget);
  148   });
  149 
  150   testWidgets('LicensePage control test', (WidgetTester tester) async {
  151     LicenseRegistry.addLicense(() {
  152       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  153         const LicenseEntryWithLineBreaks(<String>['AAA'], 'BBB'),
  154       ]);
  155     });
  156 
  157     LicenseRegistry.addLicense(() {
  158       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  159         const LicenseEntryWithLineBreaks(
  160           <String>['Another package'],
  161           'Another license',
  162         ),
  163       ]);
  164     });
  165 
  166     await tester.pumpWidget(
  167       const MaterialApp(
  168         home: Center(
  169           child: LicensePage(),
  170         ),
  171       ),
  172     );
  173 
  174     expect(find.text('AAA'), findsNothing);
  175     expect(find.text('BBB'), findsNothing);
  176     expect(find.text('Another package'), findsNothing);
  177     expect(find.text('Another license'), findsNothing);
  178 
  179     await tester.pumpAndSettle();
  180 
  181     // Check for packages.
  182     expect(find.text('AAA'), findsOneWidget);
  183     expect(find.text('Another package'), findsOneWidget);
  184 
  185     // Check license is displayed after entering into license page for 'AAA'.
  186     await tester.tap(find.text('AAA'));
  187     await tester.pumpAndSettle();
  188     expect(find.text('BBB'), findsOneWidget);
  189 
  190     /// Go back to list of packages.
  191     await tester.pageBack();
  192     await tester.pumpAndSettle();
  193 
  194     /// Check license is displayed after entering into license page for
  195     /// 'Another package'.
  196     await tester.tap(find.text('Another package'));
  197     await tester.pumpAndSettle();
  198     expect(find.text('Another license'), findsOneWidget);
  199   });
  200 
  201   testWidgets('LicensePage control test with all properties', (WidgetTester tester) async {
  202     const FlutterLogo logo = FlutterLogo();
  203 
  204     LicenseRegistry.addLicense(() {
  205       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  206         const LicenseEntryWithLineBreaks(<String>['AAA'], 'BBB'),
  207       ]);
  208     });
  209 
  210     LicenseRegistry.addLicense(() {
  211       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  212         const LicenseEntryWithLineBreaks(
  213           <String>['Another package'],
  214           'Another license',
  215         ),
  216       ]);
  217     });
  218 
  219     await tester.pumpWidget(
  220       const MaterialApp(
  221         title: 'Pirate app',
  222         home: Center(
  223           child: LicensePage(
  224             applicationName: 'LicensePage test app',
  225             applicationVersion: '0.1.2',
  226             applicationIcon: logo,
  227             applicationLegalese: 'I am the very model of a modern major general.',
  228           ),
  229         ),
  230       ),
  231     );
  232 
  233     expect(find.text('Pirate app'), findsNothing);
  234     expect(find.text('LicensePage test app'), findsOneWidget);
  235     expect(find.text('0.1.2'), findsOneWidget);
  236     expect(find.byWidget(logo), findsOneWidget);
  237     expect(
  238       find.text('I am the very model of a modern major general.'),
  239       findsOneWidget,
  240     );
  241     expect(find.text('AAA'), findsNothing);
  242     expect(find.text('BBB'), findsNothing);
  243     expect(find.text('Another package'), findsNothing);
  244     expect(find.text('Another license'), findsNothing);
  245 
  246     await tester.pumpAndSettle();
  247 
  248     expect(find.text('Pirate app'), findsNothing);
  249     expect(find.text('LicensePage test app'), findsOneWidget);
  250     expect(find.text('0.1.2'), findsOneWidget);
  251     expect(find.byWidget(logo), findsOneWidget);
  252     expect(
  253       find.text('I am the very model of a modern major general.'),
  254       findsOneWidget,
  255     );
  256 
  257     // Check for packages.
  258     expect(find.text('AAA'), findsOneWidget);
  259     expect(find.text('Another package'), findsOneWidget);
  260 
  261     // Check license is displayed after entering into license page for 'AAA'.
  262     await tester.tap(find.text('AAA'));
  263     await tester.pumpAndSettle();
  264     expect(find.text('BBB'), findsOneWidget);
  265 
  266     /// Go back to list of packages.
  267     await tester.pageBack();
  268     await tester.pumpAndSettle();
  269 
  270     /// Check license is displayed after entering into license page for
  271     /// 'Another package'.
  272     await tester.tap(find.text('Another package'));
  273     await tester.pumpAndSettle();
  274     expect(find.text('Another license'), findsOneWidget);
  275   });
  276 
  277   testWidgets('_PackageLicensePage title style without AppBarTheme', (WidgetTester tester) async {
  278     LicenseRegistry.addLicense(() {
  279       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  280         const LicenseEntryWithLineBreaks(<String>['AAA'], 'BBB'),
  281       ]);
  282     });
  283 
  284     const TextStyle titleTextStyle = TextStyle(
  285       fontSize: 20,
  286       color: Colors.black,
  287       inherit: false,
  288     );
  289     const TextStyle subtitleTextStyle = TextStyle(
  290       fontSize: 15,
  291       color: Colors.red,
  292       inherit: false,
  293     );
  294 
  295     await tester.pumpWidget(
  296       MaterialApp(
  297         theme: ThemeData(
  298           primaryTextTheme: const TextTheme(
  299             titleLarge: titleTextStyle,
  300             titleSmall: subtitleTextStyle,
  301           ),
  302         ),
  303         home: const Center(
  304           child: LicensePage(),
  305         ),
  306       ),
  307     );
  308     await tester.pumpAndSettle();
  309 
  310     // Check for packages.
  311     expect(find.text('AAA'), findsOneWidget);
  312 
  313     // Check license is displayed after entering into license page for 'AAA'.
  314     await tester.tap(find.text('AAA'));
  315     await tester.pumpAndSettle();
  316 
  317     // Check for titles style.
  318     final Text title = tester.widget(find.text('AAA'));
  319     expect(title.style, titleTextStyle);
  320     final Text subtitle = tester.widget(find.text('1 license.'));
  321     expect(subtitle.style, subtitleTextStyle);
  322   });
  323 
  324   testWidgets('_PackageLicensePage title style with AppBarTheme', (WidgetTester tester) async {
  325     LicenseRegistry.addLicense(() {
  326       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  327         const LicenseEntryWithLineBreaks(<String>['AAA'], 'BBB'),
  328       ]);
  329     });
  330 
  331     const TextStyle titleTextStyle = TextStyle(
  332       fontSize: 20,
  333       color: Colors.indigo,
  334     );
  335     const TextStyle subtitleTextStyle = TextStyle(
  336       fontSize: 15,
  337       color: Colors.indigo,
  338     );
  339 
  340     await tester.pumpWidget(
  341       MaterialApp(
  342         theme: ThemeData(
  343           // Not used because appBarTheme is prioritized.
  344           primaryTextTheme: const TextTheme(
  345             titleLarge: TextStyle(
  346               fontSize: 12,
  347               color: Colors.grey,
  348             ),
  349             titleSmall: TextStyle(
  350               fontSize: 10,
  351               color: Colors.grey,
  352             ),
  353           ),
  354           appBarTheme: const AppBarTheme(
  355             textTheme: TextTheme(
  356               titleLarge: titleTextStyle,
  357               titleSmall: subtitleTextStyle,
  358             ),
  359             foregroundColor: Colors.indigo,
  360           ),
  361         ),
  362         home: const Center(
  363           child: LicensePage(),
  364         ),
  365       ),
  366     );
  367     await tester.pumpAndSettle();
  368 
  369     // Check for packages.
  370     expect(find.text('AAA'), findsOneWidget);
  371 
  372     // Check license is displayed after entering into license page for 'AAA'.
  373     await tester.tap(find.text('AAA'));
  374     await tester.pumpAndSettle();
  375 
  376     // Check for titles style.
  377     final Text title = tester.widget(find.text('AAA'));
  378     expect(title.style, titleTextStyle);
  379     final Text subtitle = tester.widget(find.text('1 license.'));
  380     expect(subtitle.style, subtitleTextStyle);
  381   });
  382 
  383   testWidgets('LicensePage respects the notch', (WidgetTester tester) async {
  384     const double safeareaPadding = 27.0;
  385 
  386     LicenseRegistry.addLicense(() {
  387       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  388         const LicenseEntryWithLineBreaks(<String>['ABC'], 'DEF'),
  389       ]);
  390     });
  391 
  392     await tester.pumpWidget(
  393       const MaterialApp(
  394         home: MediaQuery(
  395           data: MediaQueryData(
  396             padding: EdgeInsets.all(safeareaPadding),
  397           ),
  398           child: LicensePage(),
  399         ),
  400       ),
  401     );
  402 
  403     await tester.pumpAndSettle();
  404 
  405     // The position of the top left of app bar title should indicate whether
  406     // the safe area is sufficiently respected.
  407     expect(
  408       tester.getTopLeft(find.text('Licenses')),
  409       const Offset(16.0 + safeareaPadding, 18.0 + safeareaPadding),
  410     );
  411   });
  412 
  413   testWidgets('LicensePage returns early if unmounted', (WidgetTester tester) async {
  414     final Completer<LicenseEntry> licenseCompleter = Completer<LicenseEntry>();
  415     LicenseRegistry.addLicense(() {
  416       return Stream<LicenseEntry>.fromFuture(licenseCompleter.future);
  417     });
  418 
  419     await tester.pumpWidget(
  420       const MaterialApp(
  421         home: LicensePage(),
  422       ),
  423     );
  424     await tester.pump();
  425 
  426     await tester.pumpWidget(
  427       const MaterialApp(
  428         home: Placeholder(),
  429       ),
  430     );
  431 
  432     await tester.pumpAndSettle();
  433     final FakeLicenseEntry licenseEntry = FakeLicenseEntry();
  434     licenseCompleter.complete(licenseEntry);
  435     expect(licenseEntry.packagesCalled, false);
  436   });
  437 
  438   testWidgets('LicensePage returns late if unmounted', (WidgetTester tester) async {
  439     final Completer<LicenseEntry> licenseCompleter = Completer<LicenseEntry>();
  440     LicenseRegistry.addLicense(() {
  441       return Stream<LicenseEntry>.fromFuture(licenseCompleter.future);
  442     });
  443 
  444     await tester.pumpWidget(
  445       const MaterialApp(
  446         home: LicensePage(),
  447       ),
  448     );
  449     await tester.pump();
  450     final FakeLicenseEntry licenseEntry = FakeLicenseEntry();
  451     licenseCompleter.complete(licenseEntry);
  452 
  453     await tester.pumpWidget(
  454       const MaterialApp(
  455         home: Placeholder(),
  456       ),
  457     );
  458 
  459     await tester.pumpAndSettle();
  460     expect(licenseEntry.packagesCalled, true);
  461   });
  462 
  463   testWidgets('LicensePage logic defaults to executable name for app name', (WidgetTester tester) async {
  464     await tester.pumpWidget(
  465       const MaterialApp(
  466         title: 'flutter_tester',
  467         home: Material(child: LicensePage()),
  468       ),
  469     );
  470     expect(find.text('flutter_tester'), findsOneWidget);
  471   });
  472 
  473   testWidgets('AboutListTile dense property is applied', (WidgetTester tester) async {
  474     await tester.pumpWidget(const MaterialApp(
  475       home: Material(child: Center(child: AboutListTile())),
  476     ));
  477     Rect tileRect = tester.getRect(find.byType(AboutListTile));
  478     expect(tileRect.height, 56.0);
  479 
  480     await tester.pumpWidget(const MaterialApp(
  481       home: Material(child: Center(child: AboutListTile(dense: false))),
  482     ));
  483     tileRect = tester.getRect(find.byType(AboutListTile));
  484     expect(tileRect.height, 56.0);
  485 
  486     await tester.pumpWidget(const MaterialApp(
  487       home: Material(child: Center(child: AboutListTile(dense: true))),
  488     ));
  489     tileRect = tester.getRect(find.byType(AboutListTile));
  490     expect(tileRect.height, 48.0);
  491   });
  492 
  493   testWidgets('showLicensePage uses nested navigator by default', (WidgetTester tester) async {
  494     final LicensePageObserver rootObserver = LicensePageObserver();
  495     final LicensePageObserver nestedObserver = LicensePageObserver();
  496 
  497     await tester.pumpWidget(MaterialApp(
  498       navigatorObservers: <NavigatorObserver>[rootObserver],
  499       initialRoute: '/',
  500       onGenerateRoute: (_) {
  501         return PageRouteBuilder<dynamic>(
  502           pageBuilder: (_, __, ___) => Navigator(
  503             observers: <NavigatorObserver>[nestedObserver],
  504             onGenerateRoute: (RouteSettings settings) {
  505               return PageRouteBuilder<dynamic>(
  506                 pageBuilder: (BuildContext context, _, __) {
  507                   return ElevatedButton(
  508                     onPressed: () {
  509                       showLicensePage(
  510                         context: context,
  511                         applicationName: 'A',
  512                       );
  513                     },
  514                     child: const Text('Show License Page'),
  515                   );
  516                 },
  517               );
  518             },
  519           ),
  520         );
  521       },
  522     ));
  523 
  524     // Open the dialog.
  525     await tester.tap(find.byType(ElevatedButton));
  526 
  527     expect(rootObserver.licensePageCount, 0);
  528     expect(nestedObserver.licensePageCount, 1);
  529   });
  530 
  531   testWidgets('showLicensePage uses root navigator if useRootNavigator is true', (WidgetTester tester) async {
  532     final LicensePageObserver rootObserver = LicensePageObserver();
  533     final LicensePageObserver nestedObserver = LicensePageObserver();
  534 
  535     await tester.pumpWidget(MaterialApp(
  536       navigatorObservers: <NavigatorObserver>[rootObserver],
  537       initialRoute: '/',
  538       onGenerateRoute: (_) {
  539         return PageRouteBuilder<dynamic>(
  540           pageBuilder: (_, __, ___) => Navigator(
  541             observers: <NavigatorObserver>[nestedObserver],
  542             onGenerateRoute: (RouteSettings settings) {
  543               return PageRouteBuilder<dynamic>(
  544                 pageBuilder: (BuildContext context, _, __) {
  545                   return ElevatedButton(
  546                     onPressed: () {
  547                       showLicensePage(
  548                         context: context,
  549                         useRootNavigator: true,
  550                         applicationName: 'A',
  551                       );
  552                     },
  553                     child: const Text('Show License Page'),
  554                   );
  555                 },
  556               );
  557             },
  558           ),
  559         );
  560       },
  561     ));
  562 
  563     // Open the dialog.
  564     await tester.tap(find.byType(ElevatedButton));
  565 
  566     expect(rootObserver.licensePageCount, 1);
  567     expect(nestedObserver.licensePageCount, 0);
  568   });
  569 
  570   testWidgets('showAboutDialog uses root navigator by default', (WidgetTester tester) async {
  571     final AboutDialogObserver rootObserver = AboutDialogObserver();
  572     final AboutDialogObserver nestedObserver = AboutDialogObserver();
  573 
  574     await tester.pumpWidget(MaterialApp(
  575       navigatorObservers: <NavigatorObserver>[rootObserver],
  576       home: Navigator(
  577         observers: <NavigatorObserver>[nestedObserver],
  578         onGenerateRoute: (RouteSettings settings) {
  579           return MaterialPageRoute<dynamic>(
  580             builder: (BuildContext context) {
  581               return ElevatedButton(
  582                 onPressed: () {
  583                   showAboutDialog(
  584                     context: context,
  585                     applicationName: 'A',
  586                   );
  587                 },
  588                 child: const Text('Show About Dialog'),
  589               );
  590             },
  591           );
  592         },
  593       ),
  594     ));
  595 
  596     // Open the dialog.
  597     await tester.tap(find.byType(ElevatedButton));
  598 
  599     expect(rootObserver.dialogCount, 1);
  600     expect(nestedObserver.dialogCount, 0);
  601   });
  602 
  603   testWidgets('showAboutDialog uses nested navigator if useRootNavigator is false', (WidgetTester tester) async {
  604     final AboutDialogObserver rootObserver = AboutDialogObserver();
  605     final AboutDialogObserver nestedObserver = AboutDialogObserver();
  606 
  607     await tester.pumpWidget(MaterialApp(
  608       navigatorObservers: <NavigatorObserver>[rootObserver],
  609       home: Navigator(
  610         observers: <NavigatorObserver>[nestedObserver],
  611         onGenerateRoute: (RouteSettings settings) {
  612           return MaterialPageRoute<dynamic>(
  613             builder: (BuildContext context) {
  614               return ElevatedButton(
  615                 onPressed: () {
  616                   showAboutDialog(
  617                     context: context,
  618                     useRootNavigator: false,
  619                     applicationName: 'A',
  620                   );
  621                 },
  622                 child: const Text('Show About Dialog'),
  623               );
  624             },
  625           );
  626         },
  627       ),
  628     ));
  629 
  630     // Open the dialog.
  631     await tester.tap(find.byType(ElevatedButton));
  632 
  633     expect(rootObserver.dialogCount, 0);
  634     expect(nestedObserver.dialogCount, 1);
  635   });
  636 
  637   group('showAboutDialog avoids overlapping display features', () {
  638     testWidgets('default positioning', (WidgetTester tester) async {
  639       await tester.pumpWidget(MaterialApp(
  640         builder: (BuildContext context, Widget? child) {
  641           return MediaQuery(
  642             // Display has a vertical hinge down the middle
  643             data: const MediaQueryData(
  644               size: Size(800, 600),
  645               displayFeatures: <DisplayFeature>[
  646                 DisplayFeature(
  647                   bounds: Rect.fromLTRB(390, 0, 410, 600),
  648                   type: DisplayFeatureType.hinge,
  649                   state: DisplayFeatureState.unknown,
  650                 ),
  651               ],
  652             ),
  653             child: child!,
  654           );
  655         },
  656         home: Builder(
  657           builder: (BuildContext context) => ElevatedButton(
  658             onPressed: () {
  659               showAboutDialog(
  660                 context: context,
  661                 useRootNavigator: false,
  662                 applicationName: 'A',
  663               );
  664             },
  665             child: const Text('Show About Dialog'),
  666           ),
  667         ),
  668       ));
  669 
  670       // Open the dialog.
  671       await tester.tap(find.byType(ElevatedButton));
  672       await tester.pumpAndSettle();
  673 
  674       // By default it should place the dialog on the left screen
  675       expect(tester.getTopLeft(find.byType(AboutDialog)), Offset.zero);
  676       expect(tester.getBottomRight(find.byType(AboutDialog)), const Offset(390.0, 600.0));
  677     });
  678 
  679     testWidgets('positioning using anchorPoint', (WidgetTester tester) async {
  680       await tester.pumpWidget(MaterialApp(
  681         builder: (BuildContext context, Widget? child) {
  682           return MediaQuery(
  683             // Display has a vertical hinge down the middle
  684             data: const MediaQueryData(
  685               size: Size(800, 600),
  686               displayFeatures: <DisplayFeature>[
  687                 DisplayFeature(
  688                   bounds: Rect.fromLTRB(390, 0, 410, 600),
  689                   type: DisplayFeatureType.hinge,
  690                   state: DisplayFeatureState.unknown,
  691                 ),
  692               ],
  693             ),
  694             child: child!,
  695           );
  696         },
  697         home: Builder(
  698           builder: (BuildContext context) => ElevatedButton(
  699             onPressed: () {
  700               showAboutDialog(
  701                 context: context,
  702                 useRootNavigator: false,
  703                 applicationName: 'A',
  704                 anchorPoint: const Offset(1000, 0),
  705               );
  706             },
  707             child: const Text('Show About Dialog'),
  708           ),
  709         ),
  710       ));
  711 
  712       // Open the dialog.
  713       await tester.tap(find.byType(ElevatedButton));
  714       await tester.pumpAndSettle();
  715 
  716       // The anchorPoint hits the right side of the display
  717       expect(tester.getTopLeft(find.byType(AboutDialog)), const Offset(410.0, 0.0));
  718       expect(tester.getBottomRight(find.byType(AboutDialog)), const Offset(800.0, 600.0));
  719     });
  720 
  721     testWidgets('positioning using Directionality', (WidgetTester tester) async {
  722       await tester.pumpWidget(MaterialApp(
  723         builder: (BuildContext context, Widget? child) {
  724           return MediaQuery(
  725             // Display has a vertical hinge down the middle
  726             data: const MediaQueryData(
  727               size: Size(800, 600),
  728               displayFeatures: <DisplayFeature>[
  729                 DisplayFeature(
  730                   bounds: Rect.fromLTRB(390, 0, 410, 600),
  731                   type: DisplayFeatureType.hinge,
  732                   state: DisplayFeatureState.unknown,
  733                 ),
  734               ],
  735             ),
  736             child: Directionality(
  737               textDirection: TextDirection.rtl,
  738               child: child!,
  739             ),
  740           );
  741         },
  742         home: Builder(
  743           builder: (BuildContext context) => ElevatedButton(
  744             onPressed: () {
  745               showAboutDialog(
  746                 context: context,
  747                 useRootNavigator: false,
  748                 applicationName: 'A',
  749               );
  750             },
  751             child: const Text('Show About Dialog'),
  752           ),
  753         ),
  754       ));
  755 
  756       // Open the dialog.
  757       await tester.tap(find.byType(ElevatedButton));
  758       await tester.pumpAndSettle();
  759 
  760       // Since this is rtl, the first screen is the on the right
  761       expect(tester.getTopLeft(find.byType(AboutDialog)), const Offset(410.0, 0.0));
  762       expect(tester.getBottomRight(find.byType(AboutDialog)), const Offset(800.0, 600.0));
  763     });
  764   });
  765 
  766   testWidgets("AboutListTile's child should not be offset when the icon is not specified.", (WidgetTester tester) async {
  767     await tester.pumpWidget(
  768       const MaterialApp(
  769         home: Scaffold(
  770           body: AboutListTile(
  771             child: Text('About'),
  772           ),
  773         ),
  774       ),
  775     );
  776 
  777     expect(
  778       find.descendant(
  779         of: find.byType(AboutListTile),
  780         matching: find.byType(Icon),
  781       ),
  782       findsNothing,
  783     );
  784   });
  785 
  786   testWidgets("AboutDialog's contents are scrollable", (WidgetTester tester) async {
  787     final Key contentKey = UniqueKey();
  788     await tester.pumpWidget(MaterialApp(
  789       home: Navigator(
  790         onGenerateRoute: (RouteSettings settings) {
  791           return MaterialPageRoute<dynamic>(
  792             builder: (BuildContext context) {
  793               return ElevatedButton(
  794                 onPressed: () {
  795                   showAboutDialog(
  796                     context: context,
  797                     useRootNavigator: false,
  798                     applicationName: 'A',
  799                     children: <Widget>[
  800                       Container(
  801                         key: contentKey,
  802                         color: Colors.orange,
  803                         height: 500,
  804                       ),
  805                     ],
  806                   );
  807                 },
  808                 child: const Text('Show About Dialog'),
  809               );
  810             },
  811           );
  812         },
  813       ),
  814     ));
  815 
  816     await tester.tap(find.text('Show About Dialog'));
  817     await tester.pumpAndSettle();
  818 
  819     // Try dragging by the [AboutDialog]'s title.
  820     RenderBox box = tester.renderObject(find.text('A'));
  821     Offset originalOffset = box.localToGlobal(Offset.zero);
  822     await tester.drag(find.byKey(contentKey), const Offset(0.0, -20.0));
  823 
  824     expect(box.localToGlobal(Offset.zero), equals(originalOffset.translate(0.0, -20.0)));
  825 
  826     // Try dragging by the additional children in contents.
  827     box = tester.renderObject(find.byKey(contentKey));
  828     originalOffset = box.localToGlobal(Offset.zero);
  829     await tester.drag(find.byKey(contentKey), const Offset(0.0, -20.0));
  830 
  831     expect(box.localToGlobal(Offset.zero), equals(originalOffset.translate(0.0, -20.0)));
  832   });
  833 
  834   testWidgets("LicensePage's color must be same whether loading or done", (WidgetTester tester) async {
  835     const Color scaffoldColor = Color(0xFF123456);
  836     const Color cardColor = Color(0xFF654321);
  837 
  838     await tester.pumpWidget(MaterialApp(
  839       theme: ThemeData.light().copyWith(
  840         scaffoldBackgroundColor: scaffoldColor,
  841         cardColor: cardColor,
  842       ),
  843       home: Scaffold(
  844         body: Center(
  845           child: Builder(
  846             builder: (BuildContext context) => GestureDetector(
  847               child: const Text('Show licenses'),
  848               onTap: () {
  849                 showLicensePage(
  850                   context: context,
  851                   applicationName: 'MyApp',
  852                   applicationVersion: '1.0.0',
  853                 );
  854               },
  855             ),
  856           ),
  857         ),
  858       ),
  859     ));
  860 
  861     await tester.tap(find.text('Show licenses'));
  862     await tester.pump();
  863     await tester.pump();
  864 
  865     // Check color when loading.
  866     final List<Material> materialLoadings = tester.widgetList<Material>(find.byType(Material)).toList();
  867     expect(materialLoadings.length, equals(4));
  868     expect(materialLoadings[1].color, scaffoldColor);
  869     expect(materialLoadings[2].color, cardColor);
  870 
  871     await tester.pumpAndSettle();
  872 
  873     // Check color when done.
  874     expect(find.byKey(const ValueKey<ConnectionState>(ConnectionState.done)), findsOneWidget);
  875     final List<Material> materialDones = tester.widgetList<Material>(find.byType(Material)).toList();
  876     expect(materialDones.length, equals(3));
  877     expect(materialDones[0].color, scaffoldColor);
  878     expect(materialDones[1].color, cardColor);
  879   });
  880 
  881   testWidgets('Conflicting scrollbars are not applied by ScrollBehavior to _PackageLicensePage', (WidgetTester tester) async {
  882     // Regression test for https://github.com/flutter/flutter/issues/83819
  883     LicenseRegistry.addLicense(() {
  884       return Stream<LicenseEntry>.fromIterable(<LicenseEntry>[
  885         const LicenseEntryWithLineBreaks(<String>['AAA'], 'BBB'),
  886       ]);
  887     });
  888 
  889     await tester.pumpWidget(
  890       const MaterialApp(
  891         home: Center(
  892           child: LicensePage(),
  893         ),
  894       ),
  895     );
  896     await tester.pumpAndSettle();
  897 
  898     // Check for packages.
  899     expect(find.text('AAA'), findsOneWidget);
  900     // Check license is displayed after entering into license page for 'AAA'.
  901     await tester.tap(find.text('AAA'));
  902     await tester.pumpAndSettle();
  903 
  904     // The inherited ScrollBehavior should not apply Scrollbars since they are
  905     // already built in to the widget.
  906     switch (debugDefaultTargetPlatformOverride) {
  907       case TargetPlatform.android:
  908       case TargetPlatform.fuchsia:
  909       case TargetPlatform.linux:
  910       case TargetPlatform.macOS:
  911       case TargetPlatform.windows:
  912         expect(find.byType(CupertinoScrollbar), findsNothing);
  913         break;
  914       case TargetPlatform.iOS:
  915         expect(find.byType(CupertinoScrollbar), findsOneWidget);
  916         break;
  917       case null:
  918         break;
  919     }
  920     expect(find.byType(Scrollbar), findsOneWidget);
  921     expect(find.byType(RawScrollbar), findsNothing);
  922 
  923   }, variant: TargetPlatformVariant.all());
  924 
  925   testWidgets('LicensePage padding', (WidgetTester tester) async {
  926     const FlutterLogo logo = FlutterLogo();
  927 
  928     await tester.pumpWidget(
  929       const MaterialApp(
  930         title: 'Pirate app',
  931         home: Center(
  932           child: LicensePage(
  933             applicationName: 'LicensePage test app',
  934             applicationIcon: logo,
  935             applicationVersion: '0.1.2',
  936             applicationLegalese: 'I am the very model of a modern major general.',
  937           ),
  938         ),
  939       ),
  940     );
  941 
  942     final Finder appName = find.text('LicensePage test app');
  943     final Finder appIcon = find.byType(FlutterLogo);
  944     final Finder appVersion = find.text('0.1.2');
  945     final Finder appLegalese = find.text('I am the very model of a modern major general.');
  946     final Finder appPowered = find.text('Powered by Flutter');
  947 
  948     expect(appName, findsOneWidget);
  949     expect(appIcon, findsOneWidget);
  950     expect(appVersion, findsOneWidget);
  951     expect(appLegalese, findsOneWidget);
  952     expect(appPowered, findsOneWidget);
  953 
  954     // Bottom padding is applied to the app version and app legalese text.
  955     final double appNameBottomPadding = tester.getTopLeft(appIcon).dy - tester.getBottomLeft(appName).dy;
  956     expect(appNameBottomPadding, 0.0);
  957 
  958     final double appIconBottomPadding = tester.getTopLeft(appVersion).dy - tester.getBottomLeft(appIcon).dy;
  959     expect(appIconBottomPadding, 0.0);
  960 
  961     final double appVersionBottomPadding = tester.getTopLeft(appLegalese).dy - tester.getBottomLeft(appVersion).dy;
  962     expect(appVersionBottomPadding, 18.0);
  963 
  964     final double appLegaleseBottomPadding = tester.getTopLeft(appPowered).dy - tester.getBottomLeft(appLegalese).dy;
  965     expect(appLegaleseBottomPadding, 18.0);
  966   });
  967 
  968   testWidgets('LicensePage has no extra padding between app icon and app powered text', (WidgetTester tester) async {
  969     // This is a regression test for https://github.com/flutter/flutter/issues/99559
  970 
  971     const FlutterLogo logo = FlutterLogo();
  972 
  973     await tester.pumpWidget(
  974       const MaterialApp(
  975         title: 'Pirate app',
  976         home: Center(
  977           child: LicensePage(
  978             applicationIcon: logo,
  979           ),
  980         ),
  981       ),
  982     );
  983 
  984     final Finder appName = find.text('LicensePage test app');
  985     final Finder appIcon = find.byType(FlutterLogo);
  986     final Finder appVersion = find.text('0.1.2');
  987     final Finder appLegalese = find.text('I am the very model of a modern major general.');
  988     final Finder appPowered = find.text('Powered by Flutter');
  989 
  990     expect(appName, findsNothing);
  991     expect(appIcon, findsOneWidget);
  992     expect(appVersion, findsNothing);
  993     expect(appLegalese, findsNothing);
  994     expect(appPowered, findsOneWidget);
  995 
  996     // Padding between app icon and app powered text.
  997     final double appIconBottomPadding = tester.getTopLeft(appPowered).dy - tester.getBottomLeft(appIcon).dy;
  998     expect(appIconBottomPadding, 18.0);
  999   });
 1000 }
 1001 
 1002 class FakeLicenseEntry extends LicenseEntry {
 1003   FakeLicenseEntry();
 1004 
 1005   bool get packagesCalled => _packagesCalled;
 1006   bool _packagesCalled = false;
 1007 
 1008   @override
 1009   Iterable<LicenseParagraph> paragraphs = <LicenseParagraph>[];
 1010 
 1011   @override
 1012   Iterable<String> get packages {
 1013     _packagesCalled = true;
 1014     return <String>[];
 1015   }
 1016 }
 1017 
 1018 class LicensePageObserver extends NavigatorObserver {
 1019   int licensePageCount = 0;
 1020 
 1021   @override
 1022   void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
 1023     if (route is MaterialPageRoute<dynamic>) {
 1024       licensePageCount++;
 1025     }
 1026     super.didPush(route, previousRoute);
 1027   }
 1028 }
 1029 
 1030 class AboutDialogObserver extends NavigatorObserver {
 1031   int dialogCount = 0;
 1032 
 1033   @override
 1034   void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
 1035     if (route is DialogRoute) {
 1036       dialogCount++;
 1037     }
 1038     super.didPush(route, previousRoute);
 1039   }
 1040 }