notched_shapes_test.dart 3.87 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 9 10 11 12 13
import 'dart:math' as math;

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/painting.dart';

void main() {
  group('CircularNotchedRectangle', () {
14
    test("guest and host don't overlap", () {
15
      const CircularNotchedRectangle shape = CircularNotchedRectangle();
Dan Field's avatar
Dan Field committed
16 17
      const Rect host = Rect.fromLTRB(0.0, 100.0, 300.0, 300.0);
      const Rect guest = Rect.fromLTWH(50.0, 50.0, 10.0, 10.0);
18 19

      final Path actualPath = shape.getOuterPath(host, guest);
20
      final Path expectedPath = Path()..addRect(host);
21 22 23 24 25 26 27

      expect(
        actualPath,
        coversSameAreaAs(
          expectedPath,
          areaToCompare: host.inflate(5.0),
          sampleSize: 40,
28
        ),
29 30 31 32
      );
    });

    test('guest center above host', () {
33
      const CircularNotchedRectangle shape = CircularNotchedRectangle();
Dan Field's avatar
Dan Field committed
34 35
      const Rect host = Rect.fromLTRB(0.0, 100.0, 300.0, 300.0);
      const Rect guest = Rect.fromLTRB(190.0, 85.0, 210.0, 105.0);
36 37 38 39 40 41 42

      final Path actualPath = shape.getOuterPath(host, guest);

      expect(pathDoesNotContainCircle(actualPath, guest), isTrue);
    });

    test('guest center below host', () {
43
      const CircularNotchedRectangle shape = CircularNotchedRectangle();
Dan Field's avatar
Dan Field committed
44 45
      const Rect host = Rect.fromLTRB(0.0, 100.0, 300.0, 300.0);
      const Rect guest = Rect.fromLTRB(190.0, 95.0, 210.0, 115.0);
46 47 48 49 50 51

      final Path actualPath = shape.getOuterPath(host, guest);

      expect(pathDoesNotContainCircle(actualPath, guest), isTrue);
    });

52
    test('no guest is ok', () {
Dan Field's avatar
Dan Field committed
53
      const Rect host = Rect.fromLTRB(0.0, 100.0, 300.0, 300.0);
54 55 56 57 58 59
      expect(
        const CircularNotchedRectangle().getOuterPath(host, null),
        coversSameAreaAs(
          Path()..addRect(host),
          areaToCompare: host.inflate(800.0),
          sampleSize: 100,
60
        ),
61 62 63 64 65 66 67 68 69
      );
    });

    test('AutomaticNotchedShape - with guest', () {
      expect(
        const AutomaticNotchedShape(
          RoundedRectangleBorder(),
          RoundedRectangleBorder(),
        ).getOuterPath(
Dan Field's avatar
Dan Field committed
70 71
          const Rect.fromLTWH(-200.0, -100.0, 50.0, 100.0),
          const Rect.fromLTWH(-175.0, -110.0, 100.0, 100.0),
72 73 74 75 76 77 78 79 80 81
        ),
        coversSameAreaAs(
          Path()
            ..moveTo(-200.0, -100.0)
            ..lineTo(-150.0, -100.0)
            ..lineTo(-150.0, -10.0)
            ..lineTo(-175.0, -10.0)
            ..lineTo(-175.0, 0.0)
            ..lineTo(-200.0, 0.0)
            ..close(),
Dan Field's avatar
Dan Field committed
82
          areaToCompare: const Rect.fromLTWH(-300.0, -300.0, 600.0, 600.0),
83
          sampleSize: 100,
84
        ),
85
      );
86
    }, skip: isBrowser); // https://github.com/flutter/flutter/issues/44572
87 88 89 90 91 92 93

    test('AutomaticNotchedShape - no guest', () {
      expect(
        const AutomaticNotchedShape(
          RoundedRectangleBorder(),
          RoundedRectangleBorder(),
        ).getOuterPath(
Dan Field's avatar
Dan Field committed
94
          const Rect.fromLTWH(-200.0, -100.0, 50.0, 100.0),
95 96 97 98 99 100 101 102 103
          null,
        ),
        coversSameAreaAs(
          Path()
            ..moveTo(-200.0, -100.0)
            ..lineTo(-150.0, -100.0)
            ..lineTo(-150.0, 0.0)
            ..lineTo(-200.0, 0.0)
            ..close(),
Dan Field's avatar
Dan Field committed
104
          areaToCompare: const Rect.fromLTWH(-300.0, -300.0, 600.0, 600.0),
105
          sampleSize: 100,
106
        ),
107 108
      );
    });
109 110 111 112 113 114 115 116 117 118 119
  });
}

bool pathDoesNotContainCircle(Path path, Rect circleBounds) {
  assert(circleBounds.width == circleBounds.height);
  final double radius = circleBounds.width / 2.0;

  for (double theta = 0.0; theta <= 2.0 * math.pi; theta += math.pi / 20.0) {
    for (double i = 0.0; i < 1; i += 0.01) {
      final double x = i * radius * math.cos(theta);
      final double y = i * radius * math.sin(theta);
120
      if (path.contains(Offset(x,y) + circleBounds.center))
121 122 123 124 125
        return false;
    }
  }
  return true;
}