window.dart 14.2 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
// 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;

import 'package:meta/meta.dart';

/// [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
14 15 16 17
/// 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.
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 43 44
///
/// ## 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()].
///
45 46
/// To clear all fake test values in a [TestWindow], consider using
/// [clearAllTestValues()].
47
class TestWindow implements Window {
48 49
  /// Constructs a [TestWindow] that defers all behavior to the given [Window]
  /// unless explicitly overridden for test purposes.
50 51 52 53 54 55 56 57 58 59
  TestWindow({
    @required Window window,
  }) : _window = window;

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

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

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

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

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

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

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

149 150 151 152 153 154 155 156 157 158 159 160 161
  @override
  VoidCallback get onMetricsChanged => _window.onMetricsChanged;
  @override
  set onMetricsChanged(VoidCallback callback) {
    _window.onMetricsChanged = callback;
  }

  @override
  Locale get locale => _localeTestValue ?? _window.locale;
  Locale _localeTestValue;
  /// Hides the real locale and reports the given [localeTestValue] instead.
  set localeTestValue(Locale localeTestValue) {
    _localeTestValue = localeTestValue;
162
    onLocaleChanged();
163 164 165 166
  }
  /// Deletes any existing test locale and returns to using the real locale.
  void clearLocaleTestValue() {
    _localeTestValue = null;
167
    onLocaleChanged();
168 169 170 171 172 173 174 175
  }

  @override
  List<Locale> get locales => _localesTestValue ?? _window.locales;
  List<Locale> _localesTestValue;
  /// Hides the real locales and reports the given [localesTestValue] instead.
  set localesTestValue(List<Locale> localesTestValue) {
    _localesTestValue = localesTestValue;
176
    onLocaleChanged();
177 178 179 180
  }
  /// Deletes any existing test locales and returns to using the real locales.
  void clearLocalesTestValue() {
    _localesTestValue = null;
181
    onLocaleChanged();
182 183 184 185 186 187 188 189 190
  }

  @override
  VoidCallback get onLocaleChanged => _window.onLocaleChanged;
  @override
  set onLocaleChanged(VoidCallback callback) {
    _window.onLocaleChanged = callback;
  }

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

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

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

237 238 239
  @override
  bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? _window.alwaysUse24HourFormat;
  bool _alwaysUse24HourFormatTestValue;
240 241
  /// Hides the real clock format and reports the given
  /// [alwaysUse24HourFormatTestValue] instead.
242 243 244
  set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) {
    _alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
  }
245 246
  /// Deletes any existing test clock format and returns to using the real clock
  /// format.
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
  void clearAlwaysUse24HourTestValue() {
    _alwaysUse24HourFormatTestValue = null;
  }

  @override
  VoidCallback get onTextScaleFactorChanged => _window.onTextScaleFactorChanged;
  @override
  set onTextScaleFactorChanged(VoidCallback callback) {
    _window.onTextScaleFactorChanged = callback;
  }

  @override
  FrameCallback get onBeginFrame => _window.onBeginFrame;
  @override
  set onBeginFrame(FrameCallback callback) {
    _window.onBeginFrame = callback;
  }

  @override
  VoidCallback get onDrawFrame => _window.onDrawFrame;
  @override
  set onDrawFrame(VoidCallback callback) {
    _window.onDrawFrame = callback;
  }

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

279 280 281 282 283 284 285 286 287 288
  @override
  PointerDataPacketCallback get onPointerDataPacket => _window.onPointerDataPacket;
  @override
  set onPointerDataPacket(PointerDataPacketCallback callback) {
    _window.onPointerDataPacket = callback;
  }

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

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

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

  @override
  bool get semanticsEnabled => _semanticsEnabledTestValue ?? _window.semanticsEnabled;
  bool _semanticsEnabledTestValue;
313 314
  /// Hides the real semantics enabled and reports the given
  /// [semanticsEnabledTestValue] instead.
315 316
  set semanticsEnabledTestValue(bool semanticsEnabledTestValue) {
    _semanticsEnabledTestValue = semanticsEnabledTestValue;
317
    onSemanticsEnabledChanged();
318
  }
319 320
  /// Deletes any existing test semantics enabled and returns to using the real
  /// semantics enabled.
321 322
  void clearSemanticsEnabledTestValue() {
    _semanticsEnabledTestValue = null;
323
    onSemanticsEnabledChanged();
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342
  }

  @override
  VoidCallback get onSemanticsEnabledChanged => _window.onSemanticsEnabledChanged;
  @override
  set onSemanticsEnabledChanged(VoidCallback callback) {
    _window.onSemanticsEnabledChanged = callback;
  }

  @override
  SemanticsActionCallback get onSemanticsAction => _window.onSemanticsAction;
  @override
  set onSemanticsAction(SemanticsActionCallback callback) {
    _window.onSemanticsAction = callback;
  }

  @override
  AccessibilityFeatures get accessibilityFeatures => _accessibilityFeaturesTestValue ?? _window.accessibilityFeatures;
  AccessibilityFeatures _accessibilityFeaturesTestValue;
343 344
  /// Hides the real accessibility features and reports the given
  /// [accessibilityFeaturesTestValue] instead.
345 346
  set accessibilityFeaturesTestValue(AccessibilityFeatures accessibilityFeaturesTestValue) {
    _accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
347
    onAccessibilityFeaturesChanged();
348
  }
349 350
  /// Deletes any existing test accessibility features and returns to using the
  /// real accessibility features.
351 352
  void clearAccessibilityFeaturesTestValue() {
    _accessibilityFeaturesTestValue = null;
353
    onAccessibilityFeaturesChanged();
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
  }

  @override
  VoidCallback get onAccessibilityFeaturesChanged => _window.onAccessibilityFeaturesChanged;
  @override
  set onAccessibilityFeaturesChanged(VoidCallback callback) {
    _window.onAccessibilityFeaturesChanged = callback;
  }

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

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

  @override
374 375 376 377 378
  void sendPlatformMessage(
    String name,
    ByteData data,
    PlatformMessageResponseCallback callback,
  ) {
379 380 381 382 383 384 385 386 387 388 389
    _window.sendPlatformMessage(name, data, callback);
  }

  @override
  PlatformMessageCallback get onPlatformMessage => _window.onPlatformMessage;
  @override
  set onPlatformMessage(PlatformMessageCallback callback) {
    _window.onPlatformMessage = callback;
  }

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

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