page_selector_test.dart 8.51 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7 8 9
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';

10
const Color kSelectedColor = Color(0xFF00FF00);
11
const Color kUnselectedColor = Colors.transparent;
12

13
Widget buildFrame(TabController tabController, { Color color, Color selectedColor, double indicatorSize = 12.0 }) {
14
  return Directionality(
15
    textDirection: TextDirection.ltr,
16 17 18 19 20
    child: Theme(
      data: ThemeData(accentColor: kSelectedColor),
      child: SizedBox.expand(
        child: Center(
          child: SizedBox(
21 22
            width: 400.0,
            height: 400.0,
23
            child: Column(
24
              children: <Widget>[
25
                TabPageSelector(
26
                  controller: tabController,
27 28 29
                  color: color,
                  selectedColor: selectedColor,
                  indicatorSize: indicatorSize,
30
                ),
31 32
                Flexible(
                  child: TabBarView(
33
                    controller: tabController,
34
                    children: const <Widget>[
35 36 37
                      Center(child: Text('0')),
                      Center(child: Text('1')),
                      Center(child: Text('2')),
38 39 40 41 42
                    ],
                  ),
                ),
              ],
            ),
43 44 45 46 47 48 49 50 51 52 53
          ),
        ),
      ),
    ),
  );
}

List<Color> indicatorColors(WidgetTester tester) {
  final Iterable<TabPageSelectorIndicator> indicators = tester.widgetList(
    find.descendant(
      of: find.byType(TabPageSelector),
54
      matching: find.byType(TabPageSelectorIndicator),
55
    ),
56
  );
57
  return indicators.map<Color>((TabPageSelectorIndicator indicator) => indicator.backgroundColor).toList();
58 59 60 61
}

