page_transitions_theme_test.dart 7.48 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 16 17 18
    for (final TargetPlatform platform in TargetPlatform.values) {
      if (platform == TargetPlatform.fuchsia) {
        // No builder on Fuchsia.
        continue;
Dan Field's avatar
Dan Field committed
19
      }
20
      expect(theme.builders[platform], isNotNull, reason: 'theme builder for $platform is null');
Dan Field's avatar
Dan Field committed
21
    }
22 23
  });

24
  testWidgets('Default PageTransitionsTheme builds a CupertionPageTransition', (WidgetTester tester) async {
25 26
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
27
        child: TextButton(
28
          child: const Text('push'),
29
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
30 31 32 33 34 35 36 37 38 39 40
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

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

41
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
42 43 44 45 46 47
    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);
48
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));
49

50
  testWidgets('Default PageTransitionsTheme builds a _FadeUpwardsPageTransition for android', (WidgetTester tester) async {
51 52
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
53
        child: TextButton(
54
          child: const Text('push'),
55
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
56 57 58 59 60 61 62 63 64 65 66
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

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

67
    Finder findFadeUpwardsPageTransition() {
68 69
      return find.descendant(
        of: find.byType(MaterialApp),
70
        matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_FadeUpwardsPageTransition'),
71 72 73
      );
    }

74
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
75
    expect(findFadeUpwardsPageTransition(), findsOneWidget);
76 77 78 79

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('page b'), findsOneWidget);
80
    expect(findFadeUpwardsPageTransition(), findsOneWidget);
81
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
82

83
  testWidgets('PageTransitionsTheme override builds a _OpenUpwardsPageTransition', (WidgetTester tester) async {
84 85
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
86
        child: TextButton(
87
          child: const Text('push'),
88
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
        ),
      ),
      '/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'),
      );
    }

114
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
115 116 117 118 119 120
    expect(findOpenUpwardsPageTransition(), findsOneWidget);

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

123
  testWidgets('PageTransitionsTheme override builds a _ZoomPageTransition', (WidgetTester tester) async {
124 125
    final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
      '/': (BuildContext context) => Material(
126
        child: TextButton(
127
          child: const Text('push'),
128
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
129 130 131 132 133 134 135 136 137 138
        ),
      ),
      '/b': (BuildContext context) => const Text('page b'),
    };

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          pageTransitionsTheme: const PageTransitionsTheme(
            builders: <TargetPlatform, PageTransitionsBuilder>{
139
              TargetPlatform.android: ZoomPageTransitionsBuilder(), // creates a _ZoomPageTransition
140 141 142 143 144 145 146
            },
          ),
        ),
        routes: routes,
      ),
    );

147
    Finder findZoomPageTransition() {
148 149
      return find.descendant(
        of: find.byType(MaterialApp),
150
        matching: find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_ZoomPageTransition'),
151 152 153
      );
    }

154
    expect(Theme.of(tester.element(find.text('push'))).platform, debugDefaultTargetPlatformOverride);
155
    expect(findZoomPageTransition(), findsOneWidget);
156 157 158 159

    await tester.tap(find.text('push'));
    await tester.pumpAndSettle();
    expect(find.text('page b'), findsOneWidget);
160
    expect(findZoomPageTransition(), findsOneWidget);
161
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
162 163 164 165 166 167 168 169

  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(
170
        child: TextButton(
171
          child: const Text('push'),
172
          onPressed: () { Navigator.of(context).pushNamed('/b'); },
173 174 175 176 177
        ),
      ),
      '/b': (BuildContext context) => StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          builtCount++; // Increase [builtCount] each time the widget build
178
          return TextButton(
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
            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);
207
  }, variant: TargetPlatformVariant.only(TargetPlatform.android));
208
}