page_transitions_theme_test.dart 7.85 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5
// 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';
Dan Field's avatar
Dan Field committed
6
import 'package:flutter/foundation.dart';
7 8 9 10
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
11
  testWidgets('Default PageTransitionsTheme platform', (WidgetTester tester) async {
Dan Field's avatar
Dan Field committed
12
    await tester.pumpWidget(const MaterialApp(home: Text('home')));
13
    final PageTransitionsTheme theme = Theme.of(tester.element(find.text('home'))).pageTransitionsTheme;
14
    expect(theme.builders, isNotNull);
15
    for (final TargetPlatform platform in TargetPlatform.values) {
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
      switch (platform) {
        case TargetPlatform.android:
        case TargetPlatform.iOS:
        case TargetPlatform.macOS:
          expect(
            theme.builders[platform],
            isNotNull,
            reason: 'theme builder for $platform is null',
          );
          break;
        case TargetPlatform.fuchsia:
        case TargetPlatform.linux:
        case TargetPlatform.windows:
          expect(
            theme.builders[platform],
            isNull,
            reason: 'theme builder for $platform is not null',
          );
          break;
Dan Field's avatar
Dan Field committed
35 36
      }
    }
37 38
  });

39
  testWidgets('Default PageTransitionsTheme builds a CupertinoPageTransition', (WidgetTester tester) async {
40 41
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
42
        child: TextButton(
43
          child: const Text('push'),
44
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
45 46 47 48 49 50 51 52 53 54 55
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

    await tester.pumpWidget(
      MaterialApp(
        routes: routes,
      ),
    );

56
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
57 58 59 60 61 62
    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);
63
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));
64

65
  testWidgets('Default PageTransitionsTheme builds a _ZoomPageTransition for android', (WidgetTester tester) async {
66 67
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
68
        child: TextButton(
69
          child: const Text('push'),
70
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
71 72 73 74 75 76 77 78 79 80 81
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

    await tester.pumpWidget(
      MaterialApp(
        routes: routes,
      ),
    );

82
    Finder findZoomPageTransition() {
83 84
      return find.descendant(
        of: find.byType(MaterialApp),
85
        matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_ZoomPageTransition'),
86 87 88
      );
    }

89
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
90
    expect(findZoomPageTransition(), findsOneWidget);
91 92 93 94

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('page b'), findsOneWidget);
95
    expect(findZoomPageTransition(), findsOneWidget);
96
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
97

98
  testWidgets('PageTransitionsTheme override builds a _OpenUpwardsPageTransition', (WidgetTester tester) async {
99 100
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
101
        child: TextButton(
102
          child: const Text('push'),
103
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
        ),
      ),
      '/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'),
      );
    }

129
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
130 131 132 133 134 135
    expect(findOpenUpwardsPageTransition(), findsOneWidget);

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('page b'), findsOneWidget);
    expect(findOpenUpwardsPageTransition(), findsOneWidget);
136
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
137

138
  testWidgets('PageTransitionsTheme override builds a _FadeUpwardsTransition', (WidgetTester tester) async {
139 140
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
141
        child: TextButton(
142
          child: const Text('push'),
143
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
144 145 146 147 148 149 150 151 152 153
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          pageTransitionsTheme: const PageTransitionsTheme(
            builders: <TargetPlatform, PageTransitionsBuilder>{
154
              TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(), // creates a _FadeUpwardsTransition
155 156 157 158 159 160 161
            },
          ),
        ),
        routes: routes,
      ),
    );

162
    Finder findFadeUpwardsPageTransition() {
163 164
      return find.descendant(
        of: find.byType(MaterialApp),
165
        matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_FadeUpwardsPageTransition'),
166 167 168
      );
    }

169
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
170
    expect(findFadeUpwardsPageTransition(), findsOneWidget);
171 172 173 174

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('page b'), findsOneWidget);
175
    expect(findFadeUpwardsPageTransition(), findsOneWidget);
176
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
177 178 179 180 181 182 183 184

  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(
185
        child: TextButton(
186
          child: const Text('push'),
187
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
188 189 190 191 192
        ),
      ),
      '/b': (BuildContext context) => StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          builtCount++; // Increase [builtCount] each time the widget build
193
          return TextButton(
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
            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);
222
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
223
}