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

import 'package:flutter/rendering.dart';
6
import 'package:flutter_test/flutter_test.dart';
7 8 9 10 11 12 13 14 15 16 17

import 'rendering_tester.dart';

class RenderFixedSize extends RenderBox {
  double dimension = 100.0;

  void grow() {
    dimension *= 2.0;
    markNeedsLayout();
  }

18 19 20 21 22 23 24 25
  @override
  double computeMinIntrinsicWidth(double height) => dimension;
  @override
  double computeMaxIntrinsicWidth(double height) => dimension;
  @override
  double computeMinIntrinsicHeight(double width) => dimension;
  @override
  double computeMaxIntrinsicHeight(double width) => dimension;
26 27 28

  @override
  void performLayout() {
29
    size = Size.square(dimension);
30 31 32 33
  }
}

class RenderParentSize extends RenderProxyBox {
34
  RenderParentSize({ required RenderBox child }) : super(child);
35 36 37 38 39 40 41 42 43 44 45

  @override
  bool get sizedByParent => true;

  @override
  void performResize() {
    size = constraints.biggest;
  }

  @override
  void performLayout() {
46
    child!.layout(constraints);
47 48 49 50
  }
}

class RenderIntrinsicSize extends RenderProxyBox {
51
  RenderIntrinsicSize({ required RenderBox child }) : super(child);
52 53 54

  @override
  void performLayout() {
55
    child!.layout(constraints);
56
    size = Size(
57 58
      child!.getMinIntrinsicWidth(double.infinity),
      child!.getMinIntrinsicHeight(double.infinity),
59 60 61 62
    );
  }
}

63 64 65 66 67 68 69 70 71 72 73 74
class RenderInvalidIntrinsics extends RenderBox {
  @override
  bool get sizedByParent => true;
  @override
  double computeMinIntrinsicWidth(double height) => -1;
  @override
  double computeMaxIntrinsicWidth(double height) => -1;
  @override
  double computeMinIntrinsicHeight(double width) => -1;
  @override
  double computeMaxIntrinsicHeight(double width) => -1;
  @override
75
  Size computeDryLayout(BoxConstraints constraints) => Size.zero;
76 77
}

78
void main() {
79 80
  TestRenderingFlutterBinding.ensureInitialized();

81 82 83 84
  test('Whether using intrinsics means you get hooked into layout', () {
    RenderBox root;
    RenderFixedSize inner;
    layout(
85 86
      root = RenderIntrinsicSize(
        child: RenderParentSize(
87 88
          child: inner = RenderFixedSize(),
        ),
89
      ),
90
      constraints: const BoxConstraints(
91
        maxWidth: 1000.0,
92 93
        maxHeight: 1000.0,
      ),
94 95 96 97 98 99 100
    );
    expect(root.size, equals(inner.size));

    inner.grow();
    pumpFrame();
    expect(root.size, equals(inner.size));
  });
101

102 103 104
  test('Parent returns correct intrinsics', () {
    RenderParentSize parent;
    RenderFixedSize inner;
105

106 107 108
    layout(
      RenderIntrinsicSize(
        child: parent = RenderParentSize(
109 110
          child: inner = RenderFixedSize(),
        ),
111 112 113 114 115 116 117 118
      ),
      constraints: const BoxConstraints(
        maxWidth: 1000.0,
        maxHeight: 1000.0,
      ),
    );

    _expectIntrinsicDimensions(parent, 100);
119

120 121 122 123 124 125 126 127
    inner.grow();
    pumpFrame();

    _expectIntrinsicDimensions(parent, 200);
  });

  test('Intrinsic checks are turned on', () async {
    final List<FlutterErrorDetails> errorDetails = <FlutterErrorDetails>[];
128 129 130 131 132 133 134
    layout(
      RenderInvalidIntrinsics(),
      constraints: const BoxConstraints(
        maxWidth: 1000.0,
        maxHeight: 1000.0,
      ),
      onErrors: () {
135
        errorDetails.addAll(TestRenderingFlutterBinding.instance.takeAllFlutterErrorDetails());
136 137
      },
    );
138 139 140 141 142 143

    expect(errorDetails, isNotEmpty);
    expect(
      errorDetails.map((FlutterErrorDetails details) => details.toString()),
      everyElement(contains('violate the intrinsic protocol')),
    );
144 145 146 147 148 149 150 151 152 153
  });
}

/// Asserts that all unbounded intrinsic dimensions for [object] match
/// [dimension].
void _expectIntrinsicDimensions(RenderBox object, double dimension) {
  expect(object.getMinIntrinsicWidth(double.infinity), equals(dimension));
  expect(object.getMaxIntrinsicWidth(double.infinity), equals(dimension));
  expect(object.getMinIntrinsicHeight(double.infinity), equals(dimension));
  expect(object.getMaxIntrinsicHeight(double.infinity), equals(dimension));
154
}