window.dart 14.4 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
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:typed_data' show ByteData;
import 'dart:ui' hide window;

/// [Window] that wraps another [Window] and allows faking of some properties
/// for testing purposes.
///
/// Tests for certain widgets, e.g., [MaterialApp], might require faking certain
12 13 14 15
/// properties of a [Window]. [TestWindow] facilitates the faking of these
/// properties by overriding the properties of a real [Window] with desired fake
/// values. The binding used within tests, [TestWidgetsFlutterBinding], contains
/// a [TestWindow] that is used by all tests.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
///
/// ## Sample Code
///
/// A test can utilize a [TestWindow] in the following way:
///
/// ```dart
/// testWidgets('your test name here', (WidgetTester tester) async {
///   // Retrieve the TestWidgetsFlutterBinding.
///   final TestWidgetsFlutterBinding testBinding = tester.binding;
///
///   // Fake the desired properties of the TestWindow. All code running
///   // within this test will perceive the following fake text scale
///   // factor as the real text scale factor of the window.
///   testBinding.window.textScaleFactorFakeValue = 2.5;
///
///   // Test code that depends on text scale factor here.
/// });
/// ```
///
/// The [TestWidgetsFlutterBinding] is recreated for each test and
/// therefore any fake values defined in one test will not persist
/// to the next.
///
/// If a test needs to override a real [Window] property and then later
/// return to using the real [Window] property, [TestWindow] provides
/// methods to clear each individual test value, e.g., [clearLocaleTestValue()].
///
43 44
/// To clear all fake test values in a [TestWindow], consider using
/// [clearAllTestValues()].
45
class TestWindow implements Window {
46 47
  /// Constructs a [TestWindow] that defers all behavior to the given [Window]
  /// unless explicitly overridden for test purposes.
48
  TestWindow({
49
    required Window window,
50 51 52 53 54 55 56
  }) : _window = window;

  /// The [Window] that is wrapped by this [TestWindow].
  final Window _window;

  @override
  double get devicePixelRatio => _devicePixelRatio ?? _window.devicePixelRatio;
57
  double? _devicePixelRatio;
58 59
  /// Hides the real device pixel ratio and reports the given [devicePixelRatio]
  /// instead.
60 61
  set devicePixelRatioTestValue(double devicePixelRatio) {
    _devicePixelRatio = devicePixelRatio;
62
    onMetricsChanged?.call();
63
  }
64 65
  /// Deletes any existing test device pixel ratio and returns to using the real
  /// device pixel ratio.
66 67
  void clearDevicePixelRatioTestValue() {
    _devicePixelRatio = null;
68
    onMetricsChanged?.call();
69 70 71 72
  }

  @override
  Size get physicalSize => _physicalSizeTestValue ?? _window.physicalSize;
73
  Size? _physicalSizeTestValue;
74 75
  /// Hides the real physical size and reports the given [physicalSizeTestValue]
  /// instead.
76 77
  set physicalSizeTestValue (Size physicalSizeTestValue) {
    _physicalSizeTestValue = physicalSizeTestValue;
78
    onMetricsChanged?.call();
79
  }
80 81
  /// Deletes any existing test physical size and returns to using the real
  /// physical size.
82 83
  void clearPhysicalSizeTestValue() {
    _physicalSizeTestValue = null;
84
    onMetricsChanged?.call();
85 86 87 88
  }

