610 lines
22 KiB
Dart
610 lines
22 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 'dart:math' as math;
|
|
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
test('toString control test', () {
|
|
expect(Curves.linear, hasOneLineDescription);
|
|
expect(const SawTooth(3), hasOneLineDescription);
|
|
expect(const Interval(0.25, 0.75), hasOneLineDescription);
|
|
expect(const Interval(0.25, 0.75, curve: Curves.ease), hasOneLineDescription);
|
|
expect(const Split(0.25, beginCurve: Curves.ease), hasOneLineDescription);
|
|
});
|
|
|
|
test('Curve flipped control test', () {
|
|
const Curve ease = Curves.ease;
|
|
final Curve flippedEase = ease.flipped;
|
|
expect(flippedEase.transform(0.0), lessThan(0.001));
|
|
expect(flippedEase.transform(0.5), lessThan(ease.transform(0.5)));
|
|
expect(flippedEase.transform(1.0), greaterThan(0.999));
|
|
expect(flippedEase, hasOneLineDescription);
|
|
});
|
|
|
|
test('Threshold has a threshold', () {
|
|
const Curve step = Threshold(0.25);
|
|
expect(step.transform(0.0), 0.0);
|
|
expect(step.transform(0.24), 0.0);
|
|
expect(step.transform(0.25), 1.0);
|
|
expect(step.transform(0.26), 1.0);
|
|
expect(step.transform(1.0), 1.0);
|
|
});
|
|
|
|
void assertMaximumSlope(Curve curve, double maximumSlope) {
|
|
const delta = 0.005;
|
|
for (var x = 0.0; x < 1.0 - delta; x += delta) {
|
|
final double deltaY = curve.transform(x) - curve.transform(x + delta);
|
|
assert(deltaY.abs() < delta * maximumSlope, '$curve discontinuous at $x');
|
|
}
|
|
}
|
|
|
|
test('Curve is continuous', () {
|
|
assertMaximumSlope(Curves.linear, 20.0);
|
|
assertMaximumSlope(Curves.decelerate, 20.0);
|
|
assertMaximumSlope(Curves.fastOutSlowIn, 20.0);
|
|
assertMaximumSlope(Curves.slowMiddle, 20.0);
|
|
assertMaximumSlope(Curves.bounceIn, 20.0);
|
|
assertMaximumSlope(Curves.bounceOut, 20.0);
|
|
assertMaximumSlope(Curves.bounceInOut, 20.0);
|
|
assertMaximumSlope(Curves.elasticOut, 20.0);
|
|
assertMaximumSlope(Curves.elasticInOut, 20.0);
|
|
assertMaximumSlope(Curves.ease, 20.0);
|
|
|
|
assertMaximumSlope(Curves.easeIn, 20.0);
|
|
assertMaximumSlope(Curves.easeInSine, 20.0);
|
|
assertMaximumSlope(Curves.easeInQuad, 20.0);
|
|
assertMaximumSlope(Curves.easeInCubic, 20.0);
|
|
assertMaximumSlope(Curves.easeInQuart, 20.0);
|
|
assertMaximumSlope(Curves.easeInQuint, 20.0);
|
|
assertMaximumSlope(Curves.easeInExpo, 20.0);
|
|
assertMaximumSlope(Curves.easeInCirc, 20.0);
|
|
|
|
assertMaximumSlope(Curves.easeOut, 20.0);
|
|
assertMaximumSlope(Curves.easeOutSine, 20.0);
|
|
assertMaximumSlope(Curves.easeOutQuad, 20.0);
|
|
assertMaximumSlope(Curves.easeOutCubic, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutCubicEmphasized, 20.0);
|
|
assertMaximumSlope(Curves.easeOutQuart, 20.0);
|
|
assertMaximumSlope(Curves.easeOutQuint, 20.0);
|
|
assertMaximumSlope(Curves.easeOutExpo, 20.0);
|
|
assertMaximumSlope(Curves.easeOutCirc, 20.0);
|
|
|
|
// Curves.easeInOutExpo is discontinuous at its midpoint, so not included
|
|
// here
|
|
|
|
assertMaximumSlope(Curves.easeInOut, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutSine, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutQuad, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutCubic, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutQuart, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutQuint, 20.0);
|
|
assertMaximumSlope(Curves.easeInOutCirc, 20.0);
|
|
});
|
|
|
|
void expectStaysInBounds(Curve curve) {
|
|
expect(curve.transform(0.0), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.1), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.2), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.3), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.4), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.5), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.6), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.7), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.8), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(0.9), inInclusiveRange(0.0, 1.0));
|
|
expect(curve.transform(1.0), inInclusiveRange(0.0, 1.0));
|
|
}
|
|
|
|
test('Bounce stays in bounds', () {
|
|
expectStaysInBounds(Curves.bounceIn);
|
|
expectStaysInBounds(Curves.bounceOut);
|
|
expectStaysInBounds(Curves.bounceInOut);
|
|
});
|
|
|
|
List<double> estimateBounds(Curve curve) {
|
|
final values = <double>[
|
|
curve.transform(0.0),
|
|
curve.transform(0.1),
|
|
curve.transform(0.2),
|
|
curve.transform(0.3),
|
|
curve.transform(0.4),
|
|
curve.transform(0.5),
|
|
curve.transform(0.6),
|
|
curve.transform(0.7),
|
|
curve.transform(0.8),
|
|
curve.transform(0.9),
|
|
curve.transform(1.0),
|
|
];
|
|
|
|
return <double>[values.reduce(math.min), values.reduce(math.max)];
|
|
}
|
|
|
|
test('Elastic overshoots its bounds', () {
|
|
expect(Curves.elasticIn, hasOneLineDescription);
|
|
expect(Curves.elasticOut, hasOneLineDescription);
|
|
expect(Curves.elasticInOut, hasOneLineDescription);
|
|
|
|
List<double> bounds;
|
|
bounds = estimateBounds(Curves.elasticIn);
|
|
expect(bounds[0], lessThan(0.0));
|
|
expect(bounds[1], lessThanOrEqualTo(1.0));
|
|
bounds = estimateBounds(Curves.elasticOut);
|
|
expect(bounds[0], greaterThanOrEqualTo(0.0));
|
|
expect(bounds[1], greaterThan(1.0));
|
|
bounds = estimateBounds(Curves.elasticInOut);
|
|
expect(bounds[0], lessThan(0.0));
|
|
expect(bounds[1], greaterThan(1.0));
|
|
});
|
|
|
|
test('Back overshoots its bounds', () {
|
|
expect(Curves.easeInBack, hasOneLineDescription);
|
|
expect(Curves.easeOutBack, hasOneLineDescription);
|
|
expect(Curves.easeInOutBack, hasOneLineDescription);
|
|
|
|
List<double> bounds;
|
|
bounds = estimateBounds(Curves.easeInBack);
|
|
expect(bounds[0], lessThan(0.0));
|
|
expect(bounds[1], lessThanOrEqualTo(1.0));
|
|
bounds = estimateBounds(Curves.easeOutBack);
|
|
expect(bounds[0], greaterThanOrEqualTo(0.0));
|
|
expect(bounds[1], greaterThan(1.0));
|
|
bounds = estimateBounds(Curves.easeInOutBack);
|
|
expect(bounds[0], lessThan(0.0));
|
|
expect(bounds[1], greaterThan(1.0));
|
|
});
|
|
|
|
test('Decelerate does so', () {
|
|
expect(Curves.decelerate, hasOneLineDescription);
|
|
|
|
final List<double> bounds = estimateBounds(Curves.decelerate);
|
|
expect(bounds[0], greaterThanOrEqualTo(0.0));
|
|
expect(bounds[1], lessThanOrEqualTo(1.0));
|
|
|
|
final double d1 = Curves.decelerate.transform(0.2) - Curves.decelerate.transform(0.0);
|
|
final double d2 = Curves.decelerate.transform(1.0) - Curves.decelerate.transform(0.8);
|
|
expect(d2, lessThan(d1));
|
|
});
|
|
|
|
test('ThreePointCubic interpolates midpoint', () {
|
|
const test = ThreePointCubic(
|
|
Offset(0.05, 0),
|
|
Offset(0.133333, 0.06),
|
|
Offset(0.166666, 0.4),
|
|
Offset(0.208333, 0.82),
|
|
Offset(0.25, 1),
|
|
);
|
|
expect(test.transform(0.166666), equals(0.4));
|
|
});
|
|
|
|
test('Invalid transform parameter should assert', () {
|
|
expect(() => const SawTooth(2).transform(-0.0001), throwsAssertionError);
|
|
expect(() => const SawTooth(2).transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const Interval(0.0, 1.0).transform(-0.0001), throwsAssertionError);
|
|
expect(() => const Interval(0.0, 1.0).transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const Split(0.0).transform(-0.0001), throwsAssertionError);
|
|
expect(() => const Split(0.0).transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const Threshold(0.5).transform(-0.0001), throwsAssertionError);
|
|
expect(() => const Threshold(0.5).transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const ElasticInCurve().transform(-0.0001), throwsAssertionError);
|
|
expect(() => const ElasticInCurve().transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const ElasticOutCurve().transform(-0.0001), throwsAssertionError);
|
|
expect(() => const ElasticOutCurve().transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => const Cubic(0.42, 0.0, 0.58, 1.0).transform(-0.0001), throwsAssertionError);
|
|
expect(() => const Cubic(0.42, 0.0, 0.58, 1.0).transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => Curves.easeInOutCubicEmphasized.transform(-0.0001), throwsAssertionError);
|
|
expect(() => Curves.easeInOutCubicEmphasized.transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => Curves.decelerate.transform(-0.0001), throwsAssertionError);
|
|
expect(() => Curves.decelerate.transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => Curves.bounceIn.transform(-0.0001), throwsAssertionError);
|
|
expect(() => Curves.bounceIn.transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => Curves.bounceOut.transform(-0.0001), throwsAssertionError);
|
|
expect(() => Curves.bounceOut.transform(1.0001), throwsAssertionError);
|
|
|
|
expect(() => Curves.bounceInOut.transform(-0.0001), throwsAssertionError);
|
|
expect(() => Curves.bounceInOut.transform(1.0001), throwsAssertionError);
|
|
});
|
|
|
|
test('Curve transform method should return 0.0 for t=0.0 and 1.0 for t=1.0', () {
|
|
expect(const SawTooth(2).transform(0), 0);
|
|
expect(const SawTooth(2).transform(1), 1);
|
|
|
|
expect(const Interval(0, 1).transform(0), 0);
|
|
expect(const Interval(0, 1).transform(1), 1);
|
|
|
|
expect(const Split(0.5).transform(0), 0);
|
|
expect(const Split(0.5).transform(1), 1);
|
|
|
|
expect(const Threshold(0.5).transform(0), 0);
|
|
expect(const Threshold(0.5).transform(1), 1);
|
|
|
|
expect(const ElasticInCurve().transform(0), 0);
|
|
expect(const ElasticInCurve().transform(1), 1);
|
|
|
|
expect(const ElasticOutCurve().transform(0), 0);
|
|
expect(const ElasticOutCurve().transform(1), 1);
|
|
|
|
expect(const ElasticInOutCurve().transform(0), 0);
|
|
expect(const ElasticInOutCurve().transform(1), 1);
|
|
|
|
expect(Curves.linear.transform(0), 0);
|
|
expect(Curves.linear.transform(1), 1);
|
|
|
|
expect(Curves.easeInOutExpo.transform(0), 0);
|
|
expect(Curves.easeInOutExpo.transform(1), 1);
|
|
|
|
expect(Curves.easeInOutCubicEmphasized.transform(0), 0);
|
|
expect(Curves.easeInOutCubicEmphasized.transform(1), 1);
|
|
|
|
expect(const FlippedCurve(Curves.easeInOutExpo).transform(0), 0);
|
|
expect(const FlippedCurve(Curves.easeInOutExpo).transform(1), 1);
|
|
|
|
expect(Curves.decelerate.transform(0), 0);
|
|
expect(Curves.decelerate.transform(1), 1);
|
|
|
|
expect(Curves.bounceIn.transform(0), 0);
|
|
expect(Curves.bounceIn.transform(1), 1);
|
|
|
|
expect(Curves.bounceOut.transform(0), 0);
|
|
expect(Curves.bounceOut.transform(1), 1);
|
|
|
|
expect(Curves.bounceInOut.transform(0), 0);
|
|
expect(Curves.bounceInOut.transform(1), 1);
|
|
});
|
|
|
|
test('Split interpolates values properly', () {
|
|
const curve = Split(0.3);
|
|
|
|
const tolerance = 1e-6;
|
|
expect(curve.transform(0.0), equals(0.0));
|
|
expect(curve.transform(0.1), equals(0.1));
|
|
expect(curve.transform(0.25), equals(0.25));
|
|
expect(curve.transform(0.3), equals(0.3));
|
|
expect(curve.transform(0.5), moreOrLessEquals(0.760461, epsilon: tolerance));
|
|
expect(curve.transform(0.75), moreOrLessEquals(0.962055, epsilon: tolerance));
|
|
expect(curve.transform(1.0), equals(1.0));
|
|
});
|
|
|
|
test('CatmullRomSpline interpolates values properly', () {
|
|
final curve = CatmullRomSpline(
|
|
const <Offset>[
|
|
Offset.zero,
|
|
Offset(0.01, 0.25),
|
|
Offset(0.2, 0.25),
|
|
Offset(0.33, 0.25),
|
|
Offset(0.5, 1.0),
|
|
Offset(0.66, 0.75),
|
|
Offset(1.0, 1.0),
|
|
],
|
|
startHandle: const Offset(0.0, -0.3),
|
|
endHandle: const Offset(1.3, 1.3),
|
|
);
|
|
const tolerance = 1e-6;
|
|
expect(curve.transform(0.0).dx, moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.0).dy, moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.25).dx, moreOrLessEquals(0.0966945, epsilon: tolerance));
|
|
expect(curve.transform(0.25).dy, moreOrLessEquals(0.2626806, epsilon: tolerance));
|
|
expect(curve.transform(0.5).dx, moreOrLessEquals(0.33, epsilon: tolerance));
|
|
expect(curve.transform(0.5).dy, moreOrLessEquals(0.25, epsilon: tolerance));
|
|
expect(curve.transform(0.75).dx, moreOrLessEquals(0.570260, epsilon: tolerance));
|
|
expect(curve.transform(0.75).dy, moreOrLessEquals(0.883085, epsilon: tolerance));
|
|
expect(curve.transform(1.0).dx, moreOrLessEquals(1.0, epsilon: tolerance));
|
|
expect(curve.transform(1.0).dy, moreOrLessEquals(1.0, epsilon: tolerance));
|
|
});
|
|
|
|
test('CatmullRomSpline enforces contract', () {
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[Offset.zero, Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
], tension: -1.0);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
], tension: 2.0);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[
|
|
Offset(double.infinity, 0.0),
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]).generateSamples();
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(const <Offset>[
|
|
Offset(0.0, double.infinity),
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]).generateSamples();
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(startHandle: const Offset(0.0, double.infinity), const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]).generateSamples();
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline(endHandle: const Offset(0.0, double.infinity), const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]).generateSamples();
|
|
}, throwsAssertionError);
|
|
});
|
|
|
|
test('CatmullRomSpline interpolates values properly when precomputed', () {
|
|
final curve = CatmullRomSpline.precompute(
|
|
const <Offset>[
|
|
Offset.zero,
|
|
Offset(0.01, 0.25),
|
|
Offset(0.2, 0.25),
|
|
Offset(0.33, 0.25),
|
|
Offset(0.5, 1.0),
|
|
Offset(0.66, 0.75),
|
|
Offset(1.0, 1.0),
|
|
],
|
|
startHandle: const Offset(0.0, -0.3),
|
|
endHandle: const Offset(1.3, 1.3),
|
|
);
|
|
const tolerance = 1e-6;
|
|
expect(curve.transform(0.0).dx, moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.0).dy, moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.25).dx, moreOrLessEquals(0.0966945, epsilon: tolerance));
|
|
expect(curve.transform(0.25).dy, moreOrLessEquals(0.2626806, epsilon: tolerance));
|
|
expect(curve.transform(0.5).dx, moreOrLessEquals(0.33, epsilon: tolerance));
|
|
expect(curve.transform(0.5).dy, moreOrLessEquals(0.25, epsilon: tolerance));
|
|
expect(curve.transform(0.75).dx, moreOrLessEquals(0.570260, epsilon: tolerance));
|
|
expect(curve.transform(0.75).dy, moreOrLessEquals(0.883085, epsilon: tolerance));
|
|
expect(curve.transform(1.0).dx, moreOrLessEquals(1.0, epsilon: tolerance));
|
|
expect(curve.transform(1.0).dy, moreOrLessEquals(1.0, epsilon: tolerance));
|
|
});
|
|
|
|
test('CatmullRomSpline enforces contract when precomputed', () {
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[Offset.zero, Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
], tension: -1.0);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
], tension: 2.0);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[
|
|
Offset(double.infinity, 0.0),
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(const <Offset>[
|
|
Offset(0.0, double.infinity),
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(startHandle: const Offset(0.0, double.infinity), const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomSpline.precompute(endHandle: const Offset(0.0, double.infinity), const <Offset>[
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
Offset.zero,
|
|
]);
|
|
}, throwsAssertionError);
|
|
});
|
|
|
|
test('CatmullRomCurve interpolates given points correctly', () {
|
|
final curve = CatmullRomCurve(const <Offset>[
|
|
Offset(0.2, 0.25),
|
|
Offset(0.33, 0.25),
|
|
Offset(0.5, 1.0),
|
|
Offset(0.8, 0.75),
|
|
]);
|
|
|
|
// These values are approximations.
|
|
const tolerance = 1e-6;
|
|
expect(curve.transform(0.0), moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.01), moreOrLessEquals(0.012874734350170863, epsilon: tolerance));
|
|
expect(curve.transform(0.2), moreOrLessEquals(0.24989646045277542, epsilon: tolerance));
|
|
expect(curve.transform(0.33), moreOrLessEquals(0.250037698527661, epsilon: tolerance));
|
|
expect(curve.transform(0.5), moreOrLessEquals(0.9999057323235939, epsilon: tolerance));
|
|
expect(curve.transform(0.6), moreOrLessEquals(0.9357294964536621, epsilon: tolerance));
|
|
expect(curve.transform(0.8), moreOrLessEquals(0.7500423402378034, epsilon: tolerance));
|
|
expect(curve.transform(1.0), moreOrLessEquals(1.0, epsilon: tolerance));
|
|
});
|
|
|
|
test('CatmullRomCurve interpolates given points correctly when precomputed', () {
|
|
final curve = CatmullRomCurve.precompute(const <Offset>[
|
|
Offset(0.2, 0.25),
|
|
Offset(0.33, 0.25),
|
|
Offset(0.5, 1.0),
|
|
Offset(0.8, 0.75),
|
|
]);
|
|
|
|
// These values are approximations.
|
|
const tolerance = 1e-6;
|
|
expect(curve.transform(0.0), moreOrLessEquals(0.0, epsilon: tolerance));
|
|
expect(curve.transform(0.01), moreOrLessEquals(0.012874734350170863, epsilon: tolerance));
|
|
expect(curve.transform(0.2), moreOrLessEquals(0.24989646045277542, epsilon: tolerance));
|
|
expect(curve.transform(0.33), moreOrLessEquals(0.250037698527661, epsilon: tolerance));
|
|
expect(curve.transform(0.5), moreOrLessEquals(0.9999057323235939, epsilon: tolerance));
|
|
expect(curve.transform(0.6), moreOrLessEquals(0.9357294964536621, epsilon: tolerance));
|
|
expect(curve.transform(0.8), moreOrLessEquals(0.7500423402378034, epsilon: tolerance));
|
|
expect(curve.transform(1.0), moreOrLessEquals(1.0, epsilon: tolerance));
|
|
});
|
|
|
|
test('CatmullRomCurve enforces contract', () {
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
|
|
// Monotonically increasing in X.
|
|
expect(
|
|
CatmullRomCurve.validateControlPoints(const <Offset>[Offset(0.2, 0.25), Offset(0.01, 0.25)]),
|
|
isFalse,
|
|
);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset(0.2, 0.25), Offset(0.01, 0.25)]);
|
|
}, throwsAssertionError);
|
|
|
|
// X within range (0.0, 1.0).
|
|
expect(
|
|
CatmullRomCurve.validateControlPoints(const <Offset>[Offset(0.2, 0.25), Offset(1.01, 0.25)]),
|
|
isFalse,
|
|
);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset(0.2, 0.25), Offset(1.01, 0.25)]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y at x=0.0.
|
|
expect(
|
|
CatmullRomCurve.validateControlPoints(const <Offset>[
|
|
Offset(0.05, 0.50),
|
|
Offset(0.50, 0.50),
|
|
Offset(0.75, 0.75),
|
|
]),
|
|
isFalse,
|
|
);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset(0.05, 0.50), Offset(0.50, 0.50), Offset(0.75, 0.75)]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y at x=1.0.
|
|
expect(
|
|
CatmullRomCurve.validateControlPoints(const <Offset>[
|
|
Offset(0.25, 0.25),
|
|
Offset(0.50, 0.50),
|
|
Offset(0.95, 0.51),
|
|
]),
|
|
isFalse,
|
|
);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset(0.25, 0.25), Offset(0.50, 0.50), Offset(0.95, 0.51)]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y in between x = 0.0 and x = 1.0.
|
|
expect(
|
|
CatmullRomCurve.validateControlPoints(const <Offset>[Offset(0.5, 0.05), Offset(0.5, 0.95)]),
|
|
isFalse,
|
|
);
|
|
expect(() {
|
|
CatmullRomCurve(const <Offset>[Offset(0.5, 0.05), Offset(0.5, 0.95)]);
|
|
}, throwsAssertionError);
|
|
});
|
|
|
|
test('CatmullRomCurve enforces contract when precomputed', () {
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[Offset.zero]);
|
|
}, throwsAssertionError);
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[Offset.zero, Offset.zero]);
|
|
}, throwsAssertionError);
|
|
|
|
// Monotonically increasing in X.
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[Offset(0.2, 0.25), Offset(0.01, 0.25)]);
|
|
}, throwsAssertionError);
|
|
|
|
// X within range (0.0, 1.0).
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[Offset(0.2, 0.25), Offset(1.01, 0.25)]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y at x=0.0.
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[
|
|
Offset(0.05, 0.50),
|
|
Offset(0.50, 0.50),
|
|
Offset(0.75, 0.75),
|
|
]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y at x=1.0.
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[
|
|
Offset(0.25, 0.25),
|
|
Offset(0.50, 0.50),
|
|
Offset(0.95, 0.51),
|
|
]);
|
|
}, throwsAssertionError);
|
|
|
|
// Not multi-valued in Y in between x = 0.0 and x = 1.0.
|
|
expect(() {
|
|
CatmullRomCurve.precompute(const <Offset>[Offset(0.5, 0.05), Offset(0.5, 0.95)]);
|
|
}, throwsAssertionError);
|
|
});
|
|
}
|