| // 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/widgets.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| const String kApiDocsLink = 'See "Types with special considerations" at https://api.flutter.dev/flutter/animation/Tween-class.html for more information.'; |
| |
| void main() { |
| test('throws flutter error when tweening types that do not fully satisfy tween requirements - Object', () { |
| final Tween<Object> objectTween = Tween<Object>( |
| begin: Object(), |
| end: Object(), |
| ); |
| |
| expect( |
| () => objectTween.transform(0.1), |
| throwsA(isA<FlutterError>().having( |
| (FlutterError error) => error.diagnostics.map((DiagnosticsNode node) => node.toString()), |
| 'diagnostics', |
| <String>[ |
| 'Cannot lerp between "Instance of \'Object\'" and "Instance of \'Object\'".', |
| 'The type Object might not fully implement `+`, `-`, and/or `*`. $kApiDocsLink', |
| 'There may be a dedicated "ObjectTween" for this type, or you may need to create one.', |
| ], |
| )), |
| ); |
| }); |
| |
| test('throws flutter error when tweening types that do not fully satisfy tween requirements - Color', () { |
| final Tween<Color> colorTween = Tween<Color>( |
| begin: const Color(0xFF000000), |
| end: const Color(0xFFFFFFFF), |
| ); |
| |
| expect( |
| () => colorTween.transform(0.1), |
| throwsA(isA<FlutterError>().having( |
| (FlutterError error) => error.diagnostics.map((DiagnosticsNode node) => node.toString()), |
| 'diagnostics', |
| <String>[ |
| 'Cannot lerp between "Color(0xff000000)" and "Color(0xffffffff)".', |
| 'The type Color might not fully implement `+`, `-`, and/or `*`. $kApiDocsLink', |
| 'To lerp colors, consider ColorTween instead.', |
| ], |
| )), |
| ); |
| }); |
| |
| test('throws flutter error when tweening types that do not fully satisfy tween requirements - Rect', () { |
| final Tween<Rect> rectTween = Tween<Rect>( |
| begin: const Rect.fromLTWH(0, 0, 10, 10), |
| end: const Rect.fromLTWH(2, 2, 2, 2), |
| ); |
| |
| expect( |
| () => rectTween.transform(0.1), |
| throwsA(isA<FlutterError>().having( |
| (FlutterError error) => error.diagnostics.map((DiagnosticsNode node) => node.toString()), |
| 'diagnostics', |
| <String>[ |
| 'Cannot lerp between "Rect.fromLTRB(0.0, 0.0, 10.0, 10.0)" and "Rect.fromLTRB(2.0, 2.0, 4.0, 4.0)".', |
| 'The type Rect might not fully implement `+`, `-`, and/or `*`. $kApiDocsLink', |
| 'To lerp rects, consider RectTween instead.', |
| ], |
| )), |
| ); |
| }); |
| |
| test('throws flutter error when tweening types that do not fully satisfy tween requirements - int', () { |
| final Tween<int> colorTween = Tween<int>( |
| begin: 0, |
| end: 1, |
| ); |
| |
| expect( |
| () => colorTween.transform(0.1), |
| throwsA(isA<FlutterError>().having( |
| (FlutterError error) => error.diagnostics.map((DiagnosticsNode node) => node.toString()), |
| 'diagnostics', |
| <String>[ |
| 'Cannot lerp between "0" and "1".', |
| 'The type int returned a double after multiplication with a double value. $kApiDocsLink', |
| 'To lerp int values, consider IntTween or StepTween instead.', |
| ], |
| )), |
| ); |
| }); |
| |
| test('Can chain tweens', () { |
| final Tween<double> tween = Tween<double>(begin: 0.30, end: 0.50); |
| expect(tween, hasOneLineDescription); |
| final Animatable<double> chain = tween.chain(Tween<double>(begin: 0.50, end: 1.0)); |
| final AnimationController controller = AnimationController( |
| vsync: const TestVSync(), |
| ); |
| expect(chain.evaluate(controller), 0.40); |
| expect(chain, hasOneLineDescription); |
| }); |
| |
| test('Can animate tweens', () { |
| final Tween<double> tween = Tween<double>(begin: 0.30, end: 0.50); |
| final AnimationController controller = AnimationController( |
| vsync: const TestVSync(), |
| ); |
| final Animation<double> animation = tween.animate(controller); |
| controller.value = 0.50; |
| expect(animation.value, 0.40); |
| expect(animation, hasOneLineDescription); |
| expect(animation.toStringDetails(), hasOneLineDescription); |
| }); |
| |
| test('Can drive tweens', () { |
| final Tween<double> tween = Tween<double>(begin: 0.30, end: 0.50); |
| final AnimationController controller = AnimationController( |
| vsync: const TestVSync(), |
| ); |
| final Animation<double> animation = controller.drive(tween); |
| controller.value = 0.50; |
| expect(animation.value, 0.40); |
| expect(animation, hasOneLineDescription); |
| expect(animation.toStringDetails(), hasOneLineDescription); |
| }); |
| |
| test('BorderTween nullable test', () { |
| BorderTween tween = BorderTween(); |
| expect(tween.lerp(0.0), null); |
| expect(tween.lerp(1.0), null); |
| |
| tween = BorderTween(end: const Border(top: BorderSide())); |
| expect(tween.lerp(0.0), const Border()); |
| expect(tween.lerp(0.5), const Border(top: BorderSide(width: 0.5))); |
| expect(tween.lerp(1.0), const Border(top: BorderSide())); |
| }); |
| |
| test('SizeTween', () { |
| final SizeTween tween = SizeTween(begin: Size.zero, end: const Size(20.0, 30.0)); |
| expect(tween.lerp(0.5), equals(const Size(10.0, 15.0))); |
| expect(tween, hasOneLineDescription); |
| }); |
| |
| test('IntTween', () { |
| final IntTween tween = IntTween(begin: 5, end: 9); |
| expect(tween.lerp(0.5), 7); |
| expect(tween.lerp(0.7), 8); |
| }); |
| |
| test('RectTween', () { |
| const Rect a = Rect.fromLTWH(5.0, 3.0, 7.0, 11.0); |
| const Rect b = Rect.fromLTWH(8.0, 12.0, 14.0, 18.0); |
| final RectTween tween = RectTween(begin: a, end: b); |
| expect(tween.lerp(0.5), equals(Rect.lerp(a, b, 0.5))); |
| expect(tween, hasOneLineDescription); |
| }); |
| |
| test('Matrix4Tween', () { |
| final Matrix4 a = Matrix4.identity(); |
| final Matrix4 b = a.clone()..translate(6.0, -8.0)..scale(0.5, 1.0, 5.0); |
| final Matrix4Tween tween = Matrix4Tween(begin: a, end: b); |
| expect(tween.lerp(0.0), equals(a)); |
| expect(tween.lerp(1.0), equals(b)); |
| expect( |
| tween.lerp(0.5), |
| equals(a.clone()..translate(3.0, -4.0)..scale(0.75, 1.0, 3.0)), |
| ); |
| final Matrix4 c = a.clone()..rotateZ(1.0); |
| final Matrix4Tween rotationTween = Matrix4Tween(begin: a, end: c); |
| expect(rotationTween.lerp(0.0), equals(a)); |
| expect(rotationTween.lerp(1.0), equals(c)); |
| expect( |
| rotationTween.lerp(0.5).absoluteError(a.clone()..rotateZ(0.5)), |
| moreOrLessEquals(0.0), |
| ); |
| }); |
| |
| test('ConstantTween', () { |
| final ConstantTween<double> tween = ConstantTween<double>(100.0); |
| expect(tween.begin, 100.0); |
| expect(tween.end, 100.0); |
| expect(tween.lerp(0.0), 100.0); |
| expect(tween.lerp(0.5), 100.0); |
| expect(tween.lerp(1.0), 100.0); |
| }); |
| |
| test('ReverseTween', () { |
| final ReverseTween<int> tween = ReverseTween<int>(IntTween(begin: 5, end: 9)); |
| expect(tween.lerp(0.5), 7); |
| expect(tween.lerp(0.7), 6); |
| }); |
| |
| test('ColorTween', () { |
| final ColorTween tween = ColorTween( |
| begin: const Color(0xff000000), |
| end: const Color(0xffffffff), |
| ); |
| expect(tween.lerp(0.0), const Color(0xff000000)); |
| expect(tween.lerp(0.5), const Color(0xff7f7f7f)); |
| expect(tween.lerp(0.7), const Color(0xffb2b2b2)); |
| expect(tween.lerp(1.0), const Color(0xffffffff)); |
| }); |
| |
| test('StepTween', () { |
| final StepTween tween = StepTween(begin: 5, end: 9); |
| expect(tween.lerp(0.5), 7); |
| expect(tween.lerp(0.7), 7); |
| }); |
| |
| test('CurveTween', () { |
| final CurveTween tween = CurveTween(curve: Curves.easeIn); |
| expect(tween.transform(0.0), 0.0); |
| expect(tween.transform(0.5), 0.31640625); |
| expect(tween.transform(1.0), 1.0); |
| }); |
| |
| test('BorderRadiusTween nullable test', () { |
| final BorderRadiusTween tween = BorderRadiusTween(); |
| expect(tween.transform(0.0), null); |
| expect(tween.transform(1.0), null); |
| expect(tween.lerp(0.0), null); |
| }); |
| } |