animated_icons_test.dart 7.34 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math' as math show pi;

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import '../widgets/semantics_tester.dart';

class MockCanvas extends Mock implements Canvas {}

void main() {
  testWidgets('IconTheme color', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
20 21 22
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
23
          ),
24 25
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
26
            icon: AnimatedIcons.arrow_menu,
27
          ),
28 29 30 31
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
32
    final MockCanvas canvas = MockCanvas();
33
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
34
    verify(canvas.drawPath(any, argThat(hasColor(0xFF666666))));
35 36 37 38 39 40
  });

  testWidgets('IconTheme opacity', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
41 42 43
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
44
            opacity: 0.5,
45
          ),
46 47
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
48
            icon: AnimatedIcons.arrow_menu,
49
          ),
50 51 52 53
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
54
    final MockCanvas canvas = MockCanvas();
55
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
56
    verify(canvas.drawPath(any, argThat(hasColor(0x80666666))));
57 58 59 60 61 62
  });

  testWidgets('color overrides IconTheme color', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
63 64 65
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
66
          ),
67 68
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
69
            icon: AnimatedIcons.arrow_menu,
70
            color: Color(0xFF0000FF),
71
          ),
72 73 74 75
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
76
    final MockCanvas canvas = MockCanvas();
77
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
78
    verify(canvas.drawPath(any, argThat(hasColor(0xFF0000FF))));
79 80 81 82 83 84
  });

  testWidgets('IconTheme size', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
85 86 87
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
88 89
            size: 12.0,
          ),
90 91
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
92
            icon: AnimatedIcons.arrow_menu,
93
          ),
94 95 96 97
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
98
    final MockCanvas canvas = MockCanvas();
99 100 101 102 103 104 105 106 107
    customPaint.painter.paint(canvas, const Size(12.0, 12.0));
    // arrow_menu default size is 48x48 so we expect it to be scaled by 0.25.
    verify(canvas.scale(0.25, 0.25));
  });

  testWidgets('size overridesIconTheme size', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
108 109 110
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
111 112
            size: 12.0,
          ),
113 114
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
115 116
            icon: AnimatedIcons.arrow_menu,
            size: 96.0,
117
          ),
118 119 120 121
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
122
    final MockCanvas canvas = MockCanvas();
123 124 125 126 127 128
    customPaint.painter.paint(canvas, const Size(12.0, 12.0));
    // arrow_menu default size is 48x48 so we expect it to be scaled by 2.
    verify(canvas.scale(2.0, 2.0));
  });

  testWidgets('Semantic label', (WidgetTester tester) async {
129
    final SemanticsTester semantics = SemanticsTester(tester);
130 131 132 133

    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
134 135
        child: AnimatedIcon(
          progress: AlwaysStoppedAnimation<double>(0.0),
136 137 138 139 140 141 142 143
          icon: AnimatedIcons.arrow_menu,
          size: 96.0,
          semanticLabel: 'a label',
        ),
      ),
    );

    expect(semantics, includesNodeWith(label: 'a label'));
144 145

    semantics.dispose();
146 147 148 149 150 151
  });

  testWidgets('Inherited text direction rtl', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.rtl,
152 153 154
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
155
          ),
156 157
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
158
            icon: AnimatedIcons.arrow_menu,
159
          ),
160 161 162 163
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
164
    final MockCanvas canvas = MockCanvas();
165
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
166
    verifyInOrder(<void>[
167
      canvas.rotate(math.pi),
168
      canvas.translate(-48.0, -48.0),
169 170 171 172 173 174 175
    ]);
  });

  testWidgets('Inherited text direction ltr', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
176 177 178
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
179
          ),
180 181
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
182
            icon: AnimatedIcons.arrow_menu,
183
          ),
184 185 186 187
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
188
    final MockCanvas canvas = MockCanvas();
189
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
190 191
    verifyNever(canvas.rotate(any));
    verifyNever(canvas.translate(any, any));
192 193 194 195 196 197
  });

  testWidgets('Inherited text direction overridden', (WidgetTester tester) async {
    await tester.pumpWidget(
      const Directionality(
        textDirection: TextDirection.ltr,
198 199 200
        child: IconTheme(
          data: IconThemeData(
            color: Color(0xFF666666),
201
          ),
202 203
          child: AnimatedIcon(
            progress: AlwaysStoppedAnimation<double>(0.0),
204 205
            icon: AnimatedIcons.arrow_menu,
            textDirection: TextDirection.rtl,
206
          ),
207 208 209 210
        ),
      ),
    );
    final CustomPaint customPaint = tester.widget(find.byType(CustomPaint));
211
    final MockCanvas canvas = MockCanvas();
212
    customPaint.painter.paint(canvas, const Size(48.0, 48.0));
213
    verifyInOrder(<void>[
214
      canvas.rotate(math.pi),
215
      canvas.translate(-48.0, -48.0),
216 217 218 219
    ]);
  });
}

220
PaintColorMatcher hasColor(int color) {
221
  return PaintColorMatcher(color);
222 223 224 225 226 227 228 229 230 231 232 233 234
}

class PaintColorMatcher extends Matcher {
  const PaintColorMatcher(this.expectedColor);

  final int expectedColor;

  @override
  Description describe(Description description) =>
    description.add('color was not $expectedColor');

  @override
  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
235
    final Paint actualPaint = item as Paint;
236
    return actualPaint.color == Color(expectedColor);
237 238
  }
}