  @override
  WindowPadding get viewInsets => _viewInsetsTestValue ??  _window.viewInsets;
89
  WindowPadding? _viewInsetsTestValue;
90 91
  /// Hides the real view insets and reports the given [viewInsetsTestValue]
  /// instead.
92 93
  set viewInsetsTestValue(WindowPadding viewInsetsTestValue) {
    _viewInsetsTestValue = viewInsetsTestValue;
94
    onMetricsChanged?.call();
95
  }
96 97
  /// Deletes any existing test view insets and returns to using the real view
  /// insets.
98 99
  void clearViewInsetsTestValue() {
    _viewInsetsTestValue = null;
100
    onMetricsChanged?.call();
101 102
  }

103
  @override
104
  WindowPadding get viewPadding => _viewPaddingTestValue ?? _window.padding;
105
  WindowPadding? _viewPaddingTestValue;
106 107
  /// Hides the real view padding and reports the given [paddingTestValue]
  /// instead.
108 109
  set viewPaddingTestValue(WindowPadding viewPaddingTestValue) {
    _viewPaddingTestValue = viewPaddingTestValue;
110
    onMetricsChanged?.call();
111
  }
112 113
  /// Deletes any existing test view padding and returns to using the real
  /// viewPadding.
114 115
  void clearViewPaddingTestValue() {
    _viewPaddingTestValue = null;
116
    onMetricsChanged?.call();
117 118
  }

119 120
  @override
  WindowPadding get padding => _paddingTestValue ?? _window.padding;
121
  WindowPadding? _paddingTestValue;
122 123 124
  /// Hides the real padding and reports the given [paddingTestValue] instead.
  set paddingTestValue(WindowPadding paddingTestValue) {
    _paddingTestValue = paddingTestValue;
125
    onMetricsChanged?.call();
126 127 128 129
  }
  /// Deletes any existing test padding and returns to using the real padding.
  void clearPaddingTestValue() {
    _paddingTestValue = null;
130
    onMetricsChanged?.call();
131 132
  }

133 134
  @override
  WindowPadding get systemGestureInsets => _systemGestureInsetsTestValue ?? _window.systemGestureInsets;
135
  WindowPadding? _systemGestureInsetsTestValue;
136 137 138
  /// Hides the real system gesture insets and reports the given [systemGestureInsetsTestValue] instead.
  set systemGestureInsetsTestValue(WindowPadding systemGestureInsetsTestValue) {
    _systemGestureInsetsTestValue = systemGestureInsetsTestValue;
139
    onMetricsChanged?.call();
140 141 142 143
  }
  /// Deletes any existing test system gesture insets and returns to using the real system gesture insets.
  void clearSystemGestureInsetsTestValue() {
    _systemGestureInsetsTestValue = null;
144
    onMetricsChanged?.call();
145 146
  }

147
  @override
148
  VoidCallback? get onMetricsChanged => _window.onMetricsChanged;
149
  @override
150
  set onMetricsChanged(VoidCallback? callback) {
151 152 153 154
    _window.onMetricsChanged = callback;
  }

  @override
155 156
  Locale? get locale => _localeTestValue ?? _window.locale;
  Locale? _localeTestValue;
157 158 159
  /// Hides the real locale and reports the given [localeTestValue] instead.
  set localeTestValue(Locale localeTestValue) {
    _localeTestValue = localeTestValue;
160
    onLocaleChanged?.call();
161 162 163 164
  }
  /// Deletes any existing test locale and returns to using the real locale.
  void clearLocaleTestValue() {
    _localeTestValue = null;
165
    onLocaleChanged?.call();
166 167 168
  }

  @override
169 170
  List<Locale>? get locales => _localesTestValue ?? _window.locales;
  List<Locale>? _localesTestValue;
171 172 173
  /// Hides the real locales and reports the given [localesTestValue] instead.
  set localesTestValue(List<Locale> localesTestValue) {
    _localesTestValue = localesTestValue;
174
    onLocaleChanged?.call();
175 176 177 178
  }
  /// Deletes any existing test locales and returns to using the real locales.
  void clearLocalesTestValue() {
    _localesTestValue = null;
179
    onLocaleChanged?.call();
180 181 182
  }

