1// Copyright 2014 The Flutter 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
5// TODO(gspencergoog): Remove this tag once this test's state leaks/test
6// dependencies have been fixed.
7// https://github.com/flutter/flutter/issues/85160
8// Fails with "flutter test --test-randomize-ordering-seed=20210721"
9@Tags(<String>['no-shuffle'])
10library;
11
12import 'dart:async';
13import 'dart:io';
14
15import 'package:flutter/material.dart';
16import 'package:flutter/services.dart';
17import 'package:flutter_test/flutter_test.dart';
18
19void main() {
20 final AutomatedTestWidgetsFlutterBinding binding = AutomatedTestWidgetsFlutterBinding();
21
22 group(TestViewConfiguration, () {
23 test('is initialized with top-level window if one is not provided', () {
24 // The code below will throw without the default.
25 TestViewConfiguration(size: const Size(1280.0, 800.0));
26 });
27
28 test('toMatrix handles zero size', () {
29 // The code below will throw without the default.
30 final Matrix4 matrix = TestViewConfiguration(size: Size.zero).toMatrix();
31 expect(matrix.storage.every((double x) => x.isFinite), isTrue);
32 });
33
34 test('sets the DPR to match the window', () {
35 final TestViewConfiguration configuration = TestViewConfiguration(
36 size: const Size(1280.0, 800.0),
37 );
38 expect(configuration.devicePixelRatio, binding.window.devicePixelRatio);
39 });
40 });
41
42 group(AutomatedTestWidgetsFlutterBinding, () {
43 test('allows setting defaultTestTimeout to 5 minutes', () {
44 binding.defaultTestTimeout = const Timeout(Duration(minutes: 5));
45 expect(binding.defaultTestTimeout.duration, const Duration(minutes: 5));
46 });
47 });
48
49 // The next three tests must run in order -- first using `test`, then `testWidgets`, then `test` again.
50
51 int order = 0;
52
53 test('Initializes httpOverrides and testTextInput', () async {
54 assert(order == 0);
55 expect(binding.testTextInput, isNotNull);
56 expect(binding.testTextInput.isRegistered, isFalse);
57 expect(HttpOverrides.current, isNotNull);
58 order += 1;
59 });
60
61 testWidgets('Registers testTextInput', (WidgetTester tester) async {
62 assert(order == 1);
63 expect(tester.testTextInput.isRegistered, isTrue);
64 order += 1;
65 });
66
67 test('Unregisters testTextInput', () async {
68 assert(order == 2);
69 expect(binding.testTextInput.isRegistered, isFalse);
70 order += 1;
71 });
72
73 testWidgets('timeStamp should be accurate to microsecond precision', (WidgetTester tester) async {
74 final WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
75
76 await tester.pumpWidget(const CircularProgressIndicator());
77
78 final Duration timeStampBefore = widgetsBinding.currentSystemFrameTimeStamp;
79 await tester.pump(const Duration(microseconds: 12345));
80 final Duration timeStampAfter = widgetsBinding.currentSystemFrameTimeStamp;
81
82 expect(timeStampAfter - timeStampBefore, const Duration(microseconds: 12345));
83 });
84
85 group('elapseBlocking', () {
86 testWidgets('timer is not called', (WidgetTester tester) async {
87 bool timerCalled = false;
88 Timer.run(() => timerCalled = true);
89
90 binding.elapseBlocking(const Duration(seconds: 1));
91
92 expect(timerCalled, false);
93 binding.idle();
94 });
95
96 testWidgets('can use to simulate slow build', (WidgetTester tester) async {
97 final DateTime beforeTime = binding.clock.now();
98
99 await tester.pumpWidget(
100 Builder(
101 builder: (_) {
102 bool timerCalled = false;
103 Timer.run(() => timerCalled = true);
104
105 binding.elapseBlocking(const Duration(seconds: 1));
106
107 // if we use `delayed` instead of `elapseBlocking`, such as
108 // binding.delayed(const Duration(seconds: 1));
109 // the timer will be called here. Surely, that violates how
110 // a flutter widget build works
111 expect(timerCalled, false);
112
113 return Container();
114 },
115 ),
116 );
117
118 expect(binding.clock.now(), beforeTime.add(const Duration(seconds: 1)));
119 binding.idle();
120 });
121 });
122
123 testWidgets('Assets in the tester can be loaded without turning event loop', (
124 WidgetTester tester,
125 ) async {
126 bool responded = false;
127 // The particular asset does not matter, as long as it exists.
128 rootBundle.load('AssetManifest.json').then((ByteData data) {
129 responded = true;
130 });
131 expect(responded, true);
132 });
133}
134