shape_decoration_test.dart 5.45 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5 6
// @dart = 2.8

7 8
import 'dart:async';
import 'dart:typed_data';
9
import 'dart:ui' as ui;
10

11 12
import 'package:flutter/foundation.dart';
import 'package:flutter/painting.dart';
13 14
import 'package:flutter_test/flutter_test.dart';

15
import '../rendering/mock_canvas.dart';
16
import '../rendering/rendering_tester.dart';
17

18
void main() {
19
  TestRenderingFlutterBinding(); // initializes the imageCache
20

21
  test('ShapeDecoration constructor', () {
22 23 24 25
    const Color colorR = Color(0xffff0000);
    const Color colorG = Color(0xff00ff00);
    const Gradient gradient = LinearGradient(colors: <Color>[colorR, colorG]);
    expect(const ShapeDecoration(shape: Border()), const ShapeDecoration(shape: Border()));
26 27
    expect(() => ShapeDecoration(color: colorR, gradient: nonconst(gradient), shape: const Border()), throwsAssertionError);
    expect(() => ShapeDecoration(gradient: nonconst(gradient), shape: null), throwsAssertionError);
28
    expect(
29
      ShapeDecoration.fromBoxDecoration(const BoxDecoration(shape: BoxShape.circle)),
30
      const ShapeDecoration(shape: CircleBorder(side: BorderSide.none)),
31 32
    );
    expect(
33 34
      ShapeDecoration.fromBoxDecoration(BoxDecoration(shape: BoxShape.rectangle, borderRadius: BorderRadiusDirectional.circular(100.0))),
      ShapeDecoration(shape: RoundedRectangleBorder(borderRadius: BorderRadiusDirectional.circular(100.0))),
35 36
    );
    expect(
37
      ShapeDecoration.fromBoxDecoration(BoxDecoration(shape: BoxShape.circle, border: Border.all(color: colorG))),
38
      const ShapeDecoration(shape: CircleBorder(side: BorderSide(color: colorG))),
39 40
    );
    expect(
41 42
      ShapeDecoration.fromBoxDecoration(BoxDecoration(shape: BoxShape.rectangle, border: Border.all(color: colorR))),
      ShapeDecoration(shape: Border.all(color: colorR)),
43 44
    );
    expect(
45
      ShapeDecoration.fromBoxDecoration(const BoxDecoration(shape: BoxShape.rectangle, border: BorderDirectional(start: BorderSide()))),
46
      const ShapeDecoration(shape: BorderDirectional(start: BorderSide())),
47 48 49 50
    );
  });

  test('ShapeDecoration.lerp and hit test', () {
51 52
    const Decoration a = ShapeDecoration(shape: CircleBorder());
    const Decoration b = ShapeDecoration(shape: RoundedRectangleBorder());
53 54
    expect(Decoration.lerp(a, b, 0.0), a);
    expect(Decoration.lerp(a, b, 1.0), b);
55
    const Size size = Size(200.0, 100.0); // at t=0.5, width will be 150 (x=25 to x=175).
56 57 58 59 60 61
    expect(a.hitTest(size, const Offset(20.0, 50.0)), isFalse);
    expect(Decoration.lerp(a, b, 0.1).hitTest(size, const Offset(20.0, 50.0)), isFalse);
    expect(Decoration.lerp(a, b, 0.5).hitTest(size, const Offset(20.0, 50.0)), isFalse);
    expect(Decoration.lerp(a, b, 0.9).hitTest(size, const Offset(20.0, 50.0)), isTrue);
    expect(b.hitTest(size, const Offset(20.0, 50.0)), isTrue);
  });
62 63 64

  test('ShapeDecoration.image RTL test', () {
    final List<int> log = <int>[];
65
    final ShapeDecoration decoration = ShapeDecoration(
66
      shape: const CircleBorder(),
67 68
      image: DecorationImage(
        image: TestImageProvider(),
69 70 71 72
        alignment: AlignmentDirectional.bottomEnd,
      ),
    );
    final BoxPainter painter = decoration.createBoxPainter(() { log.add(0); });
73
    expect((Canvas canvas) => painter.paint(canvas, Offset.zero, const ImageConfiguration(size: Size(100.0, 100.0))), paintsAssertion);
74 75 76 77 78 79
    expect(
      (Canvas canvas) {
        return painter.paint(
          canvas,
          const Offset(20.0, -40.0),
          const ImageConfiguration(
80
            size: Size(1000.0, 1000.0),
81 82 83 84 85
            textDirection: TextDirection.rtl,
          ),
        );
      },
      paints
Dan Field's avatar
Dan Field committed
86
        ..drawImageRect(source: const Rect.fromLTRB(0.0, 0.0, 100.0, 200.0), destination: const Rect.fromLTRB(20.0, 1000.0 - 40.0 - 200.0, 20.0 + 100.0, 1000.0 - 40.0)),
87 88 89 90 91 92 93
    );
    expect(
      (Canvas canvas) {
        return painter.paint(
          canvas,
          Offset.zero,
          const ImageConfiguration(
94
            size: Size(100.0, 200.0),
95 96 97 98
            textDirection: TextDirection.ltr,
          ),
        );
      },
99
      isNot(paints..image()), // we always use drawImageRect
100 101 102
    );
    expect(log, isEmpty);
  });
103 104 105 106 107 108 109 110 111 112 113

  test('ShapeDecoration.getClipPath', () {
    const ShapeDecoration decoration = ShapeDecoration(shape: CircleBorder(side: BorderSide.none));
    const Rect rect = Rect.fromLTWH(0.0, 0.0, 100.0, 20.0);
    final Path clipPath = decoration.getClipPath(rect, TextDirection.ltr);
    final Matcher isLookLikeExpectedPath = isPathThat(
      includes: const <Offset>[ Offset(50.0, 10.0), ],
      excludes: const <Offset>[ Offset(1.0, 1.0), Offset(30.0, 10.0), Offset(99.0, 19.0), ],
    );
    expect(clipPath, isLookLikeExpectedPath);
  });
114 115 116 117 118
}

class TestImageProvider extends ImageProvider<TestImageProvider> {
  @override
  Future<TestImageProvider> obtainKey(ImageConfiguration configuration) {
119
    return SynchronousFuture<TestImageProvider>(this);
120 121 122
  }

  @override
123
  ImageStreamCompleter load(TestImageProvider key, DecoderCallback decode) {
124 125
    return OneFrameImageStreamCompleter(
      SynchronousFuture<ImageInfo>(ImageInfo(image: TestImage(), scale: 1.0)),
126 127 128 129
    );
  }
}

130
class TestImage implements ui.Image {
131 132 133 134 135 136 137 138
  @override
  int get width => 100;

  @override
  int get height => 200;

  @override
  void dispose() { }
139 140

  @override
141
  Future<ByteData> toByteData({ ui.ImageByteFormat format = ui.ImageByteFormat.rawRgba }) async {
142
    throw UnsupportedError('Cannot encode test image');
143
  }
144
}