blob: 2db3f43e7c3756636669f2458e251cb04aad0abe [file] [log] [blame]
// 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_test/flutter_test.dart';
void main() {
testWidgets('Default PageTransitionsTheme platform', (WidgetTester tester) async {
await tester.pumpWidget(const MaterialApp(home: Text('home')));
final PageTransitionsTheme theme = Theme.of(tester.element(find.text('home'))).pageTransitionsTheme;
expect(theme.builders, isNotNull);
for (final TargetPlatform platform in TargetPlatform.values) {
if (platform == TargetPlatform.fuchsia) {
// No builder on Fuchsia.
continue;
}
expect(theme.builders[platform], isNotNull, reason: 'theme builder for $platform is null');
}
});
testWidgets('Default PageTransitionsTheme builds a CupertionPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: TextButton(
child: const Text('push'),
onPressed: () { Navigator.of(context).pushNamed('/b'); },
),
),
'/b': (BuildContext context) => const Text('page b'),
};
await tester.pumpWidget(
MaterialApp(
routes: routes,
),
);
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(find.byType(CupertinoPageTransition), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(find.byType(CupertinoPageTransition), findsOneWidget);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Default PageTransitionsTheme builds a _FadeUpwardsPageTransition for android', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: TextButton(
child: const Text('push'),
onPressed: () { Navigator.of(context).pushNamed('/b'); },
),
),
'/b': (BuildContext context) => const Text('page b'),
};
await tester.pumpWidget(
MaterialApp(
routes: routes,
),
);
Finder findFadeUpwardsPageTransition() {
return find.descendant(
of: find.byType(MaterialApp),
matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_FadeUpwardsPageTransition'),
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findFadeUpwardsPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findFadeUpwardsPageTransition(), findsOneWidget);
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('PageTransitionsTheme override builds a _OpenUpwardsPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: TextButton(
child: const Text('push'),
onPressed: () { Navigator.of(context).pushNamed('/b'); },
),
),
'/b': (BuildContext context) => const Text('page b'),
};
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: OpenUpwardsPageTransitionsBuilder(), // creates a _OpenUpwardsPageTransition
},
),
),
routes: routes,
),
);
Finder findOpenUpwardsPageTransition() {
return find.descendant(
of: find.byType(MaterialApp),
matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_OpenUpwardsPageTransition'),
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findOpenUpwardsPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findOpenUpwardsPageTransition(), findsOneWidget);
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('PageTransitionsTheme override builds a _ZoomPageTransition', (WidgetTester tester) async {
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: TextButton(
child: const Text('push'),
onPressed: () { Navigator.of(context).pushNamed('/b'); },
),
),
'/b': (BuildContext context) => const Text('page b'),
};
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(), // creates a _ZoomPageTransition
},
),
),
routes: routes,
),
);
Finder findZoomPageTransition() {
return find.descendant(
of: find.byType(MaterialApp),
matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_ZoomPageTransition'),
);
}
expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
expect(findZoomPageTransition(), findsOneWidget);
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(find.text('page b'), findsOneWidget);
expect(findZoomPageTransition(), findsOneWidget);
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('_ZoomPageTransition only cause child widget built once', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/58345
int builtCount = 0;
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (BuildContext context) => Material(
child: TextButton(
child: const Text('push'),
onPressed: () { Navigator.of(context).pushNamed('/b'); },
),
),
'/b': (BuildContext context) => StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
builtCount++; // Increase [builtCount] each time the widget build
return TextButton(
child: const Text('pop'),
onPressed: () { Navigator.pop(context); },
);
},
),
};
await tester.pumpWidget(
MaterialApp(
theme: ThemeData(
pageTransitionsTheme: const PageTransitionsTheme(
builders: <TargetPlatform, PageTransitionsBuilder>{
TargetPlatform.android: ZoomPageTransitionsBuilder(), // creates a _ZoomPageTransition
},
),
),
routes: routes,
),
);
// No matter push or pop was called, the child widget should built only once.
await tester.tap(find.text('push'));
await tester.pumpAndSettle();
expect(builtCount, 1);
await tester.tap(find.text('pop'));
await tester.pumpAndSettle();
expect(builtCount, 1);
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
}