curves_test.dart 9.53 KB
Newer Older
1 2 3 4
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
import 'dart:math' as math;

7 8 9 10 11 12 13
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/widgets.dart';

void main() {
  test('toString control test', () {
    expect(Curves.linear, hasOneLineDescription);
14 15
    expect(const SawTooth(3), hasOneLineDescription);
    expect(const Interval(0.25, 0.75), hasOneLineDescription);
16
    expect(const Interval(0.25, 0.75, curve: Curves.ease), hasOneLineDescription);
17 18 19
  });

  test('Curve flipped control test', () {
20
    const Curve ease = Curves.ease;
21
    final Curve flippedEase = ease.flipped;
22 23 24 25 26 27
    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);
  });

28
  test('Threshold has a threshold', () {
29
    const Curve step = Threshold(0.25);
30 31 32 33 34 35
    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);
  });
36

37 38 39 40 41 42 43 44 45 46 47
  void assertMaximumSlope(Curve curve, double maximumSlope) {
    const double delta = 0.005;
    for (double 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.toString()} discontinuous at $x');
    }
  }

  test('Curve is continuous', () {
    assertMaximumSlope(Curves.linear, 20.0);
    assertMaximumSlope(Curves.decelerate, 20.0);
48
    assertMaximumSlope(Curves.fastOutSlowIn, 20.0);
49
    assertMaximumSlope(Curves.slowMiddle, 20.0);
50 51 52 53 54 55
    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);
56

57
    assertMaximumSlope(Curves.easeIn, 20.0);
58 59 60 61 62 63 64 65
    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);

66
    assertMaximumSlope(Curves.easeOut, 20.0);
67 68 69 70 71 72 73 74 75 76 77
    assertMaximumSlope(Curves.easeOutSine, 20.0);
    assertMaximumSlope(Curves.easeOutQuad, 20.0);
    assertMaximumSlope(Curves.easeOutCubic, 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

78
    assertMaximumSlope(Curves.easeInOut, 20.0);
79 80 81 82 83 84
    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);
85 86
  });

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
  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) {
108
    final List<double> values = <double>[];
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

    values.add(curve.transform(0.0));
    values.add(curve.transform(0.1));
    values.add(curve.transform(0.2));
    values.add(curve.transform(0.3));
    values.add(curve.transform(0.4));
    values.add(curve.transform(0.5));
    values.add(curve.transform(0.6));
    values.add(curve.transform(0.7));
    values.add(curve.transform(0.8));
    values.add(curve.transform(0.9));
    values.add(curve.transform(1.0));

    return <double>[
      values.reduce(math.min),
      values.reduce(math.max),
    ];
  }

  test('Ellastic 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));
  });
144

145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
  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));
  });

162 163 164
  test('Decelerate does so', () {
    expect(Curves.decelerate, hasOneLineDescription);

165
    final List<double> bounds = estimateBounds(Curves.decelerate);
166 167 168
    expect(bounds[0], greaterThanOrEqualTo(0.0));
    expect(bounds[1], lessThanOrEqualTo(1.0));

169 170
    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);
171 172
    expect(d2, lessThan(d1));
  });
173 174

  test('Invalid transform parameter should assert', () {
175 176
    expect(() => const SawTooth(2).transform(-0.0001), throwsAssertionError);
    expect(() => const SawTooth(2).transform(1.0001), throwsAssertionError);
177

178 179
    expect(() => const Interval(0.0, 1.0).transform(-0.0001), throwsAssertionError);
    expect(() => const Interval(0.0, 1.0).transform(1.0001), throwsAssertionError);
180

181 182
    expect(() => const Threshold(0.5).transform(-0.0001), throwsAssertionError);
    expect(() => const Threshold(0.5).transform(1.0001), throwsAssertionError);
183

184 185
    expect(() => const ElasticInCurve().transform(-0.0001), throwsAssertionError);
    expect(() => const ElasticInCurve().transform(1.0001), throwsAssertionError);
186

187 188
    expect(() => const ElasticOutCurve().transform(-0.0001), throwsAssertionError);
    expect(() => const ElasticOutCurve().transform(1.0001), throwsAssertionError);
189

190 191
    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);
192

193 194
    expect(() => Curves.decelerate.transform(-0.0001), throwsAssertionError);
    expect(() => Curves.decelerate.transform(1.0001), throwsAssertionError);
195

196 197
    expect(() => Curves.bounceIn.transform(-0.0001), throwsAssertionError);
    expect(() => Curves.bounceIn.transform(1.0001), throwsAssertionError);
198

199 200
    expect(() => Curves.bounceOut.transform(-0.0001), throwsAssertionError);
    expect(() => Curves.bounceOut.transform(1.0001), throwsAssertionError);
201

202 203
    expect(() => Curves.bounceInOut.transform(-0.0001), throwsAssertionError);
    expect(() => Curves.bounceInOut.transform(1.0001), throwsAssertionError);
204 205
  });

206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246
  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 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(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);
  });

247
}