From fe337dcaf5f540a9eb9bbcc91db77b8bb670c31a Mon Sep 17 00:00:00 2001 From: Swiftaxe Date: Mon, 16 Aug 2021 18:28:11 +0200 Subject: [PATCH] Animation controller test (#88251) Co-authored-by: Alexander Dahlberg Fixes test/animation/animation_controller_test.dart in #85160 Problem: The test 'animateTo can deal with duration == Duration.Zero' was failing with the following error: Expected: <0> Actual: <5> Expected no animation. package:test_api expect package:flutter_test/src/widget_tester.dart 484:3 expect test/animation/animation_controller_test.dart 511:5 main. Following line finds 5 transientCallbacks scheduled, while expecting zero, if shuffled with seed 123: expect(SchedulerBinding.instance!.transientCallbackCount, equals(0), reason: 'Expected no animation.'); This is caused by some other test leaving transientCallbacks scheduled. Fix: By disposing the AnimationController after each test, the transientCallbacks get cleaned up. I chose to dispose all controllers in every test, to make sure there is no risk of leaks. --- .../animation/animation_controller_test.dart | 41 ++++++++++++++++--- 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/packages/flutter/test/animation/animation_controller_test.dart b/packages/flutter/test/animation/animation_controller_test.dart index 3584941212a..265aee9d814 100644 --- a/packages/flutter/test/animation/animation_controller_test.dart +++ b/packages/flutter/test/animation/animation_controller_test.dart @@ -2,12 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// TODO(gspencergoog): Remove this tag once this test's state leaks/test -// dependencies have been fixed. -// https://github.com/flutter/flutter/issues/85160 -// Fails with "flutter test --test-randomize-ordering-seed=123" -@Tags(['no-shuffle']) - import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; @@ -57,6 +51,7 @@ void main() { expect(didDismiss, isTrue); controller.stop(); + controller.dispose(); }); test('Receives status callbacks for forward and reverse', () { @@ -118,6 +113,7 @@ void main() { expect(valueLog, equals([])); controller.stop(); + controller.dispose(); }); test('Forward and reverse from values', () { @@ -144,6 +140,7 @@ void main() { expect(statusLog, equals([ AnimationStatus.dismissed, AnimationStatus.forward ])); expect(valueLog, equals([ 0.0 ])); expect(controller.value, equals(0.0)); + controller.dispose(); }); test('Forward and reverse with different durations', () { @@ -207,6 +204,7 @@ void main() { tick(const Duration(milliseconds: 310)); expect(controller.value, moreOrLessEquals(0.0)); controller.stop(); + controller.dispose(); }); test('Forward only from value', () { @@ -226,6 +224,7 @@ void main() { expect(statusLog, equals([ AnimationStatus.forward ])); expect(valueLog, equals([ 0.2 ])); expect(controller.value, equals(0.2)); + controller.dispose(); }); test('Can fling to upper and lower bounds', () { @@ -256,6 +255,8 @@ void main() { tick(const Duration(seconds: 6)); expect(largeRangeController.value, -30.0); largeRangeController.stop(); + controller.dispose(); + largeRangeController.dispose(); }); test('Custom springDescription can be applied', () { @@ -279,6 +280,8 @@ void main() { tick(const Duration(milliseconds: 50)); expect(customSpringController.value < controller.value, true); + controller.dispose(); + customSpringController.dispose(); }); test('lastElapsedDuration control test', () { @@ -292,6 +295,7 @@ void main() { tick(const Duration(milliseconds: 40)); expect(controller.lastElapsedDuration, equals(const Duration(milliseconds: 20))); controller.stop(); + controller.dispose(); }); test('toString control test', () { @@ -311,6 +315,7 @@ void main() { tick(const Duration(milliseconds: 50)); expect(controller, hasOneLineDescription); controller.stop(); + controller.dispose(); }); test('velocity test - linear', () { @@ -354,6 +359,7 @@ void main() { expect(controller.velocity, 0.0); controller.stop(); + controller.dispose(); }); test('Disposed AnimationController toString works', () { @@ -407,6 +413,7 @@ void main() { ); expect(() { controller.repeat(); }, throwsFlutterError); expect(() { controller.repeat(period: null); }, throwsFlutterError); + controller.dispose(); }); test('Do not animate if already at target', () { @@ -421,6 +428,7 @@ void main() { controller.animateTo(0.5, duration: const Duration(milliseconds: 100)); expect(statusLog, equals([ AnimationStatus.completed ])); expect(controller.value, equals(0.5)); + controller.dispose(); }); test('Do not animate to upperBound if already at upperBound', () { @@ -437,6 +445,7 @@ void main() { controller.animateTo(1.0, duration: const Duration(milliseconds: 100)); expect(statusLog, equals([ AnimationStatus.completed ])); expect(controller.value, equals(1.0)); + controller.dispose(); }); test('Do not animate to lowerBound if already at lowerBound', () { @@ -453,6 +462,7 @@ void main() { controller.animateTo(0.0, duration: const Duration(milliseconds: 100)); expect(statusLog, equals([ AnimationStatus.completed ])); expect(controller.value, equals(0.0)); + controller.dispose(); }); test('Do not animate if already at target mid-flight (forward)', () { @@ -475,6 +485,7 @@ void main() { controller.animateTo(currentValue, duration: const Duration(milliseconds: 100)); expect(statusLog, equals([ AnimationStatus.forward, AnimationStatus.completed ])); expect(controller.value, currentValue); + controller.dispose(); }); test('Do not animate if already at target mid-flight (reverse)', () { @@ -497,6 +508,7 @@ void main() { controller.animateTo(currentValue, duration: const Duration(milliseconds: 100)); expect(statusLog, equals([ AnimationStatus.reverse, AnimationStatus.completed ])); expect(controller.value, currentValue); + controller.dispose(); }); test('animateTo can deal with duration == Duration.zero', () { @@ -510,6 +522,7 @@ void main() { controller.animateTo(1.0, duration: Duration.zero); expect(SchedulerBinding.instance!.transientCallbackCount, equals(0), reason: 'Expected no animation.'); expect(controller.value, 1.0); + controller.dispose(); }); test('resetting animation works at all phases', () { @@ -563,6 +576,7 @@ void main() { expect(controller.value, 0.0); expect(controller.status, AnimationStatus.dismissed); expect(statusLog, equals([ AnimationStatus.forward, AnimationStatus.completed, AnimationStatus.dismissed ])); + controller.dispose(); }); test('setting value directly sets correct status', () { @@ -591,6 +605,7 @@ void main() { controller.value = 0.0; expect(controller.value, 0.0); expect(controller.status, AnimationStatus.dismissed); + controller.dispose(); }); test('animateTo sets correct status', () { @@ -637,6 +652,7 @@ void main() { expect(controller.value, 0.0); expect(statusLog, equals([ AnimationStatus.forward, AnimationStatus.completed ])); statusLog.clear(); + controller.dispose(); }); test('after a reverse call animateTo sets correct status', () { @@ -665,6 +681,7 @@ void main() { expect(controller.value, 0.5); expect(statusLog, equals([ AnimationStatus.forward, AnimationStatus.completed ])); statusLog.clear(); + controller.dispose(); }); test('after a forward call animateTo sets correct status', () { @@ -693,6 +710,7 @@ void main() { expect(controller.value, 0.5); expect(statusLog, equals([ AnimationStatus.forward, AnimationStatus.completed ])); statusLog.clear(); + controller.dispose(); }); test( @@ -743,6 +761,7 @@ void main() { tick(Duration.zero); tick(const Duration(milliseconds: 150)); expect(controller.value, 0.0); + controller.dispose(); }, ); @@ -785,6 +804,7 @@ void main() { tick(Duration.zero); tick(const Duration(milliseconds: 125)); expect(controller.value, 1.0); + controller.dispose(); }, ); @@ -795,6 +815,8 @@ void main() { final AnimationController repeating = AnimationController.unbounded(vsync: const TestVSync()); expect(repeating.animationBehavior, AnimationBehavior.preserve); + controller.dispose(); + repeating.dispose(); }); test('AnimationBehavior.preserve runs at normal speed when animatingTo', () { @@ -820,6 +842,7 @@ void main() { expect(controller.value, 1.0); expect(controller.status, AnimationStatus.completed); debugSemanticsDisableAnimations = false; + controller.dispose(); }); test('AnimationBehavior.normal runs at 20x speed when animatingTo', () { @@ -845,6 +868,7 @@ void main() { expect(controller.value, 1.0); expect(controller.status, AnimationStatus.completed); debugSemanticsDisableAnimations = null; + controller.dispose(); }); test('AnimationBehavior.normal runs "faster" than AnimationBehavior.preserve', () { @@ -864,6 +888,8 @@ void main() { // We don't assert a specific faction that normal animation. expect(controller.value < fastController.value, true); debugSemanticsDisableAnimations = null; + controller.dispose(); + fastController.dispose(); }); }); @@ -895,6 +921,7 @@ void main() { tick(Duration.zero); tick(const Duration(seconds: 2)); expect(statuses, [AnimationStatus.forward]); + controller.dispose(); }); test('Simulations run forward even after a reverse run', () { @@ -915,6 +942,7 @@ void main() { tick(Duration.zero); tick(const Duration(seconds: 2)); expect(statuses, [AnimationStatus.forward]); + controller.dispose(); }); test('Repeating animation with reverse: true report as forward and reverse', () { @@ -933,6 +961,7 @@ void main() { statuses.clear(); tick(const Duration(seconds: 1)); expect(statuses, [AnimationStatus.reverse]); + controller.dispose(); }); test('AnimateBack can runs successfully with just "reverseDuration" property set', () {