Fix bug thattimeDilation is not reset, causing subsequent test errors, and add verifications to ensure such problem does not exist in the future (#113830)

This commit is contained in:
fzyzcjy 2022-11-02 06:50:00 +08:00 committed by GitHub
parent c23b5ca7db
commit 61deaef5df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 0 deletions

View file

@ -119,6 +119,7 @@ Future<File> generateTest(Directory apiDir) async {
// Collect the examples, and import them all as separate symbols.
final List<String> imports = <String>[];
imports.add('''import 'package:flutter/widgets.dart';''');
imports.add('''import 'package:flutter/scheduler.dart';''');
imports.add('''import 'package:flutter_test/flutter_test.dart';''');
imports.add('''import 'package:integration_test/integration_test.dart';''');
final List<ExampleInfo> infoList = <ExampleInfo>[];
@ -165,6 +166,7 @@ void main() {
expect(find.byType(WidgetsApp), findsOneWidget);
} finally {
ErrorWidget.builder = originalBuilder;
timeDilation = 1.0;
}
},
);

View file

@ -652,6 +652,20 @@ mixin SchedulerBinding on BindingBase {
return true;
}
/// Asserts that there is no artificial time dilation in debug mode.
///
/// Throws a [FlutterError] if there are such dilation, as this will make
/// subsequent tests see dilation and thus flaky.
bool debugAssertNoTimeDilation(String reason) {
assert(() {
if (timeDilation != 1.0) {
throw FlutterError(reason);
}
return true;
}());
return true;
}
/// Prints the stack for where the current transient callback was registered.
///
/// A transient frame callback is one that was registered with

View file

@ -13,4 +13,19 @@ void main() {
SchedulerBinding.instance.scheduleForcedFrame();
expect(SchedulerBinding.instance.platformDispatcher.onBeginFrame, isNotNull);
});
test('debugAssertNoTimeDilation does not throw if time dilate already reset', () async {
timeDilation = 2.0;
timeDilation = 1.0;
SchedulerBinding.instance.debugAssertNoTimeDilation('reason'); // no error
});
test('debugAssertNoTimeDilation throw if time dilate not reset', () async {
timeDilation = 3.0;
expect(
() => SchedulerBinding.instance.debugAssertNoTimeDilation('reason'),
throwsA(isA<FlutterError>().having((FlutterError e) => e.message, 'message', 'reason')),
);
timeDilation = 1.0;
});
}

View file

@ -215,6 +215,8 @@ void main() {
tick(const Duration(seconds: 8));
expect(lastTimeStamp, const Duration(seconds: 3)); // 2s + (8 - 6)s / 2
expect(lastSystemTimeStamp, const Duration(seconds: 8));
timeDilation = 1.0; // restore time dilation, or it will affect other tests
});
test('Animation frame scheduled in the middle of the warm-up frame', () {

View file

@ -124,6 +124,8 @@ void main() {
expect(lastDuration, const Duration(milliseconds: 20));
ticker.dispose();
timeDilation = 1.0; // restore time dilation, or it will affect other tests
});
testWidgets('Ticker can be slowed down with time dilation', (WidgetTester tester) async {
@ -140,6 +142,8 @@ void main() {
expect(lastDuration, const Duration(milliseconds: 5));
ticker.dispose();
timeDilation = 1.0; // restore time dilation, or it will affect other tests
});
testWidgets('Ticker stops ticking when application is paused', (WidgetTester tester) async {

View file

@ -965,6 +965,9 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
assert(debugAssertNoPendingPerformanceModeRequests(
'A performance mode was requested and not disposed by a test.'
));
assert(debugAssertNoTimeDilation(
'The timeDilation was changed and not reset by the test.'
));
assert(debugAssertAllFoundationVarsUnset(
'The value of a foundation debug variable was changed by the test.',
debugPrintOverride: debugPrintOverride,