window.dart 14.8 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 92 93 94 95 96 97 98 99 100 101 102 103 104
  @override
  double get physicalDepth => _physicalDepthTestValue ?? _window.physicalDepth;
  double _physicalDepthTestValue;
  /// Hides the real physical depth and reports the given
  /// [physicalDepthTestValue] instead.
  set physicalDepthTestValue (double physicalDepthTestValue) {
    _physicalDepthTestValue = physicalDepthTestValue;
    onMetricsChanged();
  }
  /// Deletes any existing test physical depth and returns to using the real
  /// physical depth.
  void clearPhysicalDepthTestValue() {
    _physicalDepthTestValue = null;
    onMetricsChanged();
  }

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

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

137 138 139 140 141 142
  @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;
143
    onMetricsChanged();
144 145 146 147
  }
  /// Deletes any existing test padding and returns to using the real padding.
  void clearPaddingTestValue() {
    _paddingTestValue = null;
148
    onMetricsChanged();
149 150
  }

151 152 153 154 155 156 157 158 159 160 161 162 163 164
  @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();
  }

165 166 167 168 169 170 171 172 173 174 175 176 177
  @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;
178
    onLocaleChanged();
179 180 181 182
  }
  /// Deletes any existing test locale and returns to using the real locale.
  void clearLocaleTestValue() {
    _localeTestValue = null;
183
    onLocaleChanged();
184 185 186 187 188 189 190 191
  }

  @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;
192
    onLocaleChanged();
193 194 195 196
  }
  /// Deletes any existing test locales and returns to using the real locales.
  void clearLocalesTestValue() {
    _localesTestValue = null;
197
    onLocaleChanged();
198 199 200 201 202 203 204 205 206
  }

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

207 208 209 210 211 212 213 214
  @override
  String get initialLifecycleState => _initialLifecycleStateTestValue;
  String _initialLifecycleStateTestValue;
  /// Sets a faked initialLifecycleState for testing.
  set initialLifecycleStateTestValue(String state) {
    _initialLifecycleStateTestValue = state;
  }

215 216 217
  @override
  double get textScaleFactor => _textScaleFactorTestValue ?? _window.textScaleFactor;
  double _textScaleFactorTestValue;
218 219
  /// Hides the real text scale factor and reports the given
  /// [textScaleFactorTestValue] instead.
220 221
  set textScaleFactorTestValue(double textScaleFactorTestValue) {
    _textScaleFactorTestValue = textScaleFactorTestValue;
222
    onTextScaleFactorChanged();
223
  }
224 225
  /// Deletes any existing test text scale factor and returns to using the real
  /// text scale factor.
226 227
  void clearTextScaleFactorTestValue() {
    _textScaleFactorTestValue = null;
228
    onTextScaleFactorChanged();
229 230
  }

231 232 233 234 235 236 237
  @override
  Brightness get platformBrightness => _platformBrightnessTestValue ?? _window.platformBrightness;
  Brightness _platformBrightnessTestValue;
  @override
  VoidCallback get onPlatformBrightnessChanged => _window.onPlatformBrightnessChanged;
  @override
  set onPlatformBrightnessChanged(VoidCallback callback) {
238
    _window.onPlatformBrightnessChanged = callback;
239
  }
240 241
  /// Hides the real text scale factor and reports the given
  /// [platformBrightnessTestValue] instead.
242 243
  set platformBrightnessTestValue(Brightness platformBrightnessTestValue) {
    _platformBrightnessTestValue = platformBrightnessTestValue;
244
    onPlatformBrightnessChanged();
245
  }
246 247
  /// Deletes any existing test platform brightness and returns to using the
  /// real platform brightness.
248 249
  void clearPlatformBrightnessTestValue() {
    _platformBrightnessTestValue = null;
250
    onPlatformBrightnessChanged();
251 252
  }

253 254 255
  @override
  bool get alwaysUse24HourFormat => _alwaysUse24HourFormatTestValue ?? _window.alwaysUse24HourFormat;
  bool _alwaysUse24HourFormatTestValue;
