box_test.dart 9.28 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1 2 3 4
// Copyright 2015 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 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
7
import 'package:flutter_test/flutter_test.dart';
8

9
import 'rendering_tester.dart';
10 11

void main() {
Ian Hickson's avatar
Ian Hickson committed
12
  test('should size to render view', () {
13 14
    final RenderBox root = RenderDecoratedBox(
      decoration: BoxDecoration(
15
        color: const Color(0xFF00FF00),
16
        gradient: RadialGradient(
17 18
          center: Alignment.topLeft,
          radius: 1.8,
19 20 21 22
          colors: <Color>[Colors.yellow[500], Colors.blue[500]],
        ),
        boxShadow: kElevationToShadow[3],
      ),
23 24 25 26 27 28 29
    );
    layout(root);
    expect(root.size.width, equals(800.0));
    expect(root.size.height, equals(600.0));
  });

  test('Flex and padding', () {
30
    final RenderBox size = RenderConstrainedBox(
31
      additionalConstraints: const BoxConstraints().tighten(height: 100.0),
32
    );
33
    final RenderBox inner = RenderDecoratedBox(
34
      decoration: const BoxDecoration(
35
        color: Color(0xFF00FF00),
36
      ),
37
      child: size,
38
    );
39
    final RenderBox padding = RenderPadding(
40
      padding: const EdgeInsets.all(50.0),
41
      child: inner,
42
    );
43
    final RenderBox flex = RenderFlex(
44
      children: <RenderBox>[padding],
45
      direction: Axis.vertical,
46
      crossAxisAlignment: CrossAxisAlignment.stretch,
47
    );
48
    final RenderBox outer = RenderDecoratedBox(
49
      decoration: const BoxDecoration(
50
        color: Color(0xFF0000FF),
51
      ),
52
      child: flex,
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
    );

    layout(outer);

    expect(size.size.width, equals(700.0));
    expect(size.size.height, equals(100.0));
    expect(inner.size.width, equals(700.0));
    expect(inner.size.height, equals(100.0));
    expect(padding.size.width, equals(800.0));
    expect(padding.size.height, equals(200.0));
    expect(flex.size.width, equals(800.0));
    expect(flex.size.height, equals(600.0));
    expect(outer.size.width, equals(800.0));
    expect(outer.size.height, equals(600.0));
  });

Ian Hickson's avatar
Ian Hickson committed
69
  test('should not have a 0 sized colored Box', () {
70
    final RenderBox coloredBox = RenderDecoratedBox(
71
      decoration: const BoxDecoration(),
72
    );
73 74

    expect(coloredBox, hasAGoodToStringDeep);
75 76 77 78 79 80 81 82 83 84 85
    expect(
        coloredBox.toStringDeep(minLevel: DiagnosticLevel.info),
        equalsIgnoringHashCodes(
          'RenderDecoratedBox#00000 NEEDS-LAYOUT NEEDS-PAINT DETACHED\n'
          '   parentData: MISSING\n'
          '   constraints: MISSING\n'
          '   size: MISSING\n'
          '   decoration: BoxDecoration:\n'
          '     <no decorations specified>\n'
          '   configuration: ImageConfiguration()\n'),
    );
86

87
    final RenderBox paddingBox = RenderPadding(
88 89
      padding: const EdgeInsets.all(10.0),
      child: coloredBox,
90
    );
91
    final RenderBox root = RenderDecoratedBox(
92
      decoration: const BoxDecoration(),
93
      child: paddingBox,
94 95 96 97
    );
    layout(root);
    expect(coloredBox.size.width, equals(780.0));
    expect(coloredBox.size.height, equals(580.0));
98 99 100

    expect(coloredBox, hasAGoodToStringDeep);
    expect(
101
      coloredBox.toStringDeep(minLevel: DiagnosticLevel.info),
102 103 104 105 106
      equalsIgnoringHashCodes(
        'RenderDecoratedBox#00000 NEEDS-PAINT\n'
        '   parentData: offset=Offset(10.0, 10.0) (can use size)\n'
        '   constraints: BoxConstraints(w=780.0, h=580.0)\n'
        '   size: Size(780.0, 580.0)\n'
107
        '   decoration: BoxDecoration:\n'
108 109 110 111
        '     <no decorations specified>\n'
        '   configuration: ImageConfiguration()\n',
      ),
    );
112
  });
113

Ian Hickson's avatar
Ian Hickson committed
114
  test('reparenting should clear position', () {
115
    final RenderDecoratedBox coloredBox = RenderDecoratedBox(
116
      decoration: const BoxDecoration(),
117
    );
118

119
    final RenderPadding paddedBox = RenderPadding(
120 121 122
      child: coloredBox,
      padding: const EdgeInsets.all(10.0),
    );
123
    layout(paddedBox);
124
    final BoxParentData parentData = coloredBox.parentData;
125
    expect(parentData.offset.dx, isNot(equals(0.0)));
126 127
    paddedBox.child = null;

128
    final RenderConstrainedBox constraintedBox = RenderConstrainedBox(
129 130 131
      child: coloredBox,
      additionalConstraints: const BoxConstraints(),
    );
132
    layout(constraintedBox);
133
    expect(coloredBox.parentData?.runtimeType, ParentData);
134
  });
135 136

  test('UnconstrainedBox expands to fit children', () {
137
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
138
      constrainedAxis: Axis.horizontal, // This is reset to null below.
139
      textDirection: TextDirection.ltr,
140
      child: RenderConstrainedBox(
141 142 143 144 145 146 147 148 149 150 151 152 153
        additionalConstraints: const BoxConstraints.tightFor(width: 200.0, height: 200.0),
      ),
      alignment: Alignment.center,
    );
    layout(
      unconstrained,
      constraints: const BoxConstraints(
        minWidth: 200.0,
        maxWidth: 200.0,
        minHeight: 200.0,
        maxHeight: 200.0,
      ),
    );
154 155 156
    // Check that we can update the constrained axis to null.
    unconstrained.constrainedAxis = null;
    renderer.reassembleApplication();
157 158 159 160 161 162

    expect(unconstrained.size.width, equals(200.0), reason: 'unconstrained width');
    expect(unconstrained.size.height, equals(200.0), reason: 'unconstrained height');
  });

  test('UnconstrainedBox handles vertical overflow', () {
163
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
164
      textDirection: TextDirection.ltr,
165
      child: RenderConstrainedBox(
166 167 168 169
        additionalConstraints: const BoxConstraints.tightFor(height: 200.0),
      ),
      alignment: Alignment.center,
    );
170
    const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
171 172 173 174 175 176 177 178
    layout(unconstrained, constraints: viewport);
    expect(unconstrained.getMinIntrinsicHeight(100.0), equals(200.0));
    expect(unconstrained.getMaxIntrinsicHeight(100.0), equals(200.0));
    expect(unconstrained.getMinIntrinsicWidth(100.0), equals(0.0));
    expect(unconstrained.getMaxIntrinsicWidth(100.0), equals(0.0));
  });

  test('UnconstrainedBox handles horizontal overflow', () {
179
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
180
      textDirection: TextDirection.ltr,
181
      child: RenderConstrainedBox(
182 183 184 185
        additionalConstraints: const BoxConstraints.tightFor(width: 200.0),
      ),
      alignment: Alignment.center,
    );
186
    const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
187 188 189 190 191 192 193 194
    layout(unconstrained, constraints: viewport);
    expect(unconstrained.getMinIntrinsicHeight(100.0), equals(0.0));
    expect(unconstrained.getMaxIntrinsicHeight(100.0), equals(0.0));
    expect(unconstrained.getMinIntrinsicWidth(100.0), equals(200.0));
    expect(unconstrained.getMaxIntrinsicWidth(100.0), equals(200.0));
  });

  test('UnconstrainedBox.toStringDeep returns useful information', () {
195
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
196 197 198 199 200 201 202 203 204 205 206 207 208
      textDirection: TextDirection.ltr,
      alignment: Alignment.center,
    );
    expect(unconstrained.alignment, Alignment.center);
    expect(unconstrained.textDirection, TextDirection.ltr);
    expect(unconstrained, hasAGoodToStringDeep);
    expect(
      unconstrained.toStringDeep(minLevel: DiagnosticLevel.info),
      equalsIgnoringHashCodes(
        'RenderUnconstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT DETACHED\n'
          '   parentData: MISSING\n'
          '   constraints: MISSING\n'
          '   size: MISSING\n'
209
          '   alignment: center\n'
210 211 212
          '   textDirection: ltr\n'),
    );
  });
