parent_data_test.dart 9.63 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
        children: const <Widget>[
          const DecoratedBox(decoration: kBoxDecorationA),
          const Positioned(
59 60
            top: 10.0,
            left: 10.0,
61
            child: const DecoratedBox(decoration: kBoxDecorationB),
62
          ),
63
          const 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
        children: const <Widget>[
          const Positioned(
79 80
            bottom: 5.0,
            right: 7.0,
81
            child: const DecoratedBox(decoration: kBoxDecorationA),
82
          ),
83
          const Positioned(
84 85
            top: 10.0,
            left: 10.0,
86
            child: const DecoratedBox(decoration: kBoxDecorationB),
87
          ),
88
          const 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
    const DecoratedBox kDecoratedBoxA = const DecoratedBox(decoration: kBoxDecorationA);
    const DecoratedBox kDecoratedBoxB = const DecoratedBox(decoration: kBoxDecorationB);
    const DecoratedBox kDecoratedBoxC = const DecoratedBox(decoration: kBoxDecorationC);
102

103
    await tester.pumpWidget(
104
      new Stack(
105
        textDirection: TextDirection.ltr,
106 107
        children: const <Widget>[
          const Positioned(
108 109
            bottom: 5.0,
            right: 7.0,
110
            child: kDecoratedBoxA,
111
          ),
112
          const Positioned(
113 114
            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
        children: const <Widget>[
          const Positioned(
133 134
            bottom: 6.0,
            right: 8.0,
135
            child: kDecoratedBoxA,
136
          ),
137
          const Positioned(
138 139
            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
          ),
          new Container(
184
            child: const Positioned(
185
              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
        children: const <Widget>[
          const Positioned(
204
            right: 10.0,
205
            child: const 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
        children: const <Widget>[
          const Positioned(
227
            top: 7.0,
228
            child: const 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
        children: const <Widget>[
257
          const Positioned(
258 259
            top: 5.0,
            bottom: 8.0,
260
            child: const Positioned(
261 262
              top: 6.0,
              left: 7.0,
263
              child: const DecoratedBox(decoration: kBoxDecorationB),
264 265 266 267
            ),
          ),
        ],
      ),
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
          children: const <Widget>[
279
            const Positioned(
280 281
              top: 6.0,
              left: 7.0,
282
              child: const DecoratedBox(decoration: kBoxDecorationB),
283 284 285 286
            ),
          ],
        ),
      ),
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
}