• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5import 'dart:ui' as ui show window;
6import 'dart:ui' show Size, Locale, WindowPadding, AccessibilityFeatures, Brightness;
7
8import 'package:flutter/widgets.dart' show WidgetsBinding;
9import 'package:flutter_test/flutter_test.dart';
10import 'package:meta/meta.dart';
11
12void main() {
13  test('TestWindow can handle new methods without breaking', () {
14    final dynamic testWindow = TestWindow(window: ui.window);
15    expect(testWindow.someNewProperty, null);
16  });
17
18  testWidgets('TestWindow can fake device pixel ratio', (WidgetTester tester) async {
19    verifyThatTestWindowCanFakeProperty<double>(
20      tester: tester,
21      realValue: ui.window.devicePixelRatio,
22      fakeValue: 2.5,
23      propertyRetriever: () {
24        return WidgetsBinding.instance.window.devicePixelRatio;
25      },
26      propertyFaker: (TestWidgetsFlutterBinding binding, double fakeValue) {
27        binding.window.devicePixelRatioTestValue = fakeValue;
28      },
29    );
30  });
31
32  testWidgets('TestWindow can fake physical size', (WidgetTester tester) async {
33    verifyThatTestWindowCanFakeProperty<Size>(
34      tester: tester,
35      realValue: ui.window.physicalSize,
36      fakeValue: const Size(50, 50),
37      propertyRetriever: () {
38        return WidgetsBinding.instance.window.physicalSize;
39      },
40      propertyFaker: (TestWidgetsFlutterBinding binding, Size fakeValue) {
41        binding.window.physicalSizeTestValue = fakeValue;
42      },
43    );
44  });
45
46  testWidgets('TestWindow can fake physical depth', (WidgetTester tester) async {
47    verifyThatTestWindowCanFakeProperty<double>(
48      tester: tester,
49      realValue: ui.window.physicalDepth,
50      fakeValue: 120.0,
51      propertyRetriever: () {
52        return WidgetsBinding.instance.window.physicalDepth;
53      },
54      propertyFaker: (TestWidgetsFlutterBinding binding, double fakeValue) {
55        binding.window.physicalDepthTestValue = fakeValue;
56      },
57    );
58  });
59
60  testWidgets('TestWindow can fake view insets', (WidgetTester tester) async {
61    verifyThatTestWindowCanFakeProperty<WindowPadding>(
62      tester: tester,
63      realValue: ui.window.viewInsets,
64      fakeValue: const FakeWindowPadding(),
65      propertyRetriever: () {
66        return WidgetsBinding.instance.window.viewInsets;
67      },
68      propertyFaker: (TestWidgetsFlutterBinding binding, WindowPadding fakeValue) {
69        binding.window.viewInsetsTestValue = fakeValue;
70      },
71    );
72  });
73
74  testWidgets('TestWindow can fake padding', (WidgetTester tester) async {
75    verifyThatTestWindowCanFakeProperty<WindowPadding>(
76      tester: tester,
77      realValue: ui.window.padding,
78      fakeValue: const FakeWindowPadding(),
79      propertyRetriever: () {
80        return WidgetsBinding.instance.window.padding;
81      },
82      propertyFaker: (TestWidgetsFlutterBinding binding, WindowPadding fakeValue) {
83        binding.window.paddingTestValue = fakeValue;
84      },
85    );
86  });
87
88  testWidgets('TestWindow can fake locale', (WidgetTester tester) async {
89    verifyThatTestWindowCanFakeProperty<Locale>(
90      tester: tester,
91      realValue: ui.window.locale,
92      fakeValue: const Locale('fake_language_code'),
93      propertyRetriever: () {
94        return WidgetsBinding.instance.window.locale;
95      },
96      propertyFaker: (TestWidgetsFlutterBinding binding, Locale fakeValue) {
97        binding.window.localeTestValue = fakeValue;
98      },
99    );
100  });
101
102  testWidgets('TestWindow can fake locales', (WidgetTester tester) async {
103    verifyThatTestWindowCanFakeProperty<List<Locale>>(
104      tester: tester,
105      realValue: ui.window.locales,
106      fakeValue: <Locale>[const Locale('fake_language_code')],
107      propertyRetriever: () {
108        return WidgetsBinding.instance.window.locales;
109      },
110      propertyFaker: (TestWidgetsFlutterBinding binding, List<Locale> fakeValue) {
111        binding.window.localesTestValue = fakeValue;
112      },
113    );
114  });
115
116  testWidgets('TestWindow can fake text scale factor', (WidgetTester tester) async {
117    verifyThatTestWindowCanFakeProperty<double>(
118      tester: tester,
119      realValue: ui.window.textScaleFactor,
120      fakeValue: 2.5,
121      propertyRetriever: () {
122        return WidgetsBinding.instance.window.textScaleFactor;
123      },
124      propertyFaker: (TestWidgetsFlutterBinding binding, double fakeValue) {
125        binding.window.textScaleFactorTestValue = fakeValue;
126      },
127    );
128  });
129
130  testWidgets('TestWindow can fake clock format', (WidgetTester tester) async {
131    verifyThatTestWindowCanFakeProperty<bool>(
132      tester: tester,
133      realValue: ui.window.alwaysUse24HourFormat,
134      fakeValue: !ui.window.alwaysUse24HourFormat,
135      propertyRetriever: () {
136        return WidgetsBinding.instance.window.alwaysUse24HourFormat;
137      },
138      propertyFaker: (TestWidgetsFlutterBinding binding, bool fakeValue) {
139        binding.window.alwaysUse24HourFormatTestValue = fakeValue;
140      },
141    );
142  });
143
144  testWidgets('TestWindow can fake default route name', (WidgetTester tester) async {
145    verifyThatTestWindowCanFakeProperty<String>(
146      tester: tester,
147      realValue: ui.window.defaultRouteName,
148      fakeValue: 'fake_route',
149      propertyRetriever: () {
150        return WidgetsBinding.instance.window.defaultRouteName;
151      },
152      propertyFaker: (TestWidgetsFlutterBinding binding, String fakeValue) {
153        binding.window.defaultRouteNameTestValue = fakeValue;
154      },
155    );
156  });
157
158  testWidgets('TestWindow can fake accessibility features', (WidgetTester tester) async {
159    verifyThatTestWindowCanFakeProperty<AccessibilityFeatures>(
160      tester: tester,
161      realValue: ui.window.accessibilityFeatures,
162      fakeValue: const FakeAccessibilityFeatures(),
163      propertyRetriever: () {
164        return WidgetsBinding.instance.window.accessibilityFeatures;
165      },
166      propertyFaker: (TestWidgetsFlutterBinding binding, AccessibilityFeatures fakeValue) {
167        binding.window.accessibilityFeaturesTestValue = fakeValue;
168      },
169    );
170  });
171
172  testWidgets('TestWindow can fake platform brightness', (WidgetTester tester) async {
173    verifyThatTestWindowCanFakeProperty<Brightness>(
174      tester: tester,
175      realValue: Brightness.light,
176      fakeValue: Brightness.dark,
177      propertyRetriever: () {
178        return WidgetsBinding.instance.window.platformBrightness;
179      },
180      propertyFaker: (TestWidgetsFlutterBinding binding, Brightness fakeValue) {
181        binding.window.platformBrightnessTestValue = fakeValue;
182      },
183    );
184  });
185
186  testWidgets('TestWindow can clear out fake properties all at once', (WidgetTester tester) async {
187    final double originalDevicePixelRatio = ui.window.devicePixelRatio;
188    final double originalTextScaleFactor = ui.window.textScaleFactor;
189    final TestWindow testWindow = retrieveTestBinding(tester).window;
190
191    // Set fake values for window properties.
192    testWindow.devicePixelRatioTestValue = 2.5;
193    testWindow.textScaleFactorTestValue = 3.0;
194
195    // Erase fake window property values.
196    testWindow.clearAllTestValues();
197
198    // Verify that the window once again reports real property values.
199    expect(WidgetsBinding.instance.window.devicePixelRatio, originalDevicePixelRatio);
200    expect(WidgetsBinding.instance.window.textScaleFactor, originalTextScaleFactor);
201  });
202}
203
204void verifyThatTestWindowCanFakeProperty<WindowPropertyType>({
205  @required WidgetTester tester,
206  @required WindowPropertyType realValue,
207  @required WindowPropertyType fakeValue,
208  @required WindowPropertyType Function() propertyRetriever,
209  @required Function(TestWidgetsFlutterBinding, WindowPropertyType fakeValue) propertyFaker,
210}) {
211  WindowPropertyType propertyBeforeFaking;
212  WindowPropertyType propertyAfterFaking;
213
214  propertyBeforeFaking = propertyRetriever();
215
216  propertyFaker(retrieveTestBinding(tester), fakeValue);
217
218  propertyAfterFaking = propertyRetriever();
219
220  expect(propertyBeforeFaking, realValue);
221  expect(propertyAfterFaking, fakeValue);
222}
223
224TestWidgetsFlutterBinding retrieveTestBinding(WidgetTester tester) {
225  final WidgetsBinding binding = tester.binding;
226  assert(binding is TestWidgetsFlutterBinding);
227  final TestWidgetsFlutterBinding testBinding = binding;
228  return testBinding;
229}
230
231class FakeWindowPadding implements WindowPadding {
232  const FakeWindowPadding({
233    this.left = 0.0,
234    this.top = 0.0,
235    this.right = 0.0,
236    this.bottom = 0.0,
237  });
238
239  @override
240  final double left;
241
242  @override
243  final double top;
244
245  @override
246  final double right;
247
248  @override
249  final double bottom;
250}
251
252class FakeAccessibilityFeatures implements AccessibilityFeatures {
253  const FakeAccessibilityFeatures({
254    this.accessibleNavigation = false,
255    this.invertColors = false,
256    this.disableAnimations = false,
257    this.boldText = false,
258    this.reduceMotion = false,
259  });
260
261  @override
262  final bool accessibleNavigation;
263
264  @override
265  final bool invertColors;
266
267  @override
268  final bool disableAnimations;
269
270  @override
271  final bool boldText;
272
273  @override
274  final bool reduceMotion;
275}
276