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

5
import 'package:flutter/foundation.dart';
6
import 'package:flutter/rendering.dart';
7
import 'package:flutter_test/flutter_test.dart';
8

9
import 'rendering_tester.dart';
10 11

void main() {
12 13
  TestRenderingFlutterBinding.ensureInitialized();

14
  test('Stack can layout with top, right, bottom, left 0.0', () {
15
    final RenderBox size = RenderConstrainedBox(
16
      additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
17
    );
18

19
    final RenderBox red = RenderDecoratedBox(
20
      decoration: const BoxDecoration(
21
        color: Color(0xFFFF0000),
22
      ),
23
      child: size,
24
    );
25

26
    final RenderBox green = RenderDecoratedBox(
27
      decoration: const BoxDecoration(
28
        color: Color(0xFFFF0000),
29
      ),
30
    );
31

32
    final RenderBox stack = RenderStack(
33 34 35
      textDirection: TextDirection.ltr,
      children: <RenderBox>[red, green],
    );
36
    final StackParentData greenParentData = green.parentData! as StackParentData;
Hixie's avatar
Hixie committed
37
    greenParentData
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
      ..top = 0.0
      ..right = 0.0
      ..bottom = 0.0
      ..left = 0.0;

    layout(stack, constraints: const BoxConstraints());

    expect(stack.size.width, equals(100.0));
    expect(stack.size.height, equals(100.0));

    expect(red.size.width, equals(100.0));
    expect(red.size.height, equals(100.0));

    expect(green.size.width, equals(100.0));
    expect(green.size.height, equals(100.0));
  });
54

55
  test('Stack can layout with no children', () {
56
    final RenderBox stack = RenderStack(
57 58 59 60
      textDirection: TextDirection.ltr,
      children: <RenderBox>[],
    );

61
    layout(stack, constraints: BoxConstraints.tight(const Size(100.0, 100.0)));
62 63 64 65

    expect(stack.size.width, equals(100.0));
    expect(stack.size.height, equals(100.0));
  });
66

67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  test('Stack respects clipBehavior', () {
    const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
    final TestClipPaintingContext context = TestClipPaintingContext();

    // By default, clipBehavior should be Clip.none
    final RenderStack defaultStack = RenderStack(textDirection: TextDirection.ltr, children: <RenderBox>[box200x200]);
    layout(defaultStack, constraints: viewport, phase: EnginePhase.composite, onErrors: expectOverflowedErrors);
    defaultStack.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.none));

    for (final Clip clip in Clip.values) {
      final RenderBox child = box200x200;
      final RenderStack stack = RenderStack(
          textDirection: TextDirection.ltr,
          children: <RenderBox>[child],
          clipBehavior: clip,
      );
      { // Make sure that the child is positioned so the stack will consider it as overflowed.
85
        final StackParentData parentData = child.parentData! as StackParentData;
86 87 88
        parentData.left = parentData.right = 0;
      }
      layout(stack, constraints: viewport, phase: EnginePhase.composite, onErrors: expectOverflowedErrors);
89
      context.paintChild(stack, Offset.zero);
90 91 92 93
      expect(context.clipBehavior, equals(clip));
    }
  });

94 95
  group('RenderIndexedStack', () {
    test('visitChildrenForSemantics only visits displayed child', () {
96
      final RenderBox child1 = RenderConstrainedBox(
97
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
98
      );
99
      final RenderBox child2 = RenderConstrainedBox(
100
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
101
      );
102
      final RenderBox child3 = RenderConstrainedBox(
103
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
104
      );
105
      final RenderBox stack = RenderIndexedStack(
106 107 108
        index: 1,
        textDirection: TextDirection.ltr,
        children: <RenderBox>[child1, child2, child3],
109 110
      );

Josh Soref's avatar
Josh Soref committed
111
      final List<RenderObject> visitedChildren = <RenderObject>[];
112
      void visitor(RenderObject child) {
Josh Soref's avatar
Josh Soref committed
113
        visitedChildren.add(child);
114
      }
115 116 117

      stack.visitChildrenForSemantics(visitor);

Josh Soref's avatar
Josh Soref committed
118 119
      expect(visitedChildren, hasLength(1));
      expect(visitedChildren.first, child2);
120 121
    });

122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
    test('debugDescribeChildren marks invisible children as offstage', () {
      final RenderBox child1 = RenderConstrainedBox(
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
      );
      final RenderBox child2 = RenderConstrainedBox(
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
      );
      final RenderBox child3 = RenderConstrainedBox(
        additionalConstraints: BoxConstraints.tight(const Size(100.0, 100.0)),
      );

      final RenderBox stack = RenderIndexedStack(
        index: 2,
        children: <RenderBox>[child1, child2, child3],
      );

      final List<DiagnosticsNode> diagnosticNodes = stack.debugDescribeChildren();

      expect(diagnosticNodes[0].name, 'child 1');
      expect(diagnosticNodes[0].style, DiagnosticsTreeStyle.offstage);

      expect(diagnosticNodes[1].name, 'child 2');
      expect(diagnosticNodes[1].style, DiagnosticsTreeStyle.offstage);

      expect(diagnosticNodes[2].name, 'child 3');
      expect(diagnosticNodes[2].style, DiagnosticsTreeStyle.sparse);
    });
149 150
  });

151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  test('Stack in Flex can layout with no children', () {
    // Render an empty Stack in a Flex
    final RenderFlex flex = RenderFlex(
      textDirection: TextDirection.ltr,
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: <RenderBox>[
        RenderStack(
          textDirection: TextDirection.ltr,
          children: <RenderBox>[],
        ),
      ]
    );

    bool stackFlutterErrorThrown = false;
    layout(
      flex,
      constraints: BoxConstraints.tight(const Size(100.0, 100.0)),
      onErrors: () {
        stackFlutterErrorThrown = true;
      }
    );

    expect(stackFlutterErrorThrown, false);
  });

176
  // More tests in ../widgets/stack_test.dart
177
}