diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart index 758b32ce0ab..a901f33ec65 100644 --- a/packages/flutter_test/lib/src/binding.dart +++ b/packages/flutter_test/lib/src/binding.dart @@ -1277,6 +1277,12 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { return Future.value(); } + /// Simulates the synchronous passage of time, resulting from blocking or + /// expensive calls. + void elapseBlocking(Duration duration) { + _currentFakeAsync!.elapseBlocking(duration); + } + @override Future runTest( Future Function() testBody, diff --git a/packages/flutter_test/test/bindings_test.dart b/packages/flutter_test/test/bindings_test.dart index c5a4b923db0..8773abfc278 100644 --- a/packages/flutter_test/test/bindings_test.dart +++ b/packages/flutter_test/test/bindings_test.dart @@ -7,7 +7,7 @@ // https://github.com/flutter/flutter/issues/85160 // Fails with "flutter test --test-randomize-ordering-seed=20210721" @Tags(['no-shuffle']) - +import 'dart:async'; import 'dart:io'; import 'package:flutter/widgets.dart'; @@ -56,4 +56,38 @@ void main() { expect(binding.testTextInput.isRegistered, isFalse); order += 1; }); + + group('elapseBlocking', () { + testWidgets('timer is not called', (WidgetTester tester) async { + bool timerCalled = false; + Timer.run(() => timerCalled = true); + + binding.elapseBlocking(const Duration(seconds: 1)); + + expect(timerCalled, false); + binding.idle(); + }); + + testWidgets('can use to simulate slow build', (WidgetTester tester) async { + final DateTime beforeTime = binding.clock.now(); + + await tester.pumpWidget(Builder(builder: (_) { + bool timerCalled = false; + Timer.run(() => timerCalled = true); + + binding.elapseBlocking(const Duration(seconds: 1)); + + // if we use `delayed` instead of `elapseBlocking`, such as + // binding.delayed(const Duration(seconds: 1)); + // the timer will be called here. Surely, that violates how + // a flutter widget build works + expect(timerCalled, false); + + return Container(); + })); + + expect(binding.clock.now(), beforeTime.add(const Duration(seconds: 1))); + binding.idle(); + }); + }); }