page_selector_test.dart 8.49 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2017 The Chromium 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_test/flutter_test.dart';
import 'package:flutter/material.dart';

8
const Color kSelectedColor = Color(0xFF00FF00);
9
const Color kUnselectedColor = Colors.transparent;
10

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

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

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

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

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

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

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

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

    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));
98
    expect(colors[2], kUnselectedColor);
99 100 101
    await tester.pump(const Duration(milliseconds: 175));
    colors = indicatorColors(tester);
    expect(colors[0].alpha, lessThan(colors[1].alpha));
102
    expect(colors[2], kUnselectedColor);
103 104
    await tester.pumpAndSettle();
    expect(tabController.index, 1);
105
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kSelectedColor, kUnselectedColor]);
106 107 108 109 110 111 112

    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));
113
    expect(colors[0], kUnselectedColor);
114 115 116
    await tester.pump(const Duration(milliseconds: 175));
    colors = indicatorColors(tester);
    expect(colors[1].alpha, lessThan(colors[2].alpha));
117
    expect(colors[0], kUnselectedColor);
118 119
    await tester.pumpAndSettle();
    expect(tabController.index, 2);
120
    expect(indicatorColors(tester), const <Color>[kUnselectedColor, kUnselectedColor, kSelectedColor]);
121 122 123
  });

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

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

    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));
142
    expect(colors[0], kUnselectedColor);
143 144 145 146 147

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

    // 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));
156
    expect(colors[2], kUnselectedColor);
157 158 159 160 161

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

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

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

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

  });

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

186
    final TabController tabController = TabController(
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
      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 {
202
    final TabController tabController = TabController(
203 204 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.
    for (Element indicatorElement in indicatorElements)
      expect(indicatorElement.size, const Size(24.0, 24.0));
217

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

}