256 257
  /// Hides the real clock format and reports the given
  /// [alwaysUse24HourFormatTestValue] instead.
258 259 260
  set alwaysUse24HourFormatTestValue(bool alwaysUse24HourFormatTestValue) {
    _alwaysUse24HourFormatTestValue = alwaysUse24HourFormatTestValue;
  }
261 262
  /// Deletes any existing test clock format and returns to using the real clock
  /// format.
263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
  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;
  }

288
  @override
289 290 291 292 293
  TimingsCallback get onReportTimings => _window.onReportTimings;
  @override
  set onReportTimings(TimingsCallback callback) {
    _window.onReportTimings = callback;
  }
294

295 296 297 298 299 300 301 302 303 304
  @override
  PointerDataPacketCallback get onPointerDataPacket => _window.onPointerDataPacket;
  @override
  set onPointerDataPacket(PointerDataPacketCallback callback) {
    _window.onPointerDataPacket = callback;
  }

  @override
  String get defaultRouteName => _defaultRouteNameTestValue ?? _window.defaultRouteName;
  String _defaultRouteNameTestValue;
305 306
  /// Hides the real default route name and reports the given
  /// [defaultRouteNameTestValue] instead.
307 308 309
  set defaultRouteNameTestValue(String defaultRouteNameTestValue) {
    _defaultRouteNameTestValue = defaultRouteNameTestValue;
  }
310 311
  /// Deletes any existing test default route name and returns to using the real
  /// default route name.
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
  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;
329 330
  /// Hides the real semantics enabled and reports the given
  /// [semanticsEnabledTestValue] instead.
331 332
  set semanticsEnabledTestValue(bool semanticsEnabledTestValue) {
    _semanticsEnabledTestValue = semanticsEnabledTestValue;
333
    onSemanticsEnabledChanged();
334
  }
335 336
  /// Deletes any existing test semantics enabled and returns to using the real
  /// semantics enabled.
337 338
  void clearSemanticsEnabledTestValue() {
    _semanticsEnabledTestValue = null;
339
    onSemanticsEnabledChanged();
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
  }

  @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;
359 360
  /// Hides the real accessibility features and reports the given
  /// [accessibilityFeaturesTestValue] instead.
361 362
  set accessibilityFeaturesTestValue(AccessibilityFeatures accessibilityFeaturesTestValue) {
    _accessibilityFeaturesTestValue = accessibilityFeaturesTestValue;
363
    onAccessibilityFeaturesChanged();
364
  }
365 366
  /// Deletes any existing test accessibility features and returns to using the
  /// real accessibility features.
367 368
  void clearAccessibilityFeaturesTestValue() {
    _accessibilityFeaturesTestValue = null;
369
    onAccessibilityFeaturesChanged();
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
  }

  @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
390 391 392 393 394
  void sendPlatformMessage(
    String name,
    ByteData data,
    PlatformMessageResponseCallback callback,
  ) {
395 396 397 398 399 400 401 402 403 404 405
    _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]
406 407
  /// and return to reporting the real [Window] values for all [Window]
  /// properties.
408
  ///
409 410
  /// If desired, clearing of properties can be done on an individual basis,
  /// e.g., [clearLocaleTestValue()].
411 412 413 414 415
  void clearAllTestValues() {
    clearAccessibilityFeaturesTestValue();
    clearAlwaysUse24HourTestValue();
    clearDefaultRouteNameTestValue();
    clearDevicePixelRatioTestValue();
416
    clearPlatformBrightnessTestValue();
417 418 419 420
    clearLocaleTestValue();
    clearLocalesTestValue();
    clearPaddingTestValue();
    clearPhysicalSizeTestValue();
421
    clearPhysicalDepthTestValue();
422 423 424 425
    clearSemanticsEnabledTestValue();
    clearTextScaleFactorTestValue();
    clearViewInsetsTestValue();
  }
426 427

  /// This gives us some grace time when the dart:ui side adds something to
428 429
  /// Window, and makes things easier when we do rolls to give us time to catch
  /// up.
430 431 432 433
  @override
  dynamic noSuchMethod(Invocation invocation) {
    return null;
  }
434
}