213

214
  test('UnconstrainedBox honors constrainedAxis=Axis.horizontal', () {
215
    final RenderConstrainedBox flexible =
216 217
        RenderConstrainedBox(additionalConstraints: const BoxConstraints.expand(height: 200.0));
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
218 219
      constrainedAxis: Axis.horizontal,
      textDirection: TextDirection.ltr,
220
      child: RenderFlex(
221 222 223 224 225 226 227 228 229 230
        direction: Axis.horizontal,
        textDirection: TextDirection.ltr,
        children: <RenderBox>[flexible],
      ),
      alignment: Alignment.center,
    );
    final FlexParentData flexParentData = flexible.parentData;
    flexParentData.flex = 1;
    flexParentData.fit = FlexFit.tight;

231
    const BoxConstraints viewport = BoxConstraints(maxWidth: 100.0);
232 233 234 235 236 237
    layout(unconstrained, constraints: viewport);

    expect(unconstrained.size.width, equals(100.0), reason: 'constrained width');
    expect(unconstrained.size.height, equals(200.0), reason: 'unconstrained height');
  });

238
  test('UnconstrainedBox honors constrainedAxis=Axis.vertical', () {
239
    final RenderConstrainedBox flexible =
240 241
    RenderConstrainedBox(additionalConstraints: const BoxConstraints.expand(width: 200.0));
    final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
242 243
      constrainedAxis: Axis.vertical,
      textDirection: TextDirection.ltr,
244
      child: RenderFlex(
245 246 247 248 249 250 251 252 253 254
        direction: Axis.vertical,
        textDirection: TextDirection.ltr,
        children: <RenderBox>[flexible],
      ),
      alignment: Alignment.center,
    );
    final FlexParentData flexParentData = flexible.parentData;
    flexParentData.flex = 1;
    flexParentData.fit = FlexFit.tight;

255
    const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0);
256 257 258 259 260
    layout(unconstrained, constraints: viewport);

    expect(unconstrained.size.width, equals(200.0), reason: 'unconstrained width');
    expect(unconstrained.size.height, equals(100.0), reason: 'constrained height');
  });
261
}