mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Animation controller test (#88251)
Co-authored-by: Alexander Dahlberg <alexander.dahlberg@sigma.se> 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.
This commit is contained in:
parent
06be7e5392
commit
fe337dcaf5
@ -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(<String>['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(<AnimationStatus>[]));
|
||||
|
||||
controller.stop();
|
||||
controller.dispose();
|
||||
});
|
||||
|
||||
test('Forward and reverse from values', () {
|
||||
@ -144,6 +140,7 @@ void main() {
|
||||
expect(statusLog, equals(<AnimationStatus>[ AnimationStatus.dismissed, AnimationStatus.forward ]));
|
||||
expect(valueLog, equals(<double>[ 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>[ AnimationStatus.forward ]));
|
||||
expect(valueLog, equals(<double>[ 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>[ 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>[ 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>[ 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>[ 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>[ 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>[ 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>[ 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>[ 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>[ 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>[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>[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>[AnimationStatus.reverse]);
|
||||
controller.dispose();
|
||||
});
|
||||
|
||||
test('AnimateBack can runs successfully with just "reverseDuration" property set', () {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user