  @override
183
  VoidCallback? get onLocaleChanged => _window.onLocaleChanged;
184
  @override
185
  set onLocaleChanged(VoidCallback? callback) {
186 187 188
    _window.onLocaleChanged = callback;
  }

189 190
  @override
  String get initialLifecycleState => _initialLifecycleStateTestValue;
191
  String _initialLifecycleStateTestValue = '';
192 193 194 195 196
  /// Sets a faked initialLifecycleState for testing.
  set initialLifecycleStateTestValue(String state) {
    _initialLifecycleStateTestValue = state;
  }

197 198
  @override
  double get textScaleFactor => _textScaleFactorTestValue ?? _window.textScaleFactor;
199
  double? _textScaleFactorTestValue;
200 201
  /// Hides the real text scale factor and reports the given
  /// [textScaleFactorTestValue] instead.
202 203
  set textScaleFactorTestValue(double textScaleFactorTestValue) {
    _textScaleFactorTestValue = textScaleFactorTestValue;
204
    onTextScaleFactorChanged?.call();
205
  }
206 207
  /// Deletes any existing test text scale factor and returns to using the real
  /// text scale factor.
208 209
  void clearTextScaleFactorTestValue() {
    _textScaleFactorTestValue = null;
210
    onTextScaleFactorChanged?.call();
211 212
  }

213 214
  @override
  Brightness get platformBrightness => _platformBrightnessTestValue ?? _window.platformBrightness;
215
  Brightness? _platformBrightnessTestValue;
216
  @override
217
  VoidCallback? get onPlatformBrightnessChanged => _window.onPlatformBrightnessChanged;
218
  @override
219
  set onPlatformBrightnessChanged(VoidCallback? callback) {
220
    _window.onPlatformBrightnessChanged = callback;
221
  }
222 223
  /// Hides the real text scale factor and reports the given
  /// [platformBrightnessTestValue] instead.
224 225
  set platformBrightnessTestValue(Brightness platformBrightnessTestValue) {
    _platformBrightnessTestValue = platformBrightnessTestValue;
226
    onPlatformBrightnessChanged?.call();
227
  }
228 229
  /// Deletes any existing test platform brightness and returns to using the
  /// real platform brightness.
230 231
  void clearPlatformBrightnessTestValue() {
    _platformBrightnessTestValue = null;
232
    onPlatformBrightnessChanged?.call();
233 234
  }

235 236
  @override
  bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? _window.alwaysUse24HourFormat;
237
  bool? _alwaysUse24HourFormatTestValue;
238 239
  /// Hides the real clock format and reports the given
  /// [alwaysUse24HourFormatTestValue] instead.
240 241 242
  set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) {
    _alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
  }
243 244
  /// Deletes any existing test clock format and returns to using the real clock
  /// format.
245 246 247 248 249
  void clearAlwaysUse24HourTestValue() {
    _alwaysUse24HourFormatTestValue = null;
  }

  @override
250
  VoidCallback? get onTextScaleFactorChanged => _window.onTextScaleFactorChanged;
251
  @override
252
  set onTextScaleFactorChanged(VoidCallback? callback) {
253 254 255 256
    _window.onTextScaleFactorChanged = callback;
  }

  @override
257
  FrameCallback? get onBeginFrame => _window.onBeginFrame;
258
  @override
259
  set onBeginFrame(FrameCallback? callback) {
260 261 262 263
    _window.onBeginFrame = callback;
  }

  @override
264
  VoidCallback? get onDrawFrame => _window.onDrawFrame;
265
  @override
266
  set onDrawFrame(VoidCallback? callback) {
267 268 269
    _window.onDrawFrame = callback;
  }

270
  @override
271
  TimingsCallback? get onReportTimings => _window.onReportTimings;
272
  @override
273
  set onReportTimings(TimingsCallback? callback) {
274 275
    _window.onReportTimings = callback;
  }
276

277
  @override
278
  PointerDataPacketCallback? get onPointerDataPacket => _window.onPointerDataPacket;
279
  @override
280
  set onPointerDataPacket(PointerDataPacketCallback? callback) {
281 282 283 284 285
    _window.onPointerDataPacket = callback;
  }

  @override
  String get defaultRouteName => _defaultRouteNameTestValue ?? _window.defaultRouteName;
286
  String? _defaultRouteNameTestValue;
287 288
  /// Hides the real default route name and reports the given
  /// [defaultRouteNameTestValue] instead.
289 290 291
  set defaultRouteNameTestValue(String defaultRouteNameTestValue) {
    _defaultRouteNameTestValue = defaultRouteNameTestValue;
  }
292 293
  /// Deletes any existing test default route name and returns to using the real
  /// default route name.
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
  void clearDefaultRouteNameTestValue() {
    _defaultRouteNameTestValue = null;
  }

  @override
  void scheduleFrame() {
    _window.scheduleFrame();
  }

  @override
  void render(Scene scene) {
    _window.render(scene);
  }

  @override
  bool get semanticsEnabled => _semanticsEnabledTestValue ?? _window.semanticsEnabled;
310
  bool? _semanticsEnabledTestValue;
