parent_data_test.dart 9.53 KB
Newer Older
Hixie's avatar
Hixie 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.

Adam Barth's avatar
Adam Barth committed
5
import 'package:flutter_test/flutter_test.dart';
6 7
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
Adam Barth's avatar
Adam Barth committed
8 9 10 11 12 13 14 15 16 17 18 19 20

import 'test_widgets.dart';

class TestParentData {
  TestParentData({ this.top, this.right, this.bottom, this.left });

  final double top;
  final double right;
  final double bottom;
  final double left;
}

void checkTree(WidgetTester tester, List<TestParentData> expectedParentData) {
21
  final MultiChildRenderObjectElement element = tester.element(
22 23
    find.byElementPredicate((Element element) => element is MultiChildRenderObjectElement)
  );
Adam Barth's avatar
Adam Barth committed
24 25
  expect(element, isNotNull);
  expect(element.renderObject is RenderStack, isTrue);
26
  final RenderStack renderObject = element.renderObject;
Adam Barth's avatar
Adam Barth committed
27 28 29 30
  try {
    RenderObject child = renderObject.firstChild;
    for (TestParentData expected in expectedParentData) {
      expect(child is RenderDecoratedBox, isTrue);
31
      final RenderDecoratedBox decoratedBox = child;
Adam Barth's avatar
Adam Barth committed
32
      expect(decoratedBox.parentData is StackParentData, isTrue);
33
      final StackParentData parentData = decoratedBox.parentData;
Adam Barth's avatar
Adam Barth committed
34 35 36 37
      expect(parentData.top, equals(expected.top));
      expect(parentData.right, equals(expected.right));
      expect(parentData.bottom, equals(expected.bottom));
      expect(parentData.left, equals(expected.left));
38
      final StackParentData decoratedBoxParentData = decoratedBox.parentData;
Hixie's avatar
Hixie committed
39
      child = decoratedBoxParentData.nextSibling;
Adam Barth's avatar
Adam Barth committed
40 41 42 43 44 45 46 47 48 49 50
    }
    expect(child, isNull);
  } catch (e) {
    print(renderObject.toStringDeep());
    rethrow;
  }
}

final TestParentData kNonPositioned = new TestParentData();

void main() {
51
  testWidgets('ParentDataWidget control test', (WidgetTester tester) async {
52

53
    await tester.pumpWidget(
54
      new Stack(
55
        textDirection: TextDirection.ltr,
56 57 58 59 60
        children: <Widget>[
          new DecoratedBox(decoration: kBoxDecorationA),
          new Positioned(
            top: 10.0,
            left: 10.0,
61
            child: new DecoratedBox(decoration: kBoxDecorationB),
62 63
          ),
          new DecoratedBox(decoration: kBoxDecorationC),
64 65
        ],
      ),
66 67 68 69 70 71 72 73
    );

    checkTree(tester, <TestParentData>[
      kNonPositioned,
      new TestParentData(top: 10.0, left: 10.0),
      kNonPositioned,
    ]);

74
    await tester.pumpWidget(
75
      new Stack(
76
        textDirection: TextDirection.ltr,
77 78 79 80
        children: <Widget>[
          new Positioned(
            bottom: 5.0,
            right: 7.0,
81
            child: new DecoratedBox(decoration: kBoxDecorationA),
82 83 84 85
          ),
          new Positioned(
            top: 10.0,
            left: 10.0,
86
            child: new DecoratedBox(decoration: kBoxDecorationB),
87 88
          ),
          new DecoratedBox(decoration: kBoxDecorationC),
89 90
        ],
      ),
91 92 93 94 95 96 97 98
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(bottom: 5.0, right: 7.0),
      new TestParentData(top: 10.0, left: 10.0),
      kNonPositioned,
    ]);

99 100 101
    final DecoratedBox kDecoratedBoxA = new DecoratedBox(decoration: kBoxDecorationA);
    final DecoratedBox kDecoratedBoxB = new DecoratedBox(decoration: kBoxDecorationB);
    final DecoratedBox kDecoratedBoxC = new DecoratedBox(decoration: kBoxDecorationC);
102

103
    await tester.pumpWidget(
104
      new Stack(
105
        textDirection: TextDirection.ltr,
106 107 108 109
        children: <Widget>[
          new Positioned(
            bottom: 5.0,
            right: 7.0,
110
            child: kDecoratedBoxA,
111 112 113 114
          ),
          new Positioned(
            top: 10.0,
            left: 10.0,
115
            child: kDecoratedBoxB,
116 117
          ),
          kDecoratedBoxC,
118 119
        ],
      ),
120 121 122 123 124 125 126 127
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(bottom: 5.0, right: 7.0),
      new TestParentData(top: 10.0, left: 10.0),
      kNonPositioned,
    ]);

128
    await tester.pumpWidget(
129
      new Stack(
130
        textDirection: TextDirection.ltr,
131 132 133 134
        children: <Widget>[
          new Positioned(
            bottom: 6.0,
            right: 8.0,
135
            child: kDecoratedBoxA,
136 137 138 139
          ),
          new Positioned(
            left: 10.0,
            right: 10.0,
140
            child: kDecoratedBoxB,
141 142
          ),
          kDecoratedBoxC,
143 144
        ],
      ),
145 146 147 148 149 150 151 152
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(bottom: 6.0, right: 8.0),
      new TestParentData(left: 10.0, right: 10.0),
      kNonPositioned,
    ]);