void main() {
  testWidgets('PageSelector responds correctly to setting the TabController index', (WidgetTester tester) async {
62
    final TabController tabController = TabController(
63 64 65 66 67 68
      vsync: const TestVSync(),
      length: 3,
    );
    await tester.pumpWidget(buildFrame(tabController));

    expect(tabController.index, 0);
69
    expect(indicatorColors(tester), const <Color>[kSelectedColor, kUnselectedColor, kUnselectedColor]);
70 71 72 73

    tabController.index = 1;
    await tester.pump();
    expect(tabController.index, 1);
74
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
75 76 77 78

    tabController.index = 2;
    await tester.pump();
    expect(tabController.index, 2);
79
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
80 81 82
  });

  testWidgets('PageSelector responds correctly to TabController.animateTo()', (WidgetTester tester) async {
83
    final TabController tabController = TabController(
84 85 86 87 88 89
      vsync: const TestVSync(),
      length: 3,
    );
    await tester.pumpWidget(buildFrame(tabController));

    expect(tabController.index, 0);
90
    expect(indicatorColors(tester), const <Color>[kSelectedColor, kUnselectedColor, kUnselectedColor]);
91 92 93 94 95 96 97 98 99

    tabController.animateTo(1, duration: const Duration(milliseconds: 200));
    await tester.pump();
    // Verify that indicator 0's color is becoming increasingly transparent,
    /// and indicator 1's color is becoming increasingly opaque during the
    // 200ms animation. Indicator 2 remains transparent throughout.
    await tester.pump(const Duration(milliseconds: 10));
    List<Color> colors = indicatorColors(tester);
    expect(colors[0].alpha, greaterThan(colors[1].alpha));
100
    expect(colors[2], kUnselectedColor);
101 102 103
    await tester.pump(const Duration(milliseconds: 175));
    colors = indicatorColors(tester);
    expect(colors[0].alpha, lessThan(colors[1].alpha));
104
    expect(colors[2], kUnselectedColor);
105 106
    await tester.pumpAndSettle();
    expect(tabController.index, 1);
107
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
108 109 110 111 112 113 114

    tabController.animateTo(2, duration: const Duration(milliseconds: 200));
    await tester.pump();
    // Same animation test as above for indicators 1 and 2.
    await tester.pump(const Duration(milliseconds: 10));
    colors = indicatorColors(tester);
    expect(colors[1].alpha, greaterThan(colors[2].alpha));
115
    expect(colors[0], kUnselectedColor);
116 117 118
    await tester.pump(const Duration(milliseconds: 175));
    colors = indicatorColors(tester);
    expect(colors[1].alpha, lessThan(colors[2].alpha));
119
    expect(colors[0], kUnselectedColor);
120 121
    await tester.pumpAndSettle();
    expect(tabController.index, 2);
122
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
123 124 125
  });

  testWidgets('PageSelector responds correctly to TabBarView drags', (WidgetTester tester) async {
126
    final TabController tabController = TabController(
127 128 129 130 131 132 133
      vsync: const TestVSync(),
      initialIndex: 1,
      length: 3,
    );
    await tester.pumpWidget(buildFrame(tabController));

    expect(tabController.index, 1);
134
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
135 136 137 138 139 140 141 142 143

    final TestGesture gesture = await tester.startGesture(const Offset(200.0, 200.0));

    // Drag to the left moving the selection towards indicator 2. Indicator 2's
    // opacity should increase and Indicator 1's opacity should decrease.
    await gesture.moveBy(const Offset(-100.0, 0.0));
    await tester.pumpAndSettle();
    List<Color> colors = indicatorColors(tester);
    expect(colors[1].alpha, greaterThan(colors[2].alpha));
144
    expect(colors[0], kUnselectedColor);
145 146 147 148 149

    // Drag back to where we started.
    await gesture.moveBy(const Offset(100.0, 0.0));
    await tester.pumpAndSettle();
    colors = indicatorColors(tester);
150
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
151 152 153 154 155 156 157

    // Drag to the left moving the selection towards indicator 0. Indicator 0's
    // opacity should increase and Indicator 1's opacity should decrease.
    await gesture.moveBy(const Offset(100.0, 0.0));
    await tester.pumpAndSettle();
    colors = indicatorColors(tester);
    expect(colors[1].alpha, greaterThan(colors[0].alpha));
158
    expect(colors[2], kUnselectedColor);
159 160 161 162 163

    // Drag back to where we started.
    await gesture.moveBy(const Offset(-100.0, 0.0));
    await tester.pumpAndSettle();
    colors = indicatorColors(tester);
164
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
165 166 167 168 169

    // Completing the gesture doesn't change anything
    await gesture.up();
    await tester.pumpAndSettle();
    colors = indicatorColors(tester);
170
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
171 172 173 174

    // Fling to the left, selects indicator 2
    await tester.fling(find.byType(TabBarView), const Offset(-100.0, 0.0), 1000.0);
    await tester.pumpAndSettle();
175
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
176 177 178 179

    // Fling to the right, selects indicator 1
    await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 1000.0);
    await tester.pumpAndSettle();
180 181 182 183 184
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);

  });

  testWidgets('PageSelector indicatorColors', (WidgetTester tester) async {
185 186
    const Color kRed = Color(0xFFFF0000);
    const Color kBlue = Color(0xFF0000FF);
187

188
    final TabController tabController = TabController(
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
      vsync: const TestVSync(),
      initialIndex: 1,
      length: 3,
    );
    await tester.pumpWidget(buildFrame(tabController, color: kRed, selectedColor: kBlue));

    expect(tabController.index, 1);
    expect(indicatorColors(tester), const <Color>[kRed, kBlue, kRed]);

    tabController.index = 0;
    await tester.pumpAndSettle();
    expect(indicatorColors(tester), const <Color>[kBlue, kRed, kRed]);
  });

  testWidgets('PageSelector indicatorSize', (WidgetTester tester) async {
204
    final TabController tabController = TabController(
205 206 207 208 209 210 211 212 213 214 215 216
      vsync: const TestVSync(),
      initialIndex: 1,
      length: 3,
    );
    await tester.pumpWidget(buildFrame(tabController, indicatorSize: 16.0));

    final Iterable<Element> indicatorElements = find.descendant(
      of: find.byType(TabPageSelector),
      matching: find.byType(TabPageSelectorIndicator),
    ).evaluate();

    // Indicators get an 8 pixel margin, 16 + 8 = 24.
217
    for (final Element indicatorElement in indicatorElements)
218
      expect(indicatorElement.size, const Size(24.0, 24.0));
219

220
    expect(tester.getSize(find.byType(TabPageSelector)).height, 24.0);
221 222 223
  });

}