966 lines
29 KiB
Dart
966 lines
29 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
class MockOnEndFunction {
|
|
int called = 0;
|
|
|
|
void handler() {
|
|
called++;
|
|
}
|
|
}
|
|
|
|
const Duration animationDuration = Duration(milliseconds: 1000);
|
|
const Duration additionalDelay = Duration(milliseconds: 1);
|
|
|
|
void main() {
|
|
late MockOnEndFunction mockOnEndFunction;
|
|
const switchKey = Key('switchKey');
|
|
|
|
setUp(() {
|
|
mockOnEndFunction = MockOnEndFunction();
|
|
});
|
|
|
|
testWidgets('BoxConstraintsTween control test', (WidgetTester tester) async {
|
|
final tween = BoxConstraintsTween(
|
|
begin: BoxConstraints.tight(const Size(20.0, 50.0)),
|
|
end: BoxConstraints.tight(const Size(10.0, 30.0)),
|
|
);
|
|
final BoxConstraints result = tween.lerp(0.25);
|
|
expect(result.minWidth, 17.5);
|
|
expect(result.maxWidth, 17.5);
|
|
expect(result.minHeight, 45.0);
|
|
expect(result.maxHeight, 45.0);
|
|
});
|
|
|
|
testWidgets('DecorationTween control test', (WidgetTester tester) async {
|
|
final tween = DecorationTween(
|
|
begin: const BoxDecoration(color: Color(0xFF00FF00)),
|
|
end: const BoxDecoration(color: Color(0xFFFFFF00)),
|
|
);
|
|
final result = tween.lerp(0.25) as BoxDecoration;
|
|
expect(result.color, isSameColorAs(const Color(0xFF3FFF00)));
|
|
});
|
|
|
|
testWidgets('EdgeInsetsTween control test', (WidgetTester tester) async {
|
|
final tween = EdgeInsetsTween(
|
|
begin: const EdgeInsets.symmetric(vertical: 50.0),
|
|
end: const EdgeInsets.only(top: 10.0, bottom: 30.0),
|
|
);
|
|
final EdgeInsets result = tween.lerp(0.25);
|
|
expect(result.left, 0.0);
|
|
expect(result.right, 0.0);
|
|
expect(result.top, 40.0);
|
|
expect(result.bottom, 45.0);
|
|
});
|
|
|
|
testWidgets('Matrix4Tween control test', (WidgetTester tester) async {
|
|
final tween = Matrix4Tween(
|
|
begin: Matrix4.translationValues(10.0, 20.0, 30.0),
|
|
end: Matrix4.translationValues(14.0, 24.0, 34.0),
|
|
);
|
|
final Matrix4 result = tween.lerp(0.25);
|
|
expect(result, equals(Matrix4.translationValues(11.0, 21.0, 31.0)));
|
|
});
|
|
|
|
testWidgets('AnimatedContainer onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedContainerWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedPadding onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedPaddingWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedAlign onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedAlignWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedPositioned onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedPositionedWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedPositionedDirectional onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedPositionedDirectionalWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedSlide onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedSlideWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedSlide transition test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(switchKey: switchKey, state: _TestAnimatedSlideWidgetState()),
|
|
),
|
|
);
|
|
|
|
final RebuildCountingState<StatefulWidget> state = tester
|
|
.widget<TestAnimatedWidget>(find.byType(TestAnimatedWidget))
|
|
.rebuildState!;
|
|
final Finder switchFinder = find.byKey(switchKey);
|
|
final SlideTransition slideWidget = tester.widget<SlideTransition>(
|
|
find.ancestor(of: find.byType(Placeholder), matching: find.byType(SlideTransition)).first,
|
|
);
|
|
|
|
expect(state.builds, equals(1));
|
|
|
|
await tester.tap(switchFinder);
|
|
expect(state.builds, equals(1));
|
|
await tester.pump();
|
|
expect(slideWidget.position.value, equals(Offset.zero));
|
|
expect(state.builds, equals(2));
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(slideWidget.position.value, equals(const Offset(0.5, 0.5)));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(slideWidget.position.value, equals(const Offset(0.75, 0.75)));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(slideWidget.position.value, equals(const Offset(1, 1)));
|
|
expect(state.builds, equals(2));
|
|
});
|
|
|
|
testWidgets('AnimatedScale onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedScaleWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedScale transition test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(switchKey: switchKey, state: _TestAnimatedScaleWidgetState()),
|
|
),
|
|
);
|
|
|
|
final RebuildCountingState<StatefulWidget> state = tester
|
|
.widget<TestAnimatedWidget>(find.byType(TestAnimatedWidget))
|
|
.rebuildState!;
|
|
final Finder switchFinder = find.byKey(switchKey);
|
|
final ScaleTransition scaleWidget = tester.widget<ScaleTransition>(
|
|
find.ancestor(of: find.byType(Placeholder), matching: find.byType(ScaleTransition)).first,
|
|
);
|
|
|
|
expect(state.builds, equals(1));
|
|
|
|
await tester.tap(switchFinder);
|
|
expect(state.builds, equals(1));
|
|
await tester.pump();
|
|
expect(scaleWidget.scale.value, equals(1.0));
|
|
expect(state.builds, equals(2));
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(scaleWidget.scale.value, equals(1.5));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(scaleWidget.scale.value, equals(1.75));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(scaleWidget.scale.value, equals(2.0));
|
|
expect(state.builds, equals(2));
|
|
});
|
|
|
|
testWidgets('AnimatedRotation onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedRotationWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedRotation transition test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(switchKey: switchKey, state: _TestAnimatedRotationWidgetState()),
|
|
),
|
|
);
|
|
|
|
final RebuildCountingState<StatefulWidget> state = tester
|
|
.widget<TestAnimatedWidget>(find.byType(TestAnimatedWidget))
|
|
.rebuildState!;
|
|
final Finder switchFinder = find.byKey(switchKey);
|
|
final RotationTransition rotationWidget = tester.widget<RotationTransition>(
|
|
find.ancestor(of: find.byType(Placeholder), matching: find.byType(RotationTransition)).first,
|
|
);
|
|
|
|
expect(state.builds, equals(1));
|
|
|
|
await tester.tap(switchFinder);
|
|
expect(state.builds, equals(1));
|
|
await tester.pump();
|
|
expect(rotationWidget.turns.value, equals(0.0));
|
|
expect(state.builds, equals(2));
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(rotationWidget.turns.value, equals(0.75));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(rotationWidget.turns.value, equals(1.125));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(rotationWidget.turns.value, equals(1.5));
|
|
expect(state.builds, equals(2));
|
|
});
|
|
|
|
testWidgets('AnimatedOpacity onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedOpacityWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedOpacity transition test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(switchKey: switchKey, state: _TestAnimatedOpacityWidgetState()),
|
|
),
|
|
);
|
|
|
|
final RebuildCountingState<StatefulWidget> state = tester
|
|
.widget<TestAnimatedWidget>(find.byType(TestAnimatedWidget))
|
|
.rebuildState!;
|
|
final Finder switchFinder = find.byKey(switchKey);
|
|
final FadeTransition opacityWidget = tester.widget<FadeTransition>(
|
|
find.ancestor(of: find.byType(Placeholder), matching: find.byType(FadeTransition)).first,
|
|
);
|
|
|
|
expect(state.builds, equals(1));
|
|
|
|
await tester.tap(switchFinder);
|
|
expect(state.builds, equals(1));
|
|
await tester.pump();
|
|
expect(opacityWidget.opacity.value, equals(0.0));
|
|
expect(state.builds, equals(2));
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(opacityWidget.opacity.value, equals(0.5));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(opacityWidget.opacity.value, equals(0.75));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(opacityWidget.opacity.value, equals(1.0));
|
|
expect(state.builds, equals(2));
|
|
});
|
|
|
|
testWidgets('AnimatedFractionallySizedBox onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedFractionallySizedBoxWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('SliverAnimatedOpacity onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestSliverAnimatedOpacityWidgetState(),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('SliverAnimatedOpacity transition test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
switchKey: switchKey,
|
|
state: _TestSliverAnimatedOpacityWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final RebuildCountingState<StatefulWidget> state = tester
|
|
.widget<TestAnimatedWidget>(find.byType(TestAnimatedWidget))
|
|
.rebuildState!;
|
|
final Finder switchFinder = find.byKey(switchKey);
|
|
final SliverFadeTransition opacityWidget = tester.widget<SliverFadeTransition>(
|
|
find
|
|
.ancestor(of: find.byType(Placeholder), matching: find.byType(SliverFadeTransition))
|
|
.first,
|
|
);
|
|
|
|
expect(state.builds, equals(1));
|
|
|
|
await tester.tap(switchFinder);
|
|
expect(state.builds, equals(1));
|
|
await tester.pump();
|
|
expect(opacityWidget.opacity.value, equals(0.0));
|
|
expect(state.builds, equals(2));
|
|
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(opacityWidget.opacity.value, equals(0.5));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(opacityWidget.opacity.value, equals(0.75));
|
|
expect(state.builds, equals(2));
|
|
await tester.pump(const Duration(milliseconds: 250));
|
|
expect(opacityWidget.opacity.value, equals(1.0));
|
|
expect(state.builds, equals(2));
|
|
});
|
|
|
|
testWidgets('AnimatedDefaultTextStyle onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedDefaultTextStyleWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedPhysicalModelWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('TweenAnimationBuilder onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestTweenAnimationBuilderWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('AnimatedTheme onEnd callback test', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: TestAnimatedWidget(
|
|
callback: mockOnEndFunction.handler,
|
|
switchKey: switchKey,
|
|
state: _TestAnimatedThemeWidgetState(),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Finder widgetFinder = find.byKey(switchKey);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(animationDuration);
|
|
expect(mockOnEndFunction.called, 0);
|
|
await tester.pump(additionalDelay);
|
|
expect(mockOnEndFunction.called, 1);
|
|
|
|
await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
|
|
});
|
|
|
|
testWidgets('Ensure CurvedAnimations are disposed on widget change', (WidgetTester tester) async {
|
|
final key = GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>>();
|
|
final curve = ValueNotifier<Curve>(const Interval(0.0, 0.5));
|
|
addTearDown(curve.dispose);
|
|
await tester.pumpWidget(
|
|
wrap(
|
|
child: ValueListenableBuilder<Curve>(
|
|
valueListenable: curve,
|
|
builder: (_, Curve c, _) => AnimatedOpacity(
|
|
key: key,
|
|
opacity: 1.0,
|
|
duration: const Duration(seconds: 1),
|
|
curve: c,
|
|
child: Container(color: Colors.green),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final ImplicitlyAnimatedWidgetState<AnimatedOpacity>? firstState = key.currentState;
|
|
final Animation<double>? firstAnimation = firstState?.animation;
|
|
if (firstAnimation == null) {
|
|
fail('animation was null!');
|
|
}
|
|
|
|
final firstCurvedAnimation = firstAnimation as CurvedAnimation;
|
|
|
|
expect(firstCurvedAnimation.isDisposed, isFalse);
|
|
|
|
curve.value = const Interval(0.0, 0.6);
|
|
await tester.pumpAndSettle();
|
|
|
|
final ImplicitlyAnimatedWidgetState<AnimatedOpacity>? secondState = key.currentState;
|
|
final Animation<double>? secondAnimation = secondState?.animation;
|
|
if (secondAnimation == null) {
|
|
fail('animation was null!');
|
|
}
|
|
|
|
final secondCurvedAnimation = secondAnimation as CurvedAnimation;
|
|
|
|
expect(firstState, equals(secondState));
|
|
expect(firstAnimation, isNot(equals(secondAnimation)));
|
|
|
|
expect(firstCurvedAnimation.isDisposed, isTrue);
|
|
expect(secondCurvedAnimation.isDisposed, isFalse);
|
|
|
|
await tester.pumpWidget(wrap(child: const Offstage()));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(secondCurvedAnimation.isDisposed, isTrue);
|
|
});
|
|
|
|
group('Verify that default args match non-animated variants', () {
|
|
const Widget child = SizedBox.shrink();
|
|
const color = Color(0x00000000);
|
|
|
|
testWidgets('PhysicalModel default args', (WidgetTester tester) async {
|
|
const animatedPhysicalModel = AnimatedPhysicalModel(
|
|
duration: Duration.zero,
|
|
color: color,
|
|
shadowColor: color,
|
|
child: child,
|
|
);
|
|
const physicalModel = PhysicalModel(color: color, shadowColor: color, child: child);
|
|
expect(identical(animatedPhysicalModel.shape, physicalModel.shape), isTrue);
|
|
expect(identical(animatedPhysicalModel.clipBehavior, physicalModel.clipBehavior), isTrue);
|
|
expect(identical(animatedPhysicalModel.borderRadius, physicalModel.borderRadius), isTrue);
|
|
});
|
|
// TODO(nate-thegrate): add every class!
|
|
});
|
|
}
|
|
|
|
Future<void> tapTest2and3(
|
|
WidgetTester tester,
|
|
Finder widgetFinder,
|
|
MockOnEndFunction mockOnEndFunction,
|
|
) async {
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
await tester.pump(animationDuration + additionalDelay);
|
|
expect(mockOnEndFunction.called, 2);
|
|
|
|
await tester.tap(widgetFinder);
|
|
|
|
await tester.pump();
|
|
await tester.pump(animationDuration + additionalDelay);
|
|
expect(mockOnEndFunction.called, 3);
|
|
}
|
|
|
|
Widget wrap({required Widget child}) {
|
|
return Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Material(child: Center(child: child)),
|
|
);
|
|
}
|
|
|
|
abstract class RebuildCountingState<T extends StatefulWidget> extends State<T> {
|
|
int builds = 0;
|
|
}
|
|
|
|
class TestAnimatedWidget extends StatefulWidget {
|
|
const TestAnimatedWidget({
|
|
super.key,
|
|
this.callback,
|
|
required this.switchKey,
|
|
required this.state,
|
|
});
|
|
final VoidCallback? callback;
|
|
final Key switchKey;
|
|
final State<StatefulWidget> state;
|
|
|
|
RebuildCountingState<StatefulWidget>? get rebuildState =>
|
|
state is RebuildCountingState<StatefulWidget>
|
|
? state as RebuildCountingState<StatefulWidget>
|
|
: null;
|
|
|
|
@override
|
|
State<StatefulWidget> createState() => state; // ignore: no_logic_in_create_state, this test predates the lint
|
|
}
|
|
|
|
abstract class _TestAnimatedWidgetState extends RebuildCountingState<TestAnimatedWidget> {
|
|
bool toggle = false;
|
|
final Widget child = const Placeholder();
|
|
final Duration duration = animationDuration;
|
|
|
|
void onChanged(bool v) {
|
|
setState(() {
|
|
toggle = v;
|
|
});
|
|
}
|
|
|
|
Widget getAnimatedWidget();
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
builds++;
|
|
final Widget animatedWidget = getAnimatedWidget();
|
|
|
|
return Stack(
|
|
children: <Widget>[
|
|
animatedWidget,
|
|
Switch(key: widget.switchKey, value: toggle, onChanged: onChanged),
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedContainerWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedContainer(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
width: toggle ? 10 : 20,
|
|
foregroundDecoration: toggle ? const BoxDecoration() : null,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedPaddingWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedPadding(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
padding: toggle ? const EdgeInsets.all(8.0) : const EdgeInsets.all(16.0),
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedAlignWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedAlign(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
alignment: toggle ? Alignment.topLeft : Alignment.bottomRight,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedPositionedWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedPositioned(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
left: toggle ? 10 : 20,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedPositionedDirectionalWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedPositionedDirectional(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
start: toggle ? 10 : 20,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedSlideWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedSlide(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
offset: toggle ? const Offset(1, 1) : Offset.zero,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedScaleWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedScale(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
scale: toggle ? 2.0 : 1.0,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedRotationWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedRotation(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
turns: toggle ? 1.5 : 0.0,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedOpacityWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedOpacity(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
opacity: toggle ? 1.0 : 0.0,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedFractionallySizedBoxWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedFractionallySizedBox(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
heightFactor: toggle ? 0.25 : 0.75,
|
|
widthFactor: toggle ? 0.25 : 0.75,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestSliverAnimatedOpacityWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return SliverAnimatedOpacity(
|
|
sliver: SliverToBoxAdapter(child: child),
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
opacity: toggle ? 1.0 : 0.0,
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
builds++;
|
|
final Widget animatedWidget = getAnimatedWidget();
|
|
|
|
return Material(
|
|
child: Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: CustomScrollView(
|
|
slivers: <Widget>[
|
|
animatedWidget,
|
|
SliverToBoxAdapter(
|
|
child: Switch(key: widget.switchKey, value: toggle, onChanged: onChanged),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedDefaultTextStyleWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedDefaultTextStyle(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
style: toggle
|
|
? const TextStyle(fontStyle: FontStyle.italic)
|
|
: const TextStyle(fontStyle: FontStyle.normal),
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedPhysicalModelWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedPhysicalModel(
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
color: toggle ? Colors.red : Colors.green,
|
|
shadowColor: Colors.blue,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestTweenAnimationBuilderWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return TweenAnimationBuilder<double>(
|
|
tween: toggle ? Tween<double>(begin: 1, end: 2) : Tween<double>(begin: 2, end: 1),
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
child: child,
|
|
builder: (BuildContext context, double? size, Widget? child) {
|
|
return SizedBox(width: size, height: size, child: child);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class _TestAnimatedThemeWidgetState extends _TestAnimatedWidgetState {
|
|
@override
|
|
Widget getAnimatedWidget() {
|
|
return AnimatedTheme(
|
|
data: toggle ? ThemeData.dark() : ThemeData(),
|
|
duration: duration,
|
|
onEnd: widget.callback,
|
|
child: child,
|
|
);
|
|
}
|
|
}
|