153
    await tester.pumpWidget(
154
      new Stack(
155
        textDirection: TextDirection.ltr,
156 157 158 159 160
        children: <Widget>[
          kDecoratedBoxA,
          new Positioned(
            left: 11.0,
            right: 12.0,
161
            child: new Container(child: kDecoratedBoxB),
162 163
          ),
          kDecoratedBoxC,
164 165
        ],
      ),
166 167 168 169 170 171 172 173
    );

    checkTree(tester, <TestParentData>[
      kNonPositioned,
      new TestParentData(left: 11.0, right: 12.0),
      kNonPositioned,
    ]);

174
    await tester.pumpWidget(
175
      new Stack(
176
        textDirection: TextDirection.ltr,
177 178 179 180
        children: <Widget>[
          kDecoratedBoxA,
          new Positioned(
            right: 10.0,
181
            child: new Container(child: kDecoratedBoxB),
182 183 184 185
          ),
          new Container(
            child: new Positioned(
              top: 8.0,
186 187 188 189 190
              child: kDecoratedBoxC,
            ),
          ),
        ],
      ),
191 192 193 194 195 196 197 198
    );

    checkTree(tester, <TestParentData>[
      kNonPositioned,
      new TestParentData(right: 10.0),
      new TestParentData(top: 8.0),
    ]);

199
    await tester.pumpWidget(
200
      new Stack(
201
        textDirection: TextDirection.ltr,
202 203 204
        children: <Widget>[
          new Positioned(
            right: 10.0,
205
            child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB),
206
          ),
207 208
        ],
      ),
209 210 211 212 213 214 215
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(right: 10.0),
    ]);

    flipStatefulWidget(tester);
216
    await tester.pump();
217 218 219 220 221

    checkTree(tester, <TestParentData>[
      new TestParentData(right: 10.0),
    ]);

222
    await tester.pumpWidget(
223
      new Stack(
224
        textDirection: TextDirection.ltr,
225 226 227
        children: <Widget>[
          new Positioned(
            top: 7.0,
228
            child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB),
229
          ),
230 231
        ],
      ),
232 233 234 235 236 237 238
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(top: 7.0),
    ]);

    flipStatefulWidget(tester);
239
    await tester.pump();
240 241 242 243 244

    checkTree(tester, <TestParentData>[
      new TestParentData(top: 7.0),
    ]);

245
    await tester.pumpWidget(
246
      new Stack(textDirection: TextDirection.ltr)
247 248 249
    );

    checkTree(tester, <TestParentData>[]);
Adam Barth's avatar
Adam Barth committed
250 251
  });

252 253
  testWidgets('ParentDataWidget conflicting data', (WidgetTester tester) async {
    await tester.pumpWidget(
254
      new Stack(
255
        textDirection: TextDirection.ltr,
256 257 258 259 260 261 262
        children: <Widget>[
          new Positioned(
            top: 5.0,
            bottom: 8.0,
            child: new Positioned(
              top: 6.0,
              left: 7.0,
263 264 265 266 267
              child: new DecoratedBox(decoration: kBoxDecorationB),
            ),
          ),
        ],
      ),
268
    );
269
    expect(tester.takeException(), isFlutterError);
270

271
    await tester.pumpWidget(new Stack(textDirection: TextDirection.ltr));
272

273
    checkTree(tester, <TestParentData>[]);
274

275
    await tester.pumpWidget(
276
      new Container(
277
        child: new Row(
278 279
          children: <Widget>[
            new Positioned(
280 281
              top: 6.0,
              left: 7.0,
282 283 284 285 286
              child: new DecoratedBox(decoration: kBoxDecorationB),
            ),
          ],
        ),
      ),
287
    );
288
    expect(tester.takeException(), isFlutterError);
289

290
    await tester.pumpWidget(
291
      new Stack(textDirection: TextDirection.ltr)
292
    );
293

294 295
    checkTree(tester, <TestParentData>[]);
  });
296

297
  testWidgets('ParentDataWidget interacts with global keys', (WidgetTester tester) async {
298
    final GlobalKey key = new GlobalKey();
299

300
    await tester.pumpWidget(
301
      new Stack(
302
        textDirection: TextDirection.ltr,
303 304 305 306
        children: <Widget>[
          new Positioned(
            top: 10.0,
            left: 10.0,
307 308 309 310
            child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
          ),
        ],
      ),
311 312 313 314 315 316
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(top: 10.0, left: 10.0),
    ]);

317
    await tester.pumpWidget(
318
      new Stack(
319
        textDirection: TextDirection.ltr,
320 321 322 323 324 325
        children: <Widget>[
          new Positioned(
            top: 10.0,
            left: 10.0,
            child: new DecoratedBox(
              decoration: kBoxDecorationB,
326 327 328 329 330
              child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
            ),
          ),
        ],
      ),
331 332 333 334 335 336
    );

    checkTree(tester, <TestParentData>[
      new TestParentData(top: 10.0, left: 10.0),
    ]);

337
    await tester.pumpWidget(
338
      new Stack(
339
        textDirection: TextDirection.ltr,
340 341 342 343
        children: <Widget>[
          new Positioned(
            top: 10.0,
            left: 10.0,
344 345 346 347
            child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
          ),
        ],
      ),
348
    );
349

350 351 352
    checkTree(tester, <TestParentData>[
      new TestParentData(top: 10.0, left: 10.0),
    ]);
353
  });
354 355 356 357 358

  testWidgets('Parent data invalid ancestor', (WidgetTester tester) async {
    await tester.pumpWidget(new Row(
      children: <Widget>[
        new Stack(
359
        textDirection: TextDirection.ltr,
360 361 362 363 364 365 366 367 368 369 370
          children: <Widget>[
            new Expanded(
              child: new Container()
            ),
          ],
        ),
      ],
    ));

    expect(tester.takeException(), isFlutterError);
  });
Adam Barth's avatar
Adam Barth committed
371
}