blob: ea5c4909f42157c45f2fbe98358e312f229683c6 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// 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';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import '../rendering/rendering_tester.dart' show TestCallbackPainter;
class TestPaintingContext implements PaintingContext {
final List<Invocation> invocations = <Invocation>[];
@override
void noSuchMethod(Invocation invocation) {
invocations.add(invocation);
}
}
void main() {
testWidgets('Can construct an empty Stack', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(),
),
);
});
testWidgets('Can construct an empty Centered Stack', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(child: Stack()),
),
);
});
testWidgets('Can change position data', (WidgetTester tester) async {
const Key key = Key('container');
await tester.pumpWidget(
Stack(
alignment: Alignment.topLeft,
children: const <Widget>[
Positioned(
left: 10.0,
child: SizedBox(
key: key,
width: 10.0,
height: 10.0,
),
),
],
),
);
Element container;
StackParentData parentData;
container = tester.element(find.byKey(key));
parentData = container.renderObject!.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, isNull);
expect(parentData.bottom, isNull);
expect(parentData.left, equals(10.0));
expect(parentData.width, isNull);
expect(parentData.height, isNull);
await tester.pumpWidget(
Stack(
alignment: Alignment.topLeft,
children: const <Widget>[
Positioned(
right: 10.0,
child: SizedBox(
key: key,
width: 10.0,
height: 10.0,
),
),
],
),
);
container = tester.element(find.byKey(key));
parentData = container.renderObject!.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, equals(10.0));
expect(parentData.bottom, isNull);
expect(parentData.left, isNull);
expect(parentData.width, isNull);
expect(parentData.height, isNull);
});
testWidgets('Can remove parent data', (WidgetTester tester) async {
const Key key = Key('container');
const SizedBox sizedBox = SizedBox(key: key, width: 10.0, height: 10.0);
await tester.pumpWidget(
Stack(
textDirection: TextDirection.ltr,
children: const <Widget>[ Positioned(left: 10.0, child: sizedBox) ],
),
);
Element containerElement = tester.element(find.byKey(key));
StackParentData parentData;
parentData = containerElement.renderObject!.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, isNull);
expect(parentData.bottom, isNull);
expect(parentData.left, equals(10.0));
expect(parentData.width, isNull);
expect(parentData.height, isNull);
await tester.pumpWidget(
Stack(
textDirection: TextDirection.ltr,
children: const <Widget>[ sizedBox ],
),
);
containerElement = tester.element(find.byKey(key));
parentData = containerElement.renderObject!.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, isNull);
expect(parentData.bottom, isNull);
expect(parentData.left, isNull);
expect(parentData.width, isNull);
expect(parentData.height, isNull);
});
testWidgets('Can align non-positioned children (LTR)', (WidgetTester tester) async {
const Key child0Key = Key('child0');
const Key child1Key = Key('child1');
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
alignment: Alignment.center,
children: const <Widget>[
SizedBox(key: child0Key, width: 20.0, height: 20.0),
SizedBox(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
final Element child0 = tester.element(find.byKey(child0Key));
final StackParentData child0RenderObjectParentData = child0.renderObject!.parentData! as StackParentData;
expect(child0RenderObjectParentData.offset, equals(Offset.zero));
final Element child1 = tester.element(find.byKey(child1Key));
final StackParentData child1RenderObjectParentData = child1.renderObject!.parentData! as StackParentData;
expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0)));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
alignment: AlignmentDirectional.bottomEnd,
children: const <Widget>[
SizedBox(key: child0Key, width: 20.0, height: 20.0),
SizedBox(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
expect(child0RenderObjectParentData.offset, equals(Offset.zero));
expect(child1RenderObjectParentData.offset, equals(const Offset(10.0, 10.0)));
});
testWidgets('Can align non-positioned children (RTL)', (WidgetTester tester) async {
const Key child0Key = Key('child0');
const Key child1Key = Key('child1');
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: Stack(
alignment: Alignment.center,
children: const <Widget>[
SizedBox(key: child0Key, width: 20.0, height: 20.0),
SizedBox(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
final Element child0 = tester.element(find.byKey(child0Key));
final StackParentData child0RenderObjectParentData = child0.renderObject!.parentData! as StackParentData;
expect(child0RenderObjectParentData.offset, equals(Offset.zero));
final Element child1 = tester.element(find.byKey(child1Key));
final StackParentData child1RenderObjectParentData = child1.renderObject!.parentData! as StackParentData;
expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0)));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: Stack(
alignment: AlignmentDirectional.bottomEnd,
children: const <Widget>[
SizedBox(key: child0Key, width: 20.0, height: 20.0),
SizedBox(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
expect(child0RenderObjectParentData.offset, equals(Offset.zero));
expect(child1RenderObjectParentData.offset, equals(const Offset(0.0, 10.0)));
});
testWidgets('Can construct an empty IndexedStack', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: IndexedStack(),
),
);
});
testWidgets('Can construct an empty Centered IndexedStack', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(child: IndexedStack()),
),
);
});
testWidgets('Can construct an IndexedStack', (WidgetTester tester) async {
const int itemCount = 3;
late List<int> itemsPainted;
Widget buildFrame(int index) {
itemsPainted = <int>[];
final List<Widget> items = List<Widget>.generate(itemCount, (int i) {
return CustomPaint(
painter: TestCallbackPainter(
onPaint: () { itemsPainted.add(i); },
),
child: Text('$i', textDirection: TextDirection.ltr),
);
});
return Center(
child: IndexedStack(
alignment: Alignment.topLeft,
index: index,
children: items,
),
);
}
await tester.pumpWidget(buildFrame(0));
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsOneWidget);
expect(find.text('2'), findsOneWidget);
expect(itemsPainted, equals(<int>[0]));
await tester.pumpWidget(buildFrame(1));
expect(itemsPainted, equals(<int>[1]));
await tester.pumpWidget(buildFrame(2));
expect(itemsPainted, equals(<int>[2]));
});
testWidgets('Can hit test an IndexedStack', (WidgetTester tester) async {
const Key key = Key('indexedStack');
const int itemCount = 3;
late List<int> itemsTapped;
Widget buildFrame(int index) {
itemsTapped = <int>[];
final List<Widget> items = List<Widget>.generate(itemCount, (int i) {
return GestureDetector(child: Text('$i', textDirection: TextDirection.ltr), onTap: () { itemsTapped.add(i); });
});
return Center(
child: IndexedStack(
alignment: Alignment.topLeft,
key: key,
index: index,
children: items,
),
);
}
await tester.pumpWidget(buildFrame(0));
expect(itemsTapped, isEmpty);
await tester.tap(find.byKey(key));
expect(itemsTapped, <int>[0]);
await tester.pumpWidget(buildFrame(2));
expect(itemsTapped, isEmpty);
await tester.tap(find.byKey(key));
expect(itemsTapped, <int>[2]);
});
testWidgets('Can set width and height', (WidgetTester tester) async {
const Key key = Key('container');
const BoxDecoration kBoxDecoration = BoxDecoration(
color: Color(0xFF00FF00),
);
await tester.pumpWidget(
Stack(
textDirection: TextDirection.ltr,
children: const <Widget>[
Positioned(
left: 10.0,
width: 11.0,
height: 12.0,
child: DecoratedBox(key: key, decoration: kBoxDecoration),
),
],
),
);
Element box;
RenderBox renderBox;
StackParentData parentData;
box = tester.element(find.byKey(key));
renderBox = box.renderObject! as RenderBox;
parentData = renderBox.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, isNull);
expect(parentData.bottom, isNull);
expect(parentData.left, equals(10.0));
expect(parentData.width, equals(11.0));
expect(parentData.height, equals(12.0));
expect(parentData.offset.dx, equals(10.0));
expect(parentData.offset.dy, equals(0.0));
expect(renderBox.size.width, equals(11.0));
expect(renderBox.size.height, equals(12.0));
await tester.pumpWidget(
Stack(
textDirection: TextDirection.ltr,
children: const <Widget>[
Positioned(
right: 10.0,
width: 11.0,
height: 12.0,
child: DecoratedBox(key: key, decoration: kBoxDecoration),
),
],
),
);
box = tester.element(find.byKey(key));
renderBox = box.renderObject! as RenderBox;
parentData = renderBox.parentData! as StackParentData;
expect(parentData.top, isNull);
expect(parentData.right, equals(10.0));
expect(parentData.bottom, isNull);
expect(parentData.left, isNull);
expect(parentData.width, equals(11.0));
expect(parentData.height, equals(12.0));
expect(parentData.offset.dx, equals(779.0));
expect(parentData.offset.dy, equals(0.0));
expect(renderBox.size.width, equals(11.0));
expect(renderBox.size.height, equals(12.0));
});
testWidgets('Can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(Stack(textDirection: TextDirection.ltr));
final RenderStack renderObject = tester.allRenderObjects.whereType<RenderStack>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
await tester.pumpWidget(Stack(textDirection: TextDirection.ltr));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
});
testWidgets('Clip.none is respected by describeApproximateClip', (WidgetTester tester) async {
await tester.pumpWidget(Stack(
textDirection: TextDirection.ltr,
children: const <Widget>[Positioned(left: 1000, right: 2000, child: SizedBox(width: 2000, height: 2000))],
));
final RenderStack renderObject = tester.allRenderObjects.whereType<RenderStack>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
bool visited = false;
renderObject.visitChildren((RenderObject child) {
visited = true;
expect(renderObject.describeApproximatePaintClip(child), const Rect.fromLTRB(0.0, 0.0, 800.0, 600.0));
});
expect(visited, true);
visited = false;
renderObject.clipBehavior = Clip.none;
renderObject.visitChildren((RenderObject child) {
visited = true;
expect(renderObject.describeApproximatePaintClip(child), null);
});
expect(visited, true);
});
testWidgets('IndexedStack with null index', (WidgetTester tester) async {
bool? tapped;
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: IndexedStack(
index: null,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () { tapped = true; },
child: const SizedBox(
width: 200.0,
height: 200.0,
),
),
],
),
),
),
);
await tester.tap(find.byType(IndexedStack), warnIfMissed: false);
final RenderBox box = tester.renderObject(find.byType(IndexedStack));
expect(box.size, equals(const Size(200.0, 200.0)));
expect(tapped, isNull);
});
testWidgets('Stack clip test', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
children: const <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
),
Positioned(
top: 0.0,
left: 0.0,
child: SizedBox(
width: 200.0,
height: 200.0,
),
),
],
),
),
),
);
RenderBox box = tester.renderObject(find.byType(Stack));
TestPaintingContext context = TestPaintingContext();
box.paint(context, Offset.zero);
expect(context.invocations.first.memberName, equals(#pushClipRect));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Stack(
clipBehavior: Clip.none,
children: const <Widget>[
SizedBox(
width: 100.0,
height: 100.0,
),
Positioned(
top: 0.0,
left: 0.0,
child: SizedBox(
width: 200.0,
height: 200.0,
),
),
],
),
),
),
);
box = tester.renderObject(find.byType(Stack));
context = TestPaintingContext();
box.paint(context, Offset.zero);
expect(context.invocations.first.memberName, equals(#paintChild));
});
testWidgets('Stack sizing: default', (WidgetTester tester) async {
final List<String> logs = <String>[];
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 2.0,
maxWidth: 3.0,
minHeight: 5.0,
maxHeight: 7.0,
),
child: Stack(
children: <Widget>[
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
logs.add(constraints.toString());
return const Placeholder();
},
),
],
),
),
),
),
);
expect(logs, <String>['BoxConstraints(0.0<=w<=3.0, 0.0<=h<=7.0)']);
});
testWidgets('Stack sizing: explicit', (WidgetTester tester) async {
final List<String> logs = <String>[];
Widget buildStack(StackFit sizing) {
return Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 2.0,
maxWidth: 3.0,
minHeight: 5.0,
maxHeight: 7.0,
),
child: Stack(
fit: sizing,
children: <Widget>[
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
logs.add(constraints.toString());
return const Placeholder();
},
),
],
),
),
),
);
}
await tester.pumpWidget(buildStack(StackFit.loose));
logs.add('=1=');
await tester.pumpWidget(buildStack(StackFit.expand));
logs.add('=2=');
await tester.pumpWidget(buildStack(StackFit.passthrough));
expect(logs, <String>[
'BoxConstraints(0.0<=w<=3.0, 0.0<=h<=7.0)',
'=1=',
'BoxConstraints(w=3.0, h=7.0)',
'=2=',
'BoxConstraints(2.0<=w<=3.0, 5.0<=h<=7.0)',
]);
});
testWidgets('Positioned.directional control test', (WidgetTester tester) async {
final Key key = UniqueKey();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
children: <Widget>[
Positioned.directional(
textDirection: TextDirection.rtl,
start: 50.0,
child: SizedBox(key: key, width: 75.0, height: 175.0),
),
],
),
),
);
expect(tester.getTopLeft(find.byKey(key)), const Offset(675.0, 0.0));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
children: <Widget>[
Positioned.directional(
textDirection: TextDirection.ltr,
start: 50.0,
child: SizedBox(key: key, width: 75.0, height: 175.0),
),
],
),
),
);
expect(tester.getTopLeft(find.byKey(key)), const Offset(50.0, 0.0));
});
testWidgets('PositionedDirectional control test', (WidgetTester tester) async {
final Key key = UniqueKey();
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: Stack(
children: <Widget>[
PositionedDirectional(
start: 50.0,
child: SizedBox(key: key, width: 75.0, height: 175.0),
),
],
),
),
);
expect(tester.getTopLeft(find.byKey(key)), const Offset(675.0, 0.0));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
children: <Widget>[
PositionedDirectional(
start: 50.0,
child: SizedBox(key: key, width: 75.0, height: 175.0),
),
],
),
),
);
expect(tester.getTopLeft(find.byKey(key)), const Offset(50.0, 0.0));
});
testWidgets('Can change the text direction of a Stack', (WidgetTester tester) async {
await tester.pumpWidget(
Stack(
alignment: Alignment.center,
),
);
await tester.pumpWidget(
Stack(
textDirection: TextDirection.rtl,
),
);
await tester.pumpWidget(
Stack(
alignment: Alignment.center,
),
);
});
testWidgets('Alignment with partially-positioned children', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: Stack(
alignment: Alignment.center,
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
Positioned(left: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(right: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(start: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(end: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
],
),
),
);
expect(tester.getRect(find.byType(SizedBox).at(0)), const Rect.fromLTWH(350.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(1)), const Rect.fromLTWH(0.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(2)), const Rect.fromLTWH(700.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(3)), const Rect.fromLTWH(350.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(4)), const Rect.fromLTWH(350.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(5)), const Rect.fromLTWH(700.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(6)), const Rect.fromLTWH(0.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(7)), const Rect.fromLTWH(350.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(8)), const Rect.fromLTWH(350.0, 500.0, 100.0, 100.0));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
alignment: Alignment.center,
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
Positioned(left: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(right: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(start: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(end: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
],
),
),
);
expect(tester.getRect(find.byType(SizedBox).at(0)), const Rect.fromLTWH(350.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(1)), const Rect.fromLTWH(0.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(2)), const Rect.fromLTWH(700.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(3)), const Rect.fromLTWH(350.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(4)), const Rect.fromLTWH(350.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(5)), const Rect.fromLTWH(0.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(6)), const Rect.fromLTWH(700.0, 250.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(7)), const Rect.fromLTWH(350.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(8)), const Rect.fromLTWH(350.0, 500.0, 100.0, 100.0));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
alignment: Alignment.bottomRight,
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
Positioned(left: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(right: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(start: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(end: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
],
),
),
);
expect(tester.getRect(find.byType(SizedBox).at(0)), const Rect.fromLTWH(700.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(1)), const Rect.fromLTWH(0.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(2)), const Rect.fromLTWH(700.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(3)), const Rect.fromLTWH(700.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(4)), const Rect.fromLTWH(700.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(5)), const Rect.fromLTWH(0.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(6)), const Rect.fromLTWH(700.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(7)), const Rect.fromLTWH(700.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(8)), const Rect.fromLTWH(700.0, 500.0, 100.0, 100.0));
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Stack(
alignment: Alignment.topLeft,
children: const <Widget>[
SizedBox(width: 100.0, height: 100.0),
Positioned(left: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(right: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
Positioned(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(start: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(end: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(top: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
PositionedDirectional(bottom: 0.0, child: SizedBox(width: 100.0, height: 100.0)),
],
),
),
);
expect(tester.getRect(find.byType(SizedBox).at(0)), const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(1)), const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(2)), const Rect.fromLTWH(700.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(3)), const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(4)), const Rect.fromLTWH(0.0, 500.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(5)), const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(6)), const Rect.fromLTWH(700.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(7)), const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
expect(tester.getRect(find.byType(SizedBox).at(8)), const Rect.fromLTWH(0.0, 500.0, 100.0, 100.0));
});
testWidgets('Stack error messages', (WidgetTester tester) async {
await tester.pumpWidget(
Stack(),
);
expect(
tester.takeException().toString(),
'No Directionality widget found.\n'
"Stack widgets require a Directionality widget ancestor to resolve the 'alignment' argument.\n"
"The default value for 'alignment' is AlignmentDirectional.topStart, which requires a text direction.\n"
'The specific widget that could not find a Directionality ancestor was:\n'
' Stack\n'
'The ownership chain for the affected widget is: "Stack ← [root]"\n'
'Typically, the Directionality widget is introduced by the MaterialApp or WidgetsApp widget at the '
'top of your application widget tree. It determines the ambient reading direction and is used, for '
'example, to determine how to lay out text, how to interpret "start" and "end" values, and to resolve '
'EdgeInsetsDirectional, AlignmentDirectional, and other *Directional objects.\n'
'Instead of providing a Directionality widget, another solution would be passing a non-directional '
"'alignment', or an explicit 'textDirection', to the Stack.",
);
});
testWidgets('Can update clipBehavior of IndexedStack',
(WidgetTester tester) async {
await tester.pumpWidget(IndexedStack(textDirection: TextDirection.ltr));
final RenderIndexedStack renderObject =
tester.renderObject<RenderIndexedStack>(find.byType(IndexedStack));
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
// Update clipBehavior to Clip.antiAlias
await tester.pumpWidget(IndexedStack(
textDirection: TextDirection.ltr,
clipBehavior: Clip.antiAlias,
));
final RenderIndexedStack renderIndexedObject =
tester.renderObject<RenderIndexedStack>(find.byType(IndexedStack));
expect(renderIndexedObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('IndexedStack sizing: explicit', (WidgetTester tester) async {
final List<String> logs = <String>[];
Widget buildIndexedStack(StackFit sizing) {
return Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(
minWidth: 2.0,
maxWidth: 3.0,
minHeight: 5.0,
maxHeight: 7.0,
),
child: IndexedStack(
sizing: sizing,
children: <Widget>[
LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
logs.add(constraints.toString());
return const Placeholder();
},
),
],
),
),
),
);
}
await tester.pumpWidget(buildIndexedStack(StackFit.loose));
logs.add('=1=');
await tester.pumpWidget(buildIndexedStack(StackFit.expand));
logs.add('=2=');
await tester.pumpWidget(buildIndexedStack(StackFit.passthrough));
expect(logs, <String>[
'BoxConstraints(0.0<=w<=3.0, 0.0<=h<=7.0)',
'=1=',
'BoxConstraints(w=3.0, h=7.0)',
'=2=',
'BoxConstraints(2.0<=w<=3.0, 5.0<=h<=7.0)',
]);
});
}