311 312
  /// Hides the real semantics enabled and reports the given
  /// [semanticsEnabledTestValue] instead.
313 314
  set semanticsEnabledTestValue(bool semanticsEnabledTestValue) {
    _semanticsEnabledTestValue = semanticsEnabledTestValue;
315
    onSemanticsEnabledChanged?.call();
316
  }
317 318
  /// Deletes any existing test semantics enabled and returns to using the real
  /// semantics enabled.
319 320
  void clearSemanticsEnabledTestValue() {
    _semanticsEnabledTestValue = null;
321
    onSemanticsEnabledChanged?.call();
322 323 324
  }

  @override
325
  VoidCallback? get onSemanticsEnabledChanged => _window.onSemanticsEnabledChanged;
326
  @override
327
  set onSemanticsEnabledChanged(VoidCallback? callback) {
328 329 330 331
    _window.onSemanticsEnabledChanged = callback;
  }

  @override
332
  SemanticsActionCallback? get onSemanticsAction => _window.onSemanticsAction;
333
  @override
334
  set onSemanticsAction(SemanticsActionCallback? callback) {
335 336 337 338 339
    _window.onSemanticsAction = callback;
  }

  @override
  AccessibilityFeatures get accessibilityFeatures => _accessibilityFeaturesTestValue ?? _window.accessibilityFeatures;
340
  AccessibilityFeatures? _accessibilityFeaturesTestValue;
341 342
  /// Hides the real accessibility features and reports the given
  /// [accessibilityFeaturesTestValue] instead.
343 344
  set accessibilityFeaturesTestValue(AccessibilityFeatures accessibilityFeaturesTestValue) {
    _accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
345
    onAccessibilityFeaturesChanged?.call();
346
  }
347 348
  /// Deletes any existing test accessibility features and returns to using the
  /// real accessibility features.
349 350
  void clearAccessibilityFeaturesTestValue() {
    _accessibilityFeaturesTestValue = null;
351
    onAccessibilityFeaturesChanged?.call();
352 353 354
  }

  @override
355
  VoidCallback? get onAccessibilityFeaturesChanged => _window.onAccessibilityFeaturesChanged;
356
  @override
357
  set onAccessibilityFeaturesChanged(VoidCallback? callback) {
358 359 360 361 362 363 364 365 366 367 368 369 370 371
    _window.onAccessibilityFeaturesChanged = callback;
  }

  @override
  void updateSemantics(SemanticsUpdate update) {
    _window.updateSemantics(update);
  }

  @override
  void setIsolateDebugName(String name) {
    _window.setIsolateDebugName(name);
  }

  @override
372 373
  void sendPlatformMessage(
    String name,
374 375
    ByteData? data,
    PlatformMessageResponseCallback? callback,
376
  ) {
377 378 379 380
    _window.sendPlatformMessage(name, data, callback);
  }

  @override
381
  PlatformMessageCallback? get onPlatformMessage => _window.onPlatformMessage;
382
  @override
383
  set onPlatformMessage(PlatformMessageCallback? callback) {
384 385 386 387
    _window.onPlatformMessage = callback;
  }

  /// Delete any test value properties that have been set on this [TestWindow]
388 389
  /// and return to reporting the real [Window] values for all [Window]
  /// properties.
390
  ///
391 392
  /// If desired, clearing of properties can be done on an individual basis,
  /// e.g., [clearLocaleTestValue()].
393 394 395 396 397
  void clearAllTestValues() {
    clearAccessibilityFeaturesTestValue();
    clearAlwaysUse24HourTestValue();
    clearDefaultRouteNameTestValue();
    clearDevicePixelRatioTestValue();
398
    clearPlatformBrightnessTestValue();
399 400 401 402 403 404 405 406
    clearLocaleTestValue();
    clearLocalesTestValue();
    clearPaddingTestValue();
    clearPhysicalSizeTestValue();
    clearSemanticsEnabledTestValue();
    clearTextScaleFactorTestValue();
    clearViewInsetsTestValue();
  }
407 408

  /// This gives us some grace time when the dart:ui side adds something to
409 410
  /// Window, and makes things easier when we do rolls to give us time to catch
  /// up.
411 412 413 414
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
415
}