Add RTL support to Stack (#11973)

Notice that the default alignment for Stack needs to know the
directionality.
This commit is contained in:
Adam Barth 2017-09-07 22:52:36 -07:00 committed by GitHub
parent 1792766a88
commit c46347b6df
30 changed files with 1500 additions and 1056 deletions

View File

@ -112,6 +112,7 @@ void main() {
// The bottom later is our RenderDots object, and on top of that we show the // The bottom later is our RenderDots object, and on top of that we show the
// text. // text.
final RenderStack stack = new RenderStack( final RenderStack stack = new RenderStack(
textDirection: TextDirection.ltr,
children: <RenderBox>[ children: <RenderBox>[
new RenderDots(), new RenderDots(),
paragraph, paragraph,

View File

@ -297,16 +297,19 @@ class RenderStack extends RenderBox
/// top left corners. /// top left corners.
RenderStack({ RenderStack({
List<RenderBox> children, List<RenderBox> children,
FractionalOffset alignment: FractionalOffset.topLeft, FractionalOffsetGeometry alignment: FractionalOffsetDirectional.topStart,
@required TextDirection textDirection,
StackFit fit: StackFit.loose, StackFit fit: StackFit.loose,
Overflow overflow: Overflow.clip Overflow overflow: Overflow.clip,
}) : assert(alignment != null), }) : assert(alignment != null),
assert(fit != null), assert(fit != null),
assert(overflow != null), assert(overflow != null),
_alignment = alignment, _alignment = alignment,
_textDirection = textDirection,
_fit = fit, _fit = fit,
_overflow = overflow { _overflow = overflow {
addAll(children); addAll(children);
_applyUpdate();
} }
bool _hasVisualOverflow = false; bool _hasVisualOverflow = false;
@ -317,19 +320,40 @@ class RenderStack extends RenderBox
child.parentData = new StackParentData(); child.parentData = new StackParentData();
} }
// The resolved absolute insets.
FractionalOffset _resolvedAlignment;
void _applyUpdate() {
final FractionalOffset resolvedAlignment = alignment.resolve(textDirection);
if (_resolvedAlignment != resolvedAlignment) {
_resolvedAlignment = resolvedAlignment;
markNeedsLayout();
}
}
/// How to align the non-positioned children in the stack. /// How to align the non-positioned children in the stack.
/// ///
/// The non-positioned children are placed relative to each other such that /// The non-positioned children are placed relative to each other such that
/// the points determined by [alignment] are co-located. For example, if the /// the points determined by [alignment] are co-located. For example, if the
/// [alignment] is [FractionalOffset.topLeft], then the top left corner of /// [alignment] is [FractionalOffset.topLeft], then the top left corner of
/// each non-positioned child will be located at the same global coordinate. /// each non-positioned child will be located at the same global coordinate.
FractionalOffset get alignment => _alignment; FractionalOffsetGeometry get alignment => _alignment;
FractionalOffset _alignment; FractionalOffsetGeometry _alignment;
set alignment(FractionalOffset value) { set alignment(FractionalOffsetGeometry value) {
assert(value != null); assert(value != null);
if (_alignment != value) { if (_alignment != value) {
_alignment = value; _alignment = value;
markNeedsLayout(); _applyUpdate();
}
}
/// The text direction with which to resolve [alignment].
TextDirection get textDirection => _textDirection;
TextDirection _textDirection;
set textDirection(TextDirection value) {
if (_textDirection != value) {
_textDirection = value;
_applyUpdate();
} }
} }
@ -455,7 +479,7 @@ class RenderStack extends RenderBox
final StackParentData childParentData = child.parentData; final StackParentData childParentData = child.parentData;
if (!childParentData.isPositioned) { if (!childParentData.isPositioned) {
childParentData.offset = alignment.alongOffset(size - child.size); childParentData.offset = _resolvedAlignment.alongOffset(size - child.size);
} else { } else {
BoxConstraints childConstraints = const BoxConstraints(); BoxConstraints childConstraints = const BoxConstraints();
@ -526,7 +550,8 @@ class RenderStack extends RenderBox
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder description) { void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment)); description.add(new DiagnosticsProperty<FractionalOffsetGeometry>('alignment', alignment));
description.add(new EnumProperty<TextDirection>('textDirection', textDirection));
description.add(new EnumProperty<StackFit>('fit', fit)); description.add(new EnumProperty<StackFit>('fit', fit));
description.add(new EnumProperty<Overflow>('overflow', overflow)); description.add(new EnumProperty<Overflow>('overflow', overflow));
} }
@ -543,11 +568,13 @@ class RenderIndexedStack extends RenderStack {
/// If the [index] parameter is null, nothing is displayed. /// If the [index] parameter is null, nothing is displayed.
RenderIndexedStack({ RenderIndexedStack({
List<RenderBox> children, List<RenderBox> children,
FractionalOffset alignment: FractionalOffset.topLeft, FractionalOffsetGeometry alignment: FractionalOffsetDirectional.topStart,
int index: 0 @required TextDirection textDirection,
int index: 0,
}) : _index = index, super( }) : _index = index, super(
children: children, children: children,
alignment: alignment alignment: alignment,
textDirection: textDirection,
); );
@override @override

View File

@ -2193,7 +2193,8 @@ class Stack extends MultiChildRenderObjectWidget {
/// top left corners. /// top left corners.
Stack({ Stack({
Key key, Key key,
this.alignment: FractionalOffset.topLeft, this.alignment: FractionalOffsetDirectional.topStart,
this.textDirection,
this.fit: StackFit.loose, this.fit: StackFit.loose,
this.overflow: Overflow.clip, this.overflow: Overflow.clip,
List<Widget> children: const <Widget>[], List<Widget> children: const <Widget>[],
@ -2205,7 +2206,12 @@ class Stack extends MultiChildRenderObjectWidget {
/// the points determined by [alignment] are co-located. For example, if the /// the points determined by [alignment] are co-located. For example, if the
/// [alignment] is [FractionalOffset.topLeft], then the top left corner of /// [alignment] is [FractionalOffset.topLeft], then the top left corner of
/// each non-positioned child will be located at the same global coordinate. /// each non-positioned child will be located at the same global coordinate.
final FractionalOffset alignment; final FractionalOffsetGeometry alignment;
/// The text direction with which to resolve [alignment].
///
/// Defaults to the ambient [Directionality].
final TextDirection textDirection;
/// How to size the non-positioned children in the stack. /// How to size the non-positioned children in the stack.
/// ///
@ -2224,6 +2230,7 @@ class Stack extends MultiChildRenderObjectWidget {
RenderStack createRenderObject(BuildContext context) { RenderStack createRenderObject(BuildContext context) {
return new RenderStack( return new RenderStack(
alignment: alignment, alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
fit: fit, fit: fit,
overflow: overflow, overflow: overflow,
); );
@ -2233,6 +2240,7 @@ class Stack extends MultiChildRenderObjectWidget {
void updateRenderObject(BuildContext context, RenderStack renderObject) { void updateRenderObject(BuildContext context, RenderStack renderObject) {
renderObject renderObject
..alignment = alignment ..alignment = alignment
..textDirection = textDirection ?? Directionality.of(context)
..fit = fit ..fit = fit
..overflow = overflow; ..overflow = overflow;
} }
@ -2240,7 +2248,8 @@ class Stack extends MultiChildRenderObjectWidget {
@override @override
void debugFillProperties(DiagnosticPropertiesBuilder description) { void debugFillProperties(DiagnosticPropertiesBuilder description) {
super.debugFillProperties(description); super.debugFillProperties(description);
description.add(new DiagnosticsProperty<FractionalOffset>('alignment', alignment)); description.add(new DiagnosticsProperty<FractionalOffsetGeometry>('alignment', alignment));
description.add(new EnumProperty<TextDirection>('textDirection', textDirection, defaultValue: null));
description.add(new EnumProperty<StackFit>('fit', fit)); description.add(new EnumProperty<StackFit>('fit', fit));
description.add(new EnumProperty<Overflow>('overflow', overflow)); description.add(new EnumProperty<Overflow>('overflow', overflow));
} }
@ -2260,23 +2269,31 @@ class IndexedStack extends Stack {
/// The [index] argument must not be null. /// The [index] argument must not be null.
IndexedStack({ IndexedStack({
Key key, Key key,
FractionalOffset alignment: FractionalOffset.topLeft, FractionalOffsetGeometry alignment: FractionalOffsetDirectional.topStart,
TextDirection textDirection,
StackFit sizing: StackFit.loose, StackFit sizing: StackFit.loose,
this.index: 0, this.index: 0,
List<Widget> children: const <Widget>[], List<Widget> children: const <Widget>[],
}) : super(key: key, alignment: alignment, fit: sizing, children: children); }) : super(key: key, alignment: alignment, textDirection: textDirection, fit: sizing, children: children);
/// The index of the child to show. /// The index of the child to show.
final int index; final int index;
@override @override
RenderIndexedStack createRenderObject(BuildContext context) => new RenderIndexedStack(index: index, alignment: alignment); RenderIndexedStack createRenderObject(BuildContext context) {
return new RenderIndexedStack(
index: index,
alignment: alignment,
textDirection: textDirection ?? Directionality.of(context),
);
}
@override @override
void updateRenderObject(BuildContext context, RenderIndexedStack renderObject) { void updateRenderObject(BuildContext context, RenderIndexedStack renderObject) {
renderObject renderObject
..index = index ..index = index
..alignment = alignment; ..alignment = alignment
..textDirection = textDirection ?? Directionality.of(context);
} }
} }

View File

@ -115,18 +115,21 @@ void main() {
} }
Widget build() { Widget build() {
return new Navigator( return new Directionality(
initialRoute: '/', textDirection: TextDirection.ltr,
onGenerateRoute: (RouteSettings settings) { child: new Navigator(
return new MaterialPageRoute<Null>( initialRoute: '/',
settings: settings, onGenerateRoute: (RouteSettings settings) {
builder: (BuildContext context) { return new MaterialPageRoute<Null>(
return new Material( settings: settings,
child: buildFrame(value: 'one', onChanged: didChangeValue), builder: (BuildContext context) {
); return new Material(
}, child: buildFrame(value: 'one', onChanged: didChangeValue),
); );
} },
);
},
),
); );
} }

View File

@ -26,7 +26,10 @@ void main() {
), ),
); );
final RenderBox stack = new RenderStack(children: <RenderBox>[red, green]); final RenderBox stack = new RenderStack(
textDirection: TextDirection.ltr,
children: <RenderBox>[red, green],
);
final StackParentData greenParentData = green.parentData; final StackParentData greenParentData = green.parentData;
greenParentData greenParentData
..top = 0.0 ..top = 0.0
@ -59,8 +62,9 @@ void main() {
additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0)) additionalConstraints: new BoxConstraints.tight(const Size(100.0, 100.0))
); );
final RenderBox stack = new RenderIndexedStack( final RenderBox stack = new RenderIndexedStack(
children: <RenderBox>[child1, child2, child3],
index: 1, index: 1,
textDirection: TextDirection.ltr,
children: <RenderBox>[child1, child2, child3],
); );
final List<RenderObject> vistedChildren = <RenderObject>[]; final List<RenderObject> vistedChildren = <RenderObject>[];

View File

@ -10,18 +10,21 @@ import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('AnimatedCrossFade test', (WidgetTester tester) async { testWidgets('AnimatedCrossFade test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const Center( const Directionality(
child: const AnimatedCrossFade( textDirection: TextDirection.ltr,
firstChild: const SizedBox( child: const Center(
width: 100.0, child: const AnimatedCrossFade(
height: 100.0, firstChild: const SizedBox(
width: 100.0,
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
), ),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
), ),
), ),
); );
@ -32,18 +35,21 @@ void main() {
expect(box.size.height, equals(100.0)); expect(box.size.height, equals(100.0));
await tester.pumpWidget( await tester.pumpWidget(
const Center( const Directionality(
child: const AnimatedCrossFade( textDirection: TextDirection.ltr,
firstChild: const SizedBox( child: const Center(
width: 100.0, child: const AnimatedCrossFade(
height: 100.0, firstChild: const SizedBox(
width: 100.0,
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
), ),
); );
@ -58,18 +64,21 @@ void main() {
testWidgets('AnimatedCrossFade test showSecond', (WidgetTester tester) async { testWidgets('AnimatedCrossFade test showSecond', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
const Center( const Directionality(
child: const AnimatedCrossFade( textDirection: TextDirection.ltr,
firstChild: const SizedBox( child: const Center(
width: 100.0, child: const AnimatedCrossFade(
height: 100.0, firstChild: const SizedBox(
width: 100.0,
height: 100.0,
),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
secondChild: const SizedBox(
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
), ),
); );
@ -85,41 +94,47 @@ void main() {
final Key secondKey = new UniqueKey(); final Key secondKey = new UniqueKey();
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new AnimatedCrossFade( textDirection: TextDirection.ltr,
alignment: FractionalOffset.bottomRight, child: new Center(
firstChild: new SizedBox( child: new AnimatedCrossFade(
key: firstKey, alignment: FractionalOffset.bottomRight,
width: 100.0, firstChild: new SizedBox(
height: 100.0, key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
), ),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showFirst,
), ),
), ),
); );
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new AnimatedCrossFade( textDirection: TextDirection.ltr,
alignment: FractionalOffset.bottomRight, child: new Center(
firstChild: new SizedBox( child: new AnimatedCrossFade(
key: firstKey, alignment: FractionalOffset.bottomRight,
width: 100.0, firstChild: new SizedBox(
height: 100.0, key: firstKey,
width: 100.0,
height: 100.0,
),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
secondChild: new SizedBox(
key: secondKey,
width: 200.0,
height: 200.0,
),
duration: const Duration(milliseconds: 200),
crossFadeState: CrossFadeState.showSecond,
), ),
), ),
); );
@ -249,11 +264,14 @@ void main() {
}); });
Widget crossFadeWithWatcher({bool towardsSecond: false}) { Widget crossFadeWithWatcher({bool towardsSecond: false}) {
return new AnimatedCrossFade( return new Directionality(
firstChild: const _TickerWatchingWidget(), textDirection: TextDirection.ltr,
secondChild: new Container(), child: new AnimatedCrossFade(
crossFadeState: towardsSecond ? CrossFadeState.showSecond : CrossFadeState.showFirst, firstChild: const _TickerWatchingWidget(),
duration: const Duration(milliseconds: 50), secondChild: new Container(),
crossFadeState: towardsSecond ? CrossFadeState.showSecond : CrossFadeState.showFirst,
duration: const Duration(milliseconds: 50),
),
); );
} }
@ -301,30 +319,45 @@ void main() {
}); });
testWidgets('AnimatedCrossFade.layoutBuilder', (WidgetTester tester) async { testWidgets('AnimatedCrossFade.layoutBuilder', (WidgetTester tester) async {
await tester.pumpWidget(const AnimatedCrossFade( await tester.pumpWidget(
firstChild: const Text('AAA', textDirection: TextDirection.ltr), const Directionality(
secondChild: const Text('BBB', textDirection: TextDirection.ltr), textDirection: TextDirection.ltr,
crossFadeState: CrossFadeState.showFirst, child: const AnimatedCrossFade(
duration: const Duration(milliseconds: 50), firstChild: const Text('AAA', textDirection: TextDirection.ltr),
)); secondChild: const Text('BBB', textDirection: TextDirection.ltr),
crossFadeState: CrossFadeState.showFirst,
duration: const Duration(milliseconds: 50),
),
),
);
expect(find.text('AAA'), findsOneWidget); expect(find.text('AAA'), findsOneWidget);
expect(find.text('BBB'), findsOneWidget); expect(find.text('BBB'), findsOneWidget);
await tester.pumpWidget(new AnimatedCrossFade( await tester.pumpWidget(
firstChild: const Text('AAA', textDirection: TextDirection.ltr), new Directionality(
secondChild: const Text('BBB', textDirection: TextDirection.ltr), textDirection: TextDirection.ltr,
crossFadeState: CrossFadeState.showFirst, child: new AnimatedCrossFade(
duration: const Duration(milliseconds: 50), firstChild: const Text('AAA', textDirection: TextDirection.ltr),
layoutBuilder: (Widget a, Key aKey, Widget b, Key bKey) => a, secondChild: const Text('BBB', textDirection: TextDirection.ltr),
)); crossFadeState: CrossFadeState.showFirst,
duration: const Duration(milliseconds: 50),
layoutBuilder: (Widget a, Key aKey, Widget b, Key bKey) => a,
),
),
);
expect(find.text('AAA'), findsOneWidget); expect(find.text('AAA'), findsOneWidget);
expect(find.text('BBB'), findsNothing); expect(find.text('BBB'), findsNothing);
await tester.pumpWidget(new AnimatedCrossFade( await tester.pumpWidget(
firstChild: const Text('AAA', textDirection: TextDirection.ltr), new Directionality(
secondChild: const Text('BBB', textDirection: TextDirection.ltr), textDirection: TextDirection.ltr,
crossFadeState: CrossFadeState.showSecond, child: new AnimatedCrossFade(
duration: const Duration(milliseconds: 50), firstChild: const Text('AAA', textDirection: TextDirection.ltr),
layoutBuilder: (Widget a, Key aKey, Widget b, Key bKey) => a, secondChild: const Text('BBB', textDirection: TextDirection.ltr),
)); crossFadeState: CrossFadeState.showSecond,
duration: const Duration(milliseconds: 50),
layoutBuilder: (Widget a, Key aKey, Widget b, Key bKey) => a,
),
),
);
expect(find.text('BBB'), findsOneWidget); expect(find.text('BBB'), findsOneWidget);
expect(find.text('AAA'), findsNothing); expect(find.text('AAA'), findsNothing);
}); });

View File

@ -27,6 +27,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -50,6 +51,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -110,6 +112,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -133,6 +136,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -156,6 +160,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -190,6 +195,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),
@ -213,6 +219,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new AnimatedPositioned( new AnimatedPositioned(
child: new Container(key: key), child: new Container(key: key),

View File

@ -26,12 +26,17 @@ class TestRoute<T> extends PageRoute<T> {
} }
Future<Null> pumpApp(WidgetTester tester) async { Future<Null> pumpApp(WidgetTester tester) async {
await tester.pumpWidget(new WidgetsApp( await tester.pumpWidget(
color: const Color(0xFF333333), new Directionality(
onGenerateRoute: (RouteSettings settings) { textDirection: TextDirection.ltr,
return new TestRoute<Null>(settings: settings, child: new Container()); child: new WidgetsApp(
}, color: const Color(0xFF333333),
)); onGenerateRoute: (RouteSettings settings) {
return new TestRoute<Null>(settings: settings, child: new Container());
},
),
),
);
} }
void main() { void main() {

View File

@ -11,25 +11,28 @@ void main() {
final LayerLink link = new LayerLink(); final LayerLink link = new LayerLink();
final GlobalKey key = new GlobalKey(); final GlobalKey key = new GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
left: 123.0, children: <Widget>[
top: 456.0, new Positioned(
child: new CompositedTransformTarget( left: 123.0,
link: link, top: 456.0,
child: new Container(height: 10.0, width: 10.0), child: new CompositedTransformTarget(
link: link,
child: new Container(height: 10.0, width: 10.0),
),
), ),
), new Positioned(
new Positioned( left: 787.0,
left: 787.0, top: 343.0,
top: 343.0, child: new CompositedTransformFollower(
child: new CompositedTransformFollower( link: link,
link: link, child: new Container(key: key, height: 10.0, width: 10.0),
child: new Container(key: key, height: 10.0, width: 10.0), ),
), ),
), ],
], ),
), ),
); );
final RenderBox box = key.currentContext.findRenderObject(); final RenderBox box = key.currentContext.findRenderObject();
@ -41,31 +44,34 @@ void main() {
final GlobalKey key1 = new GlobalKey(); final GlobalKey key1 = new GlobalKey();
final GlobalKey key2 = new GlobalKey(); final GlobalKey key2 = new GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
top: 123.0, children: <Widget>[
left: 456.0, new Positioned(
child: new Transform.rotate( top: 123.0,
angle: 1.0, // radians left: 456.0,
child: new CompositedTransformTarget( child: new Transform.rotate(
link: link, angle: 1.0, // radians
child: new Container(key: key1, height: 10.0, width: 10.0), child: new CompositedTransformTarget(
link: link,
child: new Container(key: key1, height: 10.0, width: 10.0),
),
), ),
), ),
), new Positioned(
new Positioned( top: 787.0,
top: 787.0, left: 343.0,
left: 343.0, child: new Transform.rotate(
child: new Transform.rotate( angle: -0.3, // radians
angle: -0.3, // radians child: new CompositedTransformFollower(
child: new CompositedTransformFollower( link: link,
link: link, child: new Container(key: key2, height: 10.0, width: 10.0),
child: new Container(key: key2, height: 10.0, width: 10.0), ),
), ),
), ),
), ],
], ),
), ),
); );
final RenderBox box1 = key1.currentContext.findRenderObject(); final RenderBox box1 = key1.currentContext.findRenderObject();
@ -81,43 +87,46 @@ void main() {
final GlobalKey key1 = new GlobalKey(); final GlobalKey key1 = new GlobalKey();
final GlobalKey key2 = new GlobalKey(); final GlobalKey key2 = new GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
top: 123.0, children: <Widget>[
left: 456.0, new Positioned(
child: new Transform.rotate( top: 123.0,
angle: 1.0, // radians left: 456.0,
child: new CompositedTransformTarget( child: new Transform.rotate(
link: link, angle: 1.0, // radians
child: new Container(key: key1, height: 10.0, width: 10.0), child: new CompositedTransformTarget(
link: link,
child: new Container(key: key1, height: 10.0, width: 10.0),
),
), ),
), ),
), new Positioned(
new Positioned( top: 787.0,
top: 787.0, left: 343.0,
left: 343.0, child: new Transform.rotate(
child: new Transform.rotate( angle: -0.3, // radians
angle: -0.3, // radians child: new Padding(
child: new Padding( padding: const EdgeInsets.all(20.0),
padding: const EdgeInsets.all(20.0), child: new CompositedTransformFollower(
child: new CompositedTransformFollower( link: new LayerLink(),
link: new LayerLink(), child: new Transform(
child: new Transform( transform: new Matrix4.skew(0.9, 1.1),
transform: new Matrix4.skew(0.9, 1.1), child: new Padding(
child: new Padding( padding: const EdgeInsets.all(20.0),
padding: const EdgeInsets.all(20.0), child: new CompositedTransformFollower(
child: new CompositedTransformFollower( link: link,
link: link, child: new Container(key: key2, height: 10.0, width: 10.0),
child: new Container(key: key2, height: 10.0, width: 10.0), ),
), ),
), ),
), ),
), ),
), ),
), ),
), ],
], ),
), ),
); );
final RenderBox box1 = key1.currentContext.findRenderObject(); final RenderBox box1 = key1.currentContext.findRenderObject();
@ -135,26 +144,29 @@ void main() {
final GlobalKey key3 = new GlobalKey(); final GlobalKey key3 = new GlobalKey();
bool _tapped = false; bool _tapped = false;
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
left: 123.0, children: <Widget>[
top: 456.0, new Positioned(
child: new CompositedTransformTarget( left: 123.0,
top: 456.0,
child: new CompositedTransformTarget(
link: link,
child: new Container(key: key1, height: 10.0, width: 10.0),
),
),
new CompositedTransformFollower(
link: link, link: link,
child: new Container(key: key1, height: 10.0, width: 10.0), child: new GestureDetector(
key: key2,
behavior: HitTestBehavior.opaque,
onTap: () { _tapped = true; },
child: new Container(key: key3, height: 10.0, width: 10.0),
),
), ),
), ],
new CompositedTransformFollower( ),
link: link,
child: new GestureDetector(
key: key2,
behavior: HitTestBehavior.opaque,
onTap: () { _tapped = true; },
child: new Container(key: key3, height: 10.0, width: 10.0),
),
),
],
), ),
); );
final RenderBox box2 = key2.currentContext.findRenderObject(); final RenderBox box2 = key2.currentContext.findRenderObject();

View File

@ -13,6 +13,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 100.0, top: 100.0,
@ -20,8 +21,8 @@ void main() {
child: new SizedBox( child: new SizedBox(
key: keyA, key: keyA,
width: 10.0, width: 10.0,
height: 10.0 height: 10.0,
) ),
), ),
new Positioned( new Positioned(
left: 100.0, left: 100.0,
@ -29,11 +30,11 @@ void main() {
child: new SizedBox( child: new SizedBox(
key: keyB, key: keyB,
width: 20.0, width: 20.0,
height: 10.0 height: 10.0,
) ),
), ),
] ],
) ),
); );
final RenderBox boxA = tester.renderObject(find.byKey(keyA)); final RenderBox boxA = tester.renderObject(find.byKey(keyA));

View File

@ -25,10 +25,10 @@ void main() {
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -77,7 +77,7 @@ void main() {
const Draggable<int>( const Draggable<int>(
data: 1, data: 1,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new Stack( new Stack(
children: <Widget>[ children: <Widget>[
@ -86,22 +86,22 @@ void main() {
onTap: () { onTap: () {
events.add('tap'); events.add('tap');
}, },
child: new Container(child: const Text('Button') child: new Container(child: const Text('Button'),
) ),
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new IgnorePointer( return new IgnorePointer(
child: new Container(child: const Text('Target')) child: new Container(child: const Text('Target')),
); );
}, },
onAccept: (int data) { onAccept: (int data) {
events.add('drop'); events.add('drop');
}), }),
] ],
), ),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -171,9 +171,9 @@ void main() {
onTap: () { onTap: () {
events.add('tap'); events.add('tap');
}, },
child: new Container(child: const Text('Button')) child: new Container(child: const Text('Button')),
), ),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
@ -181,10 +181,10 @@ void main() {
}, },
onAccept: (int data) { onAccept: (int data) {
events.add('drop'); events.add('drop');
} },
), ),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -221,7 +221,7 @@ void main() {
const LongPressDraggable<int>( const LongPressDraggable<int>(
data: 1, data: 1,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
@ -229,10 +229,10 @@ void main() {
}, },
onAccept: (int data) { onAccept: (int data) {
events.add('drop'); events.add('drop');
} },
), ),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -267,7 +267,7 @@ void main() {
const Draggable<int>( const Draggable<int>(
data: 1, data: 1,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
@ -275,10 +275,10 @@ void main() {
}, },
onAccept: (int data) { onAccept: (int data) {
events.add('drop'); events.add('drop');
} },
), ),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -337,8 +337,8 @@ void main() {
new Container(height: 500.0), new Container(height: 500.0),
new Container(height: 500.0), new Container(height: 500.0),
new Container(height: 500.0), new Container(height: 500.0),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -444,8 +444,8 @@ void main() {
new Container(width: 500.0), new Container(width: 500.0),
new Container(width: 500.0), new Container(width: 500.0),
new Container(width: 500.0), new Container(width: 500.0),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -537,10 +537,10 @@ void main() {
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -596,7 +596,7 @@ void main() {
onDraggableCanceledCalled = true; onDraggableCanceledCalled = true;
onDraggableCanceledVelocity = velocity; onDraggableCanceledVelocity = velocity;
onDraggableCanceledOffset = offset; onDraggableCanceledOffset = offset;
} },
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
@ -605,10 +605,10 @@ void main() {
child: const Text('Target') child: const Text('Target')
); );
}, },
onWillAccept: (int data) => false onWillAccept: (int data) => false,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -665,18 +665,18 @@ void main() {
onDraggableCanceledCalled = true; onDraggableCanceledCalled = true;
onDraggableCanceledVelocity = velocity; onDraggableCanceledVelocity = velocity;
onDraggableCanceledOffset = offset; onDraggableCanceledOffset = offset;
} },
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container( return new Container(
height: 100.0, height: 100.0,
child: const Text('Target') child: const Text('Target'),
); );
}, },
onWillAccept: (int data) => false), onWillAccept: (int data) => false),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -712,19 +712,19 @@ void main() {
feedback: const Text('Dragging'), feedback: const Text('Dragging'),
onDragCompleted: () { onDragCompleted: () {
onDragCompletedCalled = true; onDragCompletedCalled = true;
} },
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container( return new Container(
height: 100.0, height: 100.0,
child: const Text('Target') child: const Text('Target'),
); );
}, },
onWillAccept: (int data) => false onWillAccept: (int data) => false,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -776,16 +776,16 @@ void main() {
feedback: const Text('Dragging'), feedback: const Text('Dragging'),
onDragCompleted: () { onDragCompleted: () {
onDragCompletedCalled = true; onDragCompletedCalled = true;
} },
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -834,12 +834,12 @@ void main() {
const Draggable<int>( const Draggable<int>(
data: 1, data: 1,
child: const Text('IntSource'), child: const Text('IntSource'),
feedback: const Text('IntDragging') feedback: const Text('IntDragging'),
), ),
const Draggable<double>( const Draggable<double>(
data: 1.0, data: 1.0,
child: const Text('DoubleSource'), child: const Text('DoubleSource'),
feedback: const Text('DoubleDragging') feedback: const Text('DoubleDragging'),
), ),
new Stack( new Stack(
children: <Widget>[ children: <Widget>[
@ -848,27 +848,27 @@ void main() {
return new IgnorePointer( return new IgnorePointer(
child: new Container( child: new Container(
height: 100.0, height: 100.0,
child: const Text('Target1') child: const Text('Target1'),
) ),
); );
}, },
onAccept: acceptedInts.add onAccept: acceptedInts.add,
), ),
new DragTarget<double>( new DragTarget<double>(
builder: (BuildContext context, List<double> data, List<dynamic> rejects) { builder: (BuildContext context, List<double> data, List<dynamic> rejects) {
return new IgnorePointer( return new IgnorePointer(
child: new Container( child: new Container(
height: 100.0, height: 100.0,
child: const Text('Target2') child: const Text('Target2'),
) ),
); );
}, },
onAccept: acceptedDoubles.add onAccept: acceptedDoubles.add,
), ),
] ],
) ),
] ],
) ),
)); ));
expect(acceptedInts, isEmpty); expect(acceptedInts, isEmpty);
@ -947,7 +947,7 @@ void main() {
new Draggable<DragTargetData>( new Draggable<DragTargetData>(
data: dragTargetData, data: dragTargetData,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new Stack( new Stack(
children: <Widget>[ children: <Widget>[
@ -956,26 +956,26 @@ void main() {
return new IgnorePointer( return new IgnorePointer(
child: new Container( child: new Container(
height: 100.0, height: 100.0,
child: const Text('Target1') child: const Text('Target1'),
) ),
); );
}, onAccept: acceptedDragTargetDatas.add }, onAccept: acceptedDragTargetDatas.add,
), ),
new DragTarget<ExtendedDragTargetData>( new DragTarget<ExtendedDragTargetData>(
builder: (BuildContext context, List<ExtendedDragTargetData> data, List<dynamic> rejects) { builder: (BuildContext context, List<ExtendedDragTargetData> data, List<dynamic> rejects) {
return new IgnorePointer( return new IgnorePointer(
child: new Container( child: new Container(
height: 100.0, height: 100.0,
child: const Text('Target2') child: const Text('Target2'),
) ),
); );
}, },
onAccept: acceptedExtendedDragTargetDatas.add onAccept: acceptedExtendedDragTargetDatas.add,
), ),
] ],
) ),
] ],
) ),
)); ));
final Offset dragTargetLocation = tester.getCenter(find.text('Source')); final Offset dragTargetLocation = tester.getCenter(find.text('Source'));
@ -1008,16 +1008,16 @@ void main() {
data: 1, data: 1,
maxSimultaneousDrags: maxSimultaneousDrags, maxSimultaneousDrags: maxSimultaneousDrags,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging'),
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
); );
} }
@ -1109,27 +1109,32 @@ void main() {
testWidgets('Draggable disposes recognizer', (WidgetTester tester) async { testWidgets('Draggable disposes recognizer', (WidgetTester tester) async {
bool didTap = false; bool didTap = false;
await tester.pumpWidget(new Overlay( await tester.pumpWidget(
initialEntries: <OverlayEntry>[ new Directionality(
new OverlayEntry( textDirection: TextDirection.ltr,
builder: (BuildContext context) => new GestureDetector( child: new Overlay(
onTap: () { initialEntries: <OverlayEntry>[
didTap = true; new OverlayEntry(
}, builder: (BuildContext context) => new GestureDetector(
child: new Draggable<dynamic>( onTap: () {
child: new Container( didTap = true;
color: const Color(0xFFFFFF00), },
child: new Draggable<dynamic>(
child: new Container(
color: const Color(0xFFFFFF00),
),
feedback: new Container(
width: 100.0,
height: 100.0,
color: const Color(0xFFFF0000),
),
),
), ),
feedback: new Container( ),
width: 100.0, ],
height: 100.0, ),
color: const Color(0xFFFF0000), ),
) );
)
)
)
]
));
await tester.startGesture(const Offset(10.0, 10.0)); await tester.startGesture(const Offset(10.0, 10.0));
expect(didTap, isFalse); expect(didTap, isFalse);
@ -1142,25 +1147,30 @@ void main() {
// Regression test for https://github.com/flutter/flutter/issues/6128. // Regression test for https://github.com/flutter/flutter/issues/6128.
testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async { testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async {
await tester.pumpWidget(new Overlay( await tester.pumpWidget(
initialEntries: <OverlayEntry>[ new Directionality(
new OverlayEntry( textDirection: TextDirection.ltr,
builder: (BuildContext context) => new GestureDetector( child: new Overlay(
onTap: () { /* registers a tap recognizer */ }, initialEntries: <OverlayEntry>[
child: new Draggable<dynamic>( new OverlayEntry(
child: new Container( builder: (BuildContext context) => new GestureDetector(
color: const Color(0xFFFFFF00), onTap: () { /* registers a tap recognizer */ },
child: new Draggable<dynamic>(
child: new Container(
color: const Color(0xFFFFFF00),
),
feedback: new Container(
width: 100.0,
height: 100.0,
color: const Color(0xFFFF0000),
),
),
), ),
feedback: new Container( ),
width: 100.0, ],
height: 100.0, ),
color: const Color(0xFFFF0000), ),
) );
)
)
)
]
));
final TestGesture firstGesture = await tester.startGesture(const Offset(10.0, 10.0), pointer: 24); final TestGesture firstGesture = await tester.startGesture(const Offset(10.0, 10.0), pointer: 24);
final TestGesture secondGesture = await tester.startGesture(const Offset(10.0, 20.0), pointer: 25); final TestGesture secondGesture = await tester.startGesture(const Offset(10.0, 20.0), pointer: 25);
@ -1187,10 +1197,10 @@ void main() {
}, },
onAccept: (int data) { onAccept: (int data) {
events.add('drop'); events.add('drop');
} },
), ),
] ],
) ),
)); ));
expect(events, isEmpty); expect(events, isEmpty);
@ -1232,21 +1242,21 @@ void main() {
final List<int> accepted = <int>[]; final List<int> accepted = <int>[];
await tester.pumpWidget(new MaterialApp( await tester.pumpWidget(new MaterialApp(
home: new Column( home: new Column(
children: <Widget>[ children: <Widget>[
const Draggable<int>( const Draggable<int>(
data: 1, data: 1,
child: const Text('Source'), child: const Text('Source'),
feedback: const Text('Dragging') feedback: const Text('Dragging')
), ),
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -1264,16 +1274,16 @@ void main() {
expect(find.text('Target'), findsOneWidget); expect(find.text('Target'), findsOneWidget);
await tester.pumpWidget(new MaterialApp( await tester.pumpWidget(new MaterialApp(
home: new Column( home: new Column(
children: <Widget>[ children: <Widget>[
new DragTarget<int>( new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target')); return new Container(height: 100.0, child: const Text('Target'));
}, },
onAccept: accepted.add onAccept: accepted.add,
), ),
] ],
) ),
)); ));
expect(accepted, isEmpty); expect(accepted, isEmpty);
@ -1336,34 +1346,39 @@ Future<Null> _testChildAnchorFeedbackPosition({WidgetTester tester, double top:
final List<int> accepted = <int>[]; final List<int> accepted = <int>[];
int dragStartedCount = 0; int dragStartedCount = 0;
await tester.pumpWidget(new Stack(children: <Widget>[ await tester.pumpWidget(
new Positioned( new Stack(
left: left, textDirection: TextDirection.ltr,
top: top, children: <Widget>[
right: 0.0, new Positioned(
bottom: 0.0, left: left,
child: new MaterialApp( top: top,
home: new Column( right: 0.0,
children: <Widget>[ bottom: 0.0,
new Draggable<int>( child: new MaterialApp(
data: 1, home: new Column(
child: const Text('Source'), children: <Widget>[
feedback: const Text('Dragging'), new Draggable<int>(
onDragStarted: () { data: 1,
++dragStartedCount; child: const Text('Source'),
}, feedback: const Text('Dragging'),
onDragStarted: () {
++dragStartedCount;
},
),
new DragTarget<int>(
builder: (BuildContext context, List<int> data, List<dynamic> rejects) {
return new Container(height: 100.0, child: const Text('Target'));
},
onAccept: accepted.add,
),
],
), ),
new DragTarget<int>( ),
builder: (BuildContext context, List<int> data, List<dynamic> rejects) { ),
return new Container(height: 100.0, child: const Text('Target')); ],
}, ),
onAccept: accepted.add );
),
]
)
)
)
]));
expect(accepted, isEmpty); expect(accepted, isEmpty);
expect(find.text('Source'), findsOneWidget); expect(find.text('Source'), findsOneWidget);

View File

@ -10,32 +10,35 @@ void main() {
testWidgets('Can hit test flex children of stacks', (WidgetTester tester) async { testWidgets('Can hit test flex children of stacks', (WidgetTester tester) async {
bool didReceiveTap = false; bool didReceiveTap = false;
await tester.pumpWidget( await tester.pumpWidget(
new Container( new Directionality(
color: const Color(0xFF00FF00), textDirection: TextDirection.ltr,
child: new Stack( child: new Container(
children: <Widget>[ color: const Color(0xFF00FF00),
new Positioned( child: new Stack(
top: 10.0, children: <Widget>[
left: 10.0, new Positioned(
child: new Column( top: 10.0,
children: <Widget>[ left: 10.0,
new GestureDetector( child: new Column(
onTap: () { children: <Widget>[
didReceiveTap = true; new GestureDetector(
}, onTap: () {
child: new Container( didReceiveTap = true;
color: const Color(0xFF0000FF), },
width: 100.0, child: new Container(
height: 100.0, color: const Color(0xFF0000FF),
child: const Center( width: 100.0,
child: const Text('X', textDirection: TextDirection.ltr), height: 100.0,
child: const Center(
child: const Text('X', textDirection: TextDirection.ltr),
),
), ),
), ),
), ],
], ),
), ),
), ],
], ),
), ),
), ),
); );

View File

@ -47,6 +47,7 @@ void main() {
testWidgets('GlobalKey duplication 1 - double appearance', (WidgetTester tester) async { testWidgets('GlobalKey duplication 1 - double appearance', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
key: const ValueKey<int>(1), key: const ValueKey<int>(1),
@ -65,6 +66,7 @@ void main() {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
key: const ValueKey<int>(1), key: const ValueKey<int>(1),
@ -79,6 +81,7 @@ void main() {
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
key: const ValueKey<int>(1), key: const ValueKey<int>(1),
@ -97,11 +100,13 @@ void main() {
testWidgets('GlobalKey duplication 3 - splitting and changing type', (WidgetTester tester) async { testWidgets('GlobalKey duplication 3 - splitting and changing type', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new SizedBox(key: key), new SizedBox(key: key),
new Placeholder(key: key), new Placeholder(key: key),
@ -113,11 +118,13 @@ void main() {
testWidgets('GlobalKey duplication 4 - splitting and half changing type', (WidgetTester tester) async { testWidgets('GlobalKey duplication 4 - splitting and half changing type', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Placeholder(key: key), new Placeholder(key: key),
@ -129,11 +136,13 @@ void main() {
testWidgets('GlobalKey duplication 5 - splitting and half changing type', (WidgetTester tester) async { testWidgets('GlobalKey duplication 5 - splitting and half changing type', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Placeholder(key: key), new Placeholder(key: key),
new Container(key: key), new Container(key: key),
@ -145,11 +154,13 @@ void main() {
testWidgets('GlobalKey duplication 6 - splitting and not changing type', (WidgetTester tester) async { testWidgets('GlobalKey duplication 6 - splitting and not changing type', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Container(key: key), new Container(key: key),
@ -161,12 +172,14 @@ void main() {
testWidgets('GlobalKey duplication 7 - appearing later', (WidgetTester tester) async { testWidgets('GlobalKey duplication 7 - appearing later', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
new Container(key: const ValueKey<int>(2)), new Container(key: const ValueKey<int>(2)),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
new Container(key: const ValueKey<int>(2), child: new Container(key: key)), new Container(key: const ValueKey<int>(2), child: new Container(key: key)),
@ -178,12 +191,14 @@ void main() {
testWidgets('GlobalKey duplication 8 - appearing earlier', (WidgetTester tester) async { testWidgets('GlobalKey duplication 8 - appearing earlier', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1)), new Container(key: const ValueKey<int>(1)),
new Container(key: const ValueKey<int>(2), child: new Container(key: key)), new Container(key: const ValueKey<int>(2), child: new Container(key: key)),
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
new Container(key: const ValueKey<int>(2), child: new Container(key: key)), new Container(key: const ValueKey<int>(2), child: new Container(key: key)),
@ -195,6 +210,7 @@ void main() {
testWidgets('GlobalKey duplication 9 - moving and appearing later', (WidgetTester tester) async { testWidgets('GlobalKey duplication 9 - moving and appearing later', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0), child: new Container(key: key)), new Container(key: const ValueKey<int>(0), child: new Container(key: key)),
new Container(key: const ValueKey<int>(1)), new Container(key: const ValueKey<int>(1)),
@ -202,6 +218,7 @@ void main() {
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
@ -214,6 +231,7 @@ void main() {
testWidgets('GlobalKey duplication 10 - moving and appearing earlier', (WidgetTester tester) async { testWidgets('GlobalKey duplication 10 - moving and appearing earlier', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1)), new Container(key: const ValueKey<int>(1)),
new Container(key: const ValueKey<int>(2)), new Container(key: const ValueKey<int>(2)),
@ -221,6 +239,7 @@ void main() {
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
new Container(key: const ValueKey<int>(2), child: new Container(key: key)), new Container(key: const ValueKey<int>(2), child: new Container(key: key)),
@ -233,6 +252,7 @@ void main() {
testWidgets('GlobalKey duplication 11 - double sibling appearance', (WidgetTester tester) async { testWidgets('GlobalKey duplication 11 - double sibling appearance', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Container(key: key), new Container(key: key),
@ -246,6 +266,7 @@ void main() {
final Key key2 = new GlobalKey(debugLabel: 'problematic'); // intentionally the same label final Key key2 = new GlobalKey(debugLabel: 'problematic'); // intentionally the same label
final Key key3 = new GlobalKey(debugLabel: 'also problematic'); final Key key3 = new GlobalKey(debugLabel: 'also problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key1), new Container(key: key1),
new Container(key: key1), new Container(key: key1),
@ -284,6 +305,7 @@ void main() {
final Key key2 = new GlobalKey(debugLabel: 'problematic'); // intentionally the same label final Key key2 = new GlobalKey(debugLabel: 'problematic'); // intentionally the same label
final Key key3 = new GlobalKey(debugLabel: 'also problematic'); final Key key3 = new GlobalKey(debugLabel: 'also problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key1), new Container(key: key1),
new Container(key: key2), new Container(key: key2),
@ -291,6 +313,7 @@ void main() {
]), ]),
); );
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key1), new Container(key: key1),
new Container(key: key1), new Container(key: key1),
@ -327,6 +350,7 @@ void main() {
testWidgets('GlobalKey duplication 14 - moving during build - before', (WidgetTester tester) async { testWidgets('GlobalKey duplication 14 - moving during build - before', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
@ -334,6 +358,7 @@ void main() {
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
@ -344,6 +369,7 @@ void main() {
testWidgets('GlobalKey duplication 15 - duplicating during build - before', (WidgetTester tester) async { testWidgets('GlobalKey duplication 15 - duplicating during build - before', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
@ -351,6 +377,7 @@ void main() {
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: key), new Container(key: key),
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
@ -363,6 +390,7 @@ void main() {
testWidgets('GlobalKey duplication 16 - moving during build - after', (WidgetTester tester) async { testWidgets('GlobalKey duplication 16 - moving during build - after', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1)), new Container(key: const ValueKey<int>(1)),
@ -370,6 +398,7 @@ void main() {
], ],
)); ));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),
@ -380,6 +409,7 @@ void main() {
testWidgets('GlobalKey duplication 17 - duplicating during build - after', (WidgetTester tester) async { testWidgets('GlobalKey duplication 17 - duplicating during build - after', (WidgetTester tester) async {
final Key key = new GlobalKey(debugLabel: 'problematic'); final Key key = new GlobalKey(debugLabel: 'problematic');
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1)), new Container(key: const ValueKey<int>(1)),
@ -393,6 +423,7 @@ void main() {
count += 1; count += 1;
}; };
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(key: const ValueKey<int>(0)), new Container(key: const ValueKey<int>(0)),
new Container(key: const ValueKey<int>(1), child: new Container(key: key)), new Container(key: const ValueKey<int>(1), child: new Container(key: key)),

View File

@ -25,7 +25,7 @@ void main() {
}, },
child: new Container( child: new Container(
color: const Color(0xFF00FF00), color: const Color(0xFF00FF00),
) ),
); );
await tester.pumpWidget(widget); await tester.pumpWidget(widget);
@ -70,7 +70,7 @@ void main() {
onHorizontalDragEnd: (DragEndDetails details) { fail('gesture should not match'); }, onHorizontalDragEnd: (DragEndDetails details) { fail('gesture should not match'); },
child: new Container( child: new Container(
color: const Color(0xFF00FF00), color: const Color(0xFF00FF00),
) ),
); );
await tester.pumpWidget(widget); await tester.pumpWidget(widget);
@ -106,8 +106,8 @@ void main() {
}, },
child: new Container( child: new Container(
color: const Color(0xFF00FF00), color: const Color(0xFF00FF00),
) ),
) ),
); );
expect(didStartPan, isFalse); expect(didStartPan, isFalse);
@ -128,30 +128,33 @@ void main() {
Future<Null> pumpWidgetTree(HitTestBehavior behavior) { Future<Null> pumpWidgetTree(HitTestBehavior behavior) {
return tester.pumpWidget( return tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Listener( child: new Stack(
onPointerDown: (_) { children: <Widget>[
didReceivePointerDown = true; new Listener(
}, onPointerDown: (_) {
child: new Container( didReceivePointerDown = true;
},
child: new Container(
width: 100.0,
height: 100.0,
color: const Color(0xFF00FF00),
),
),
new Container(
width: 100.0, width: 100.0,
height: 100.0, height: 100.0,
color: const Color(0xFF00FF00), child: new GestureDetector(
) onTap: () {
), didTap = true;
new Container( },
width: 100.0, behavior: behavior,
height: 100.0, ),
child: new GestureDetector( ),
onTap: () { ],
didTap = true; ),
}, ),
behavior: behavior
)
)
]
)
); );
} }
@ -193,8 +196,8 @@ void main() {
onTap: () { onTap: () {
didTap = true; didTap = true;
}, },
) ),
) ),
); );
expect(didTap, isFalse); expect(didTap, isFalse);
await tester.tapAt(const Offset(10.0, 10.0)); await tester.tapAt(const Offset(10.0, 10.0));
@ -210,8 +213,8 @@ void main() {
didTap = true; didTap = true;
}, },
child: new Container(), child: new Container(),
) ),
) ),
); );
expect(didTap, isFalse); expect(didTap, isFalse);
await tester.tapAt(const Offset(10.0, 10.0)); await tester.tapAt(const Offset(10.0, 10.0));
@ -222,24 +225,24 @@ void main() {
final GestureTapCallback inputCallback = () {}; final GestureTapCallback inputCallback = () {};
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Center(
child: new GestureDetector( child: new GestureDetector(
onTap: inputCallback, onTap: inputCallback,
child: new Container(), child: new Container(),
) ),
) ),
); );
final RenderSemanticsGestureHandler renderObj1 = tester.renderObject(find.byType(GestureDetector)); final RenderSemanticsGestureHandler renderObj1 = tester.renderObject(find.byType(GestureDetector));
final GestureTapCallback actualCallback1 = renderObj1.onTap; final GestureTapCallback actualCallback1 = renderObj1.onTap;
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Center(
child: new GestureDetector( child: new GestureDetector(
onTap: inputCallback, onTap: inputCallback,
child: new Container(), child: new Container(),
) ),
) ),
); );
final RenderSemanticsGestureHandler renderObj2 = tester.renderObject(find.byType(GestureDetector)); final RenderSemanticsGestureHandler renderObj2 = tester.renderObject(find.byType(GestureDetector));

View File

@ -30,6 +30,7 @@ void main() {
testWidgets('ModalBarrier prevents interactions with widgets behind it', (WidgetTester tester) async { testWidgets('ModalBarrier prevents interactions with widgets behind it', (WidgetTester tester) async {
final Widget subject = new Stack( final Widget subject = new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
tapTarget, tapTarget,
const ModalBarrier(dismissible: false), const ModalBarrier(dismissible: false),
@ -45,6 +46,7 @@ void main() {
testWidgets('ModalBarrier does not prevent interactions with widgets in front of it', (WidgetTester tester) async { testWidgets('ModalBarrier does not prevent interactions with widgets in front of it', (WidgetTester tester) async {
final Widget subject = new Stack( final Widget subject = new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
const ModalBarrier(dismissible: false), const ModalBarrier(dismissible: false),
tapTarget, tapTarget,

View File

@ -36,75 +36,81 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new DecoratedBox(decoration: kBoxDecorationB), new DecoratedBox(decoration: kBoxDecorationB),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB), new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB), new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
new DecoratedBox(key: const Key('a'), decoration: kBoxDecorationA), new DecoratedBox(key: const Key('a'), decoration: kBoxDecorationA),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC, kBoxDecorationA]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC, kBoxDecorationA]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(key: const Key('a'), decoration: kBoxDecorationA), new DecoratedBox(key: const Key('a'), decoration: kBoxDecorationA),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB), new DecoratedBox(key: const Key('b'), decoration: kBoxDecorationB),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC, kBoxDecorationB]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC, kBoxDecorationB]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack() new Stack(textDirection: TextDirection.ltr)
); );
checkTree(tester, <BoxDecoration>[]); checkTree(tester, <BoxDecoration>[]);
@ -115,116 +121,123 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new DecoratedBox(decoration: kBoxDecorationB), new DecoratedBox(decoration: kBoxDecorationB),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new Container( new Container(
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB)
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new Container( new Container(
child: new Container( child: new Container(
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
) ),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
child: new Container( child: new Container(
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
) ),
), ),
new Container( new Container(
child: new DecoratedBox(decoration: kBoxDecorationA) child: new DecoratedBox(decoration: kBoxDecorationA),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new Container( new Container(
child: new DecoratedBox(decoration: kBoxDecorationA) child: new DecoratedBox(decoration: kBoxDecorationA),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA, kBoxDecorationC]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
key: const Key('b'), key: const Key('b'),
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new Container( new Container(
key: const Key('a'), key: const Key('a'),
child: new DecoratedBox(decoration: kBoxDecorationA) child: new DecoratedBox(decoration: kBoxDecorationA),
), ),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationA]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
key: const Key('a'), key: const Key('a'),
child: new DecoratedBox(decoration: kBoxDecorationA) child: new DecoratedBox(decoration: kBoxDecorationA),
), ),
new Container( new Container(
key: const Key('b'), key: const Key('b'),
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
), ),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack() new Stack(textDirection: TextDirection.ltr)
); );
checkTree(tester, <BoxDecoration>[]); checkTree(tester, <BoxDecoration>[]);
@ -233,25 +246,27 @@ void main() {
testWidgets('MultiChildRenderObjectElement with stateful widgets', (WidgetTester tester) async { testWidgets('MultiChildRenderObjectElement with stateful widgets', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new DecoratedBox(decoration: kBoxDecorationB), new DecoratedBox(decoration: kBoxDecorationB),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationB]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new FlipWidget( new FlipWidget(
left: new DecoratedBox(decoration: kBoxDecorationA), left: new DecoratedBox(decoration: kBoxDecorationA),
right: new DecoratedBox(decoration: kBoxDecorationB) right: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationA, kBoxDecorationC]);
@ -263,13 +278,14 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new FlipWidget( new FlipWidget(
left: new DecoratedBox(decoration: kBoxDecorationA), left: new DecoratedBox(decoration: kBoxDecorationA),
right: new DecoratedBox(decoration: kBoxDecorationB) right: new DecoratedBox(decoration: kBoxDecorationB),
), ),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB]); checkTree(tester, <BoxDecoration>[kBoxDecorationB]);
@ -281,27 +297,29 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new FlipWidget( new FlipWidget(
key: const Key('flip'), key: const Key('flip'),
left: new DecoratedBox(decoration: kBoxDecorationA), left: new DecoratedBox(decoration: kBoxDecorationA),
right: new DecoratedBox(decoration: kBoxDecorationB) right: new DecoratedBox(decoration: kBoxDecorationB),
), ),
] ],
) ),
); );
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(key: const Key('c'), decoration: kBoxDecorationC), new DecoratedBox(key: const Key('c'), decoration: kBoxDecorationC),
new FlipWidget( new FlipWidget(
key: const Key('flip'), key: const Key('flip'),
left: new DecoratedBox(decoration: kBoxDecorationA), left: new DecoratedBox(decoration: kBoxDecorationA),
right: new DecoratedBox(decoration: kBoxDecorationB) right: new DecoratedBox(decoration: kBoxDecorationB),
), ),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationC, kBoxDecorationA]); checkTree(tester, <BoxDecoration>[kBoxDecorationC, kBoxDecorationA]);
@ -313,15 +331,16 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new FlipWidget( new FlipWidget(
key: const Key('flip'), key: const Key('flip'),
left: new DecoratedBox(decoration: kBoxDecorationA), left: new DecoratedBox(decoration: kBoxDecorationA),
right: new DecoratedBox(decoration: kBoxDecorationB) right: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new DecoratedBox(key: const Key('c'), decoration: kBoxDecorationC), new DecoratedBox(key: const Key('c'), decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]); checkTree(tester, <BoxDecoration>[kBoxDecorationB, kBoxDecorationC]);

View File

@ -10,20 +10,25 @@ void main() {
(WidgetTester tester) async { (WidgetTester tester) async {
final GlobalKey overlayKey = new GlobalKey(); final GlobalKey overlayKey = new GlobalKey();
bool didBuild = false; bool didBuild = false;
await tester.pumpWidget(new Overlay( await tester.pumpWidget(
key: overlayKey, new Directionality(
initialEntries: <OverlayEntry>[ textDirection: TextDirection.ltr,
new OverlayEntry( child: new Overlay(
builder: (BuildContext context) { key: overlayKey,
didBuild = true; initialEntries: <OverlayEntry>[
final Overlay overlay = context.ancestorWidgetOfExactType(Overlay); new OverlayEntry(
expect(overlay, isNotNull); builder: (BuildContext context) {
expect(overlay.key, equals(overlayKey)); didBuild = true;
return new Container(); final Overlay overlay = context.ancestorWidgetOfExactType(Overlay);
}, expect(overlay, isNotNull);
expect(overlay.key, equals(overlayKey));
return new Container();
},
),
],
), ),
], ),
)); );
expect(didBuild, isTrue); expect(didBuild, isTrue);
final RenderObject theater = overlayKey.currentContext.findRenderObject(); final RenderObject theater = overlayKey.currentContext.findRenderObject();
@ -32,25 +37,29 @@ void main() {
theater.toStringDeep(), theater.toStringDeep(),
equalsIgnoringHashCodes( equalsIgnoringHashCodes(
'_RenderTheatre#00000\n' '_RenderTheatre#00000\n'
' │ creator: _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' │ creator: _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
' │ [root]\n'
' │ parentData: <none>\n' ' │ parentData: <none>\n'
' │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' │ size: Size(800.0, 600.0)\n' ' │ size: Size(800.0, 600.0)\n'
'\n' '\n'
' ├─onstage: RenderStack#00000\n' ' ├─onstage: RenderStack#00000\n'
' ╎ │ creator: Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ │ creator: Stack ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' ╎ │ Directionality ← [root]\n'
' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n'
' ╎ │ size)\n' ' ╎ │ size)\n'
' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' ╎ │ size: Size(800.0, 600.0)\n' ' ╎ │ size: Size(800.0, 600.0)\n'
' ╎ │ alignment: FractionalOffset.topLeft\n' ' ╎ │ alignment: FractionalOffsetDirectional.topStart\n'
' ╎ │ textDirection: ltr\n'
' ╎ │ fit: expand\n' ' ╎ │ fit: expand\n'
' ╎ │ overflow: clip\n' ' ╎ │ overflow: clip\n'
' ╎ │\n' ' ╎ │\n'
' ╎ └─child 1: RenderLimitedBox#00000\n' ' ╎ └─child 1: RenderLimitedBox#00000\n'
' ╎ │ creator: LimitedBox ← Container ←\n' ' ╎ │ creator: LimitedBox ← Container ←\n'
' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' ╎ │ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ │ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
' ╎ │ [root]\n'
' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n'
' ╎ │ size)\n' ' ╎ │ size)\n'
' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
@ -61,118 +70,133 @@ void main() {
' ╎ └─child: RenderConstrainedBox#00000\n' ' ╎ └─child: RenderConstrainedBox#00000\n'
' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n' ' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n'
' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' ╎ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
' ╎ [root]\n'
' ╎ parentData: <none> (can use size)\n' ' ╎ parentData: <none> (can use size)\n'
' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' ╎ size: Size(800.0, 600.0)\n' ' ╎ size: Size(800.0, 600.0)\n'
' ╎ additionalConstraints: BoxConstraints(biggest)\n' ' ╎ additionalConstraints: BoxConstraints(biggest)\n'
'\n' '\n'
' └╌no offstage children\n', ' └╌no offstage children\n'
), ),
); );
}); });
testWidgets('Offstage overlay', (WidgetTester tester) async { testWidgets('Offstage overlay', (WidgetTester tester) async {
final GlobalKey overlayKey = new GlobalKey(); final GlobalKey overlayKey = new GlobalKey();
await tester.pumpWidget(new Overlay( await tester.pumpWidget(
key: overlayKey, new Directionality(
initialEntries: <OverlayEntry>[ textDirection: TextDirection.ltr,
new OverlayEntry( child: new Overlay(
opaque: true, key: overlayKey,
maintainState: true, initialEntries: <OverlayEntry>[
builder: (BuildContext context) => new Container(), new OverlayEntry(
opaque: true,
maintainState: true,
builder: (BuildContext context) => new Container(),
),
new OverlayEntry(
opaque: true,
maintainState: true,
builder: (BuildContext context) => new Container(),
),
new OverlayEntry(
opaque: true,
maintainState: true,
builder: (BuildContext context) => new Container(),
),
],
), ),
new OverlayEntry( ),
opaque: true, );
maintainState: true,
builder: (BuildContext context) => new Container(),
),
new OverlayEntry(
opaque: true,
maintainState: true,
builder: (BuildContext context) => new Container(),
),
],
));
final RenderObject theater = overlayKey.currentContext.findRenderObject(); final RenderObject theater = overlayKey.currentContext.findRenderObject();
expect(theater, hasAGoodToStringDeep); expect(theater, hasAGoodToStringDeep);
expect( expect(
theater.toStringDeep(), theater.toStringDeep(),
equalsIgnoringHashCodes( equalsIgnoringHashCodes(
'_RenderTheatre#00000\n' '_RenderTheatre#00000\n'
' │ creator: _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' │ creator: _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
' │ parentData: <none>\n' ' │ [root]\n'
' │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' │ parentData: <none>\n'
' │ size: Size(800.0, 600.0)\n' ' │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
'\n' ' │ size: Size(800.0, 600.0)\n'
' ├─onstage: RenderStack#00000\n' '\n'
' ╎ │ creator: Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ├─onstage: RenderStack#00000\n'
' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' ' ╎ │ creator: Stack ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' ╎ │ size)\n' ' ╎ │ Directionality ← [root]\n'
' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n'
' ╎ │ size: Size(800.0, 600.0)\n' ' ╎ │ size)\n'
' ╎ │ alignment: FractionalOffset.topLeft\n' ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' ╎ │ fit: expand\n' ' ╎ │ size: Size(800.0, 600.0)\n'
' ╎ │ overflow: clip\n' ' ╎ │ alignment: FractionalOffsetDirectional.topStart\n'
' ╎ │\n' ' ╎ │ textDirection: ltr\n'
' ╎ └─child 1: RenderLimitedBox#00000\n' ' ╎ │ fit: expand\n'
' ╎ │ creator: LimitedBox ← Container ←\n' ' ╎ │ overflow: clip\n'
' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ │\n'
' ╎ │ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ └─child 1: RenderLimitedBox#00000\n'
' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n' ' ╎ │ creator: LimitedBox ← Container ←\n'
' ╎ │ size)\n' ' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ │ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
' ╎ │ size: Size(800.0, 600.0)\n' ' ╎ │ [root]\n'
' ╎ │ maxWidth: 0.0\n' ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0) (can use\n'
' ╎ │ maxHeight: 0.0\n' ' ╎ │ size)\n'
' ╎ │\n' ' ╎ │ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' ╎ └─child: RenderConstrainedBox#00000\n' ' ╎ │ size: Size(800.0, 600.0)\n'
' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n' ' ╎ │ maxWidth: 0.0\n'
' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ │ maxHeight: 0.0\n'
' ╎ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ │\n'
' ╎ parentData: <none> (can use size)\n' ' ╎ └─child: RenderConstrainedBox#00000\n'
' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n' ' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n'
' ╎ size: Size(800.0, 600.0)\n' ' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' ╎ additionalConstraints: BoxConstraints(biggest)\n' ' ╎ Stack ← _Theatre ← Overlay-[GlobalKey#00000] ← Directionality ←\n'
'\n' ' ╎ [root]\n'
' ╎╌offstage 1: RenderLimitedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n' ' ╎ parentData: <none> (can use size)\n'
' ╎ │ creator: LimitedBox ← Container ←\n' ' ╎ constraints: BoxConstraints(w=800.0, h=600.0)\n'
' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ size: Size(800.0, 600.0)\n'
' ╎ │ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ additionalConstraints: BoxConstraints(biggest)\n'
' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0)\n' '\n'
' ╎ │ constraints: MISSING\n' ' ╎╌offstage 1: RenderLimitedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n'
' ╎ │ size: MISSING\n' ' ╎ │ creator: LimitedBox ← Container ←\n'
' ╎ │ maxWidth: 0.0\n' ' ╎ │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' ╎ │ maxHeight: 0.0\n' ' ╎ │ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' ╎ │\n' ' ╎ │ Directionality ← [root]\n'
' ╎ └─child: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n' ' ╎ │ parentData: not positioned; offset=Offset(0.0, 0.0)\n'
' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n' ' ╎ │ constraints: MISSING\n'
' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ │ size: MISSING\n'
' ╎ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ │ maxWidth: 0.0\n'
' ╎ parentData: <none>\n' ' ╎ │ maxHeight: 0.0\n'
' ╎ constraints: MISSING\n' ' ╎ │\n'
' ╎ size: MISSING\n' ' ╎ └─child: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n'
' ╎ additionalConstraints: BoxConstraints(biggest)\n' ' ╎ creator: ConstrainedBox ← LimitedBox ← Container ←\n'
'\n' ' ╎ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' └╌offstage 2: RenderLimitedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n' ' ╎ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' │ creator: LimitedBox ← Container ←\n' ' ╎ Directionality ← [root]\n'
' │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' ╎ parentData: <none>\n'
' │ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' ╎ constraints: MISSING\n'
' │ parentData: not positioned; offset=Offset(0.0, 0.0)\n' ' ╎ size: MISSING\n'
' │ constraints: MISSING\n' ' ╎ additionalConstraints: BoxConstraints(biggest)\n'
' │ size: MISSING\n' '\n'
' │ maxWidth: 0.0\n' ' └╌offstage 2: RenderLimitedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n'
' │ maxHeight: 0.0\n' ' │ creator: LimitedBox ← Container ←\n'
'\n' ' │ _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' └─child: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n' ' │ TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' creator: ConstrainedBox ← LimitedBox ← Container ←\n' ' │ Directionality ← [root]\n'
' _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n' ' │ parentData: not positioned; offset=Offset(0.0, 0.0)\n'
' TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ← [root]\n' ' │ constraints: MISSING\n'
' parentData: <none>\n' ' │ size: MISSING\n'
' constraints: MISSING\n' ' │ maxWidth: 0.0\n'
' size: MISSING\n' ' │ maxHeight: 0.0\n'
' additionalConstraints: BoxConstraints(biggest)\n' '\n'
' └─child: RenderConstrainedBox#00000 NEEDS-LAYOUT NEEDS-PAINT\n'
' creator: ConstrainedBox ← LimitedBox ← Container ←\n'
' _OverlayEntry-[LabeledGlobalKey<_OverlayEntryState>#00000] ←\n'
' TickerMode ← _Theatre ← Overlay-[GlobalKey#00000] ←\n'
' Directionality ← [root]\n'
' parentData: <none>\n'
' constraints: MISSING\n'
' size: MISSING\n'
' additionalConstraints: BoxConstraints(biggest)\n'
), ),
); );
}); });

View File

@ -52,16 +52,17 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new DecoratedBox(decoration: kBoxDecorationA), new DecoratedBox(decoration: kBoxDecorationA),
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -72,20 +73,21 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
bottom: 5.0, bottom: 5.0,
right: 7.0, right: 7.0,
child: new DecoratedBox(decoration: kBoxDecorationA) child: new DecoratedBox(decoration: kBoxDecorationA),
), ),
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
), ),
new DecoratedBox(decoration: kBoxDecorationC), new DecoratedBox(decoration: kBoxDecorationC),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -100,20 +102,21 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
bottom: 5.0, bottom: 5.0,
right: 7.0, right: 7.0,
child: kDecoratedBoxA child: kDecoratedBoxA,
), ),
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: kDecoratedBoxB child: kDecoratedBoxB,
), ),
kDecoratedBoxC, kDecoratedBoxC,
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -124,20 +127,21 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
bottom: 6.0, bottom: 6.0,
right: 8.0, right: 8.0,
child: kDecoratedBoxA child: kDecoratedBoxA,
), ),
new Positioned( new Positioned(
left: 10.0, left: 10.0,
right: 10.0, right: 10.0,
child: kDecoratedBoxB child: kDecoratedBoxB,
), ),
kDecoratedBoxC, kDecoratedBoxC,
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -148,16 +152,17 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
kDecoratedBoxA, kDecoratedBoxA,
new Positioned( new Positioned(
left: 11.0, left: 11.0,
right: 12.0, right: 12.0,
child: new Container(child: kDecoratedBoxB) child: new Container(child: kDecoratedBoxB),
), ),
kDecoratedBoxC, kDecoratedBoxC,
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -168,20 +173,21 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
kDecoratedBoxA, kDecoratedBoxA,
new Positioned( new Positioned(
right: 10.0, right: 10.0,
child: new Container(child: kDecoratedBoxB) child: new Container(child: kDecoratedBoxB),
), ),
new Container( new Container(
child: new Positioned( child: new Positioned(
top: 8.0, top: 8.0,
child: kDecoratedBoxC child: kDecoratedBoxC,
) ),
) ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -192,13 +198,14 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
right: 10.0, right: 10.0,
child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB) child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB),
), ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -214,13 +221,14 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 7.0, top: 7.0,
child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB) child: new FlipWidget(left: kDecoratedBoxA, right: kDecoratedBoxB),
), ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -235,7 +243,7 @@ void main() {
]); ]);
await tester.pumpWidget( await tester.pumpWidget(
new Stack() new Stack(textDirection: TextDirection.ltr)
); );
checkTree(tester, <TestParentData>[]); checkTree(tester, <TestParentData>[]);
@ -244,6 +252,7 @@ void main() {
testWidgets('ParentDataWidget conflicting data', (WidgetTester tester) async { testWidgets('ParentDataWidget conflicting data', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 5.0, top: 5.0,
@ -251,15 +260,15 @@ void main() {
child: new Positioned( child: new Positioned(
top: 6.0, top: 6.0,
left: 7.0, left: 7.0,
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
) ),
) ),
] ],
) ),
); );
expect(tester.takeException(), isFlutterError); expect(tester.takeException(), isFlutterError);
await tester.pumpWidget(new Stack()); await tester.pumpWidget(new Stack(textDirection: TextDirection.ltr));
checkTree(tester, <TestParentData>[]); checkTree(tester, <TestParentData>[]);
@ -270,16 +279,16 @@ void main() {
new Positioned( new Positioned(
top: 6.0, top: 6.0,
left: 7.0, left: 7.0,
child: new DecoratedBox(decoration: kBoxDecorationB) child: new DecoratedBox(decoration: kBoxDecorationB),
) ),
] ],
) ),
) ),
); );
expect(tester.takeException(), isFlutterError); expect(tester.takeException(), isFlutterError);
await tester.pumpWidget( await tester.pumpWidget(
new Stack() new Stack(textDirection: TextDirection.ltr)
); );
checkTree(tester, <TestParentData>[]); checkTree(tester, <TestParentData>[]);
@ -290,14 +299,15 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: new DecoratedBox(key: key, decoration: kBoxDecorationA) child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
) ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -306,17 +316,18 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: new DecoratedBox( child: new DecoratedBox(
decoration: kBoxDecorationB, decoration: kBoxDecorationB,
child: new DecoratedBox(key: key, decoration: kBoxDecorationA) child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
) ),
) ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -325,14 +336,15 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
top: 10.0, top: 10.0,
left: 10.0, left: 10.0,
child: new DecoratedBox(key: key, decoration: kBoxDecorationA) child: new DecoratedBox(key: key, decoration: kBoxDecorationA),
) ),
] ],
) ),
); );
checkTree(tester, <TestParentData>[ checkTree(tester, <TestParentData>[
@ -344,6 +356,7 @@ void main() {
await tester.pumpWidget(new Row( await tester.pumpWidget(new Row(
children: <Widget>[ children: <Widget>[
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Expanded( new Expanded(
child: new Container() child: new Container()

View File

@ -13,11 +13,11 @@ void main() {
expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 600.0)); expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 600.0));
await tester.pumpWidget(const Center(child: const Placeholder())); await tester.pumpWidget(const Center(child: const Placeholder()));
expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 600.0)); expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 600.0));
await tester.pumpWidget(new Stack(children: <Widget>[const Positioned(top: 0.0, bottom: 0.0, child: const Placeholder())])); await tester.pumpWidget(new Stack(textDirection: TextDirection.ltr, children: <Widget>[const Positioned(top: 0.0, bottom: 0.0, child: const Placeholder())]));
expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(400.0, 600.0)); expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(400.0, 600.0));
await tester.pumpWidget(new Stack(children: <Widget>[const Positioned(left: 0.0, right: 0.0, child: const Placeholder())])); await tester.pumpWidget(new Stack(textDirection: TextDirection.ltr, children: <Widget>[const Positioned(left: 0.0, right: 0.0, child: const Placeholder())]));
expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 400.0)); expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(800.0, 400.0));
await tester.pumpWidget(new Stack(children: <Widget>[const Positioned(top: 0.0, child: const Placeholder(fallbackWidth: 200.0, fallbackHeight: 300.0))])); await tester.pumpWidget(new Stack(textDirection: TextDirection.ltr, children: <Widget>[const Positioned(top: 0.0, child: const Placeholder(fallbackWidth: 200.0, fallbackHeight: 300.0))]));
expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(200.0, 300.0)); expect(tester.renderObject<RenderBox>(find.byType(Placeholder)).size, const Size(200.0, 300.0));
}); });

View File

@ -60,11 +60,11 @@ void main() {
final RelativeRectTween rect = new RelativeRectTween( final RelativeRectTween rect = new RelativeRectTween(
begin: new RelativeRect.fromRect( begin: new RelativeRect.fromRect(
new Rect.fromLTRB(10.0, 20.0, 20.0, 30.0), new Rect.fromLTRB(10.0, 20.0, 20.0, 30.0),
new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0) new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0),
), ),
end: new RelativeRect.fromRect( end: new RelativeRect.fromRect(
new Rect.fromLTRB(80.0, 90.0, 90.0, 100.0), new Rect.fromLTRB(80.0, 90.0, 90.0, 100.0),
new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0) new Rect.fromLTRB(0.0, 10.0, 100.0, 110.0),
) )
); );
final AnimationController controller = new AnimationController( final AnimationController controller = new AnimationController(
@ -83,22 +83,25 @@ void main() {
} }
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new Container( textDirection: TextDirection.ltr,
height: 100.0, child: new Center(
width: 100.0, child: new Container(
child: new Stack( height: 100.0,
children: <Widget>[ width: 100.0,
new PositionedTransition( child: new Stack(
rect: rect.animate(controller), children: <Widget>[
child: new Container( new PositionedTransition(
key: key rect: rect.animate(controller),
) child: new Container(
) key: key,
] ),
) ),
) ],
) ),
),
),
),
); // t=0 ); // t=0
recordMetrics(); recordMetrics();
final Completer<Null> completer = new Completer<Null>(); final Completer<Null> completer = new Completer<Null>();

View File

@ -38,7 +38,8 @@ class OrderSwitcherState extends State<OrderSwitcher> {
children.add(widget.a); children.add(widget.a);
} }
return new Stack( return new Stack(
children: children textDirection: TextDirection.ltr,
children: children,
); );
} }
} }

View File

@ -56,6 +56,7 @@ void main() {
final StateMarker grandchild = const StateMarker(); final StateMarker grandchild = const StateMarker();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
child: new StateMarker(key: left) child: new StateMarker(key: left)
@ -82,6 +83,7 @@ void main() {
final StateMarker newGrandchild = const StateMarker(); final StateMarker newGrandchild = const StateMarker();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container( new Container(
child: new StateMarker( child: new StateMarker(
@ -129,6 +131,7 @@ void main() {
final StateMarker grandchild = const StateMarker(); final StateMarker grandchild = const StateMarker();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new StateMarker(key: left), new StateMarker(key: left),
new StateMarker( new StateMarker(
@ -151,6 +154,7 @@ void main() {
final StateMarker newGrandchild = const StateMarker(); final StateMarker newGrandchild = const StateMarker();
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new StateMarker( new StateMarker(
key: right, key: right,
@ -224,6 +228,7 @@ void main() {
final GlobalKey key = new GlobalKey(); final GlobalKey key = new GlobalKey();
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new StateMarker(key: key), new StateMarker(key: key),
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
@ -234,6 +239,7 @@ void main() {
keyState.marker = "marked"; keyState.marker = "marked";
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
new StateMarker(key: key), new StateMarker(key: key),
@ -244,6 +250,7 @@ void main() {
expect(keyState.marker, equals("marked")); expect(keyState.marker, equals("marked"));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new StateMarker(key: key), new StateMarker(key: key),
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
@ -258,6 +265,7 @@ void main() {
final GlobalKey key = new GlobalKey(); final GlobalKey key = new GlobalKey();
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
new StateMarker(key: key), new StateMarker(key: key),
@ -269,6 +277,7 @@ void main() {
keyState.marker = "marked"; keyState.marker = "marked";
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)), new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)),
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
@ -279,6 +288,7 @@ void main() {
expect(keyState.marker, equals("marked")); expect(keyState.marker, equals("marked"));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
new StateMarker(key: key), new StateMarker(key: key),
@ -290,6 +300,7 @@ void main() {
expect(keyState.marker, equals("marked")); expect(keyState.marker, equals("marked"));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)), new Container(width: 100.0, height: 100.0, child: new StateMarker(key: key)),
@ -300,6 +311,7 @@ void main() {
expect(keyState.marker, equals("marked")); expect(keyState.marker, equals("marked"));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Container(width: 100.0, height: 100.0), new Container(width: 100.0, height: 100.0),
new StateMarker(key: key), new StateMarker(key: key),

View File

@ -109,10 +109,15 @@ void main() {
testWidgets('Route management - push, replace, pop', (WidgetTester tester) async { testWidgets('Route management - push, replace, pop', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await tester.pumpWidget(new Navigator( await tester.pumpWidget(
key: navigatorKey, new Directionality(
onGenerateRoute: (_) => new TestRoute('initial') textDirection: TextDirection.ltr,
)); child: new Navigator(
key: navigatorKey,
onGenerateRoute: (_) => new TestRoute('initial'),
),
),
);
final NavigatorState host = navigatorKey.currentState; final NavigatorState host = navigatorKey.currentState;
await runNavigatorTest( await runNavigatorTest(
tester, tester,
@ -187,10 +192,15 @@ void main() {
testWidgets('Route management - push, remove, pop', (WidgetTester tester) async { testWidgets('Route management - push, remove, pop', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await tester.pumpWidget(new Navigator( await tester.pumpWidget(
key: navigatorKey, new Directionality(
onGenerateRoute: (_) => new TestRoute('first') textDirection: TextDirection.ltr,
)); child: new Navigator(
key: navigatorKey,
onGenerateRoute: (_) => new TestRoute('first')
),
),
);
final NavigatorState host = navigatorKey.currentState; final NavigatorState host = navigatorKey.currentState;
await runNavigatorTest( await runNavigatorTest(
tester, tester,
@ -293,10 +303,15 @@ void main() {
testWidgets('Route management - push, replace, popUntil', (WidgetTester tester) async { testWidgets('Route management - push, replace, popUntil', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await tester.pumpWidget(new Navigator( await tester.pumpWidget(
key: navigatorKey, new Directionality(
onGenerateRoute: (_) => new TestRoute('A') textDirection: TextDirection.ltr,
)); child: new Navigator(
key: navigatorKey,
onGenerateRoute: (_) => new TestRoute('A')
),
),
);
final NavigatorState host = navigatorKey.currentState; final NavigatorState host = navigatorKey.currentState;
await runNavigatorTest( await runNavigatorTest(
tester, tester,
@ -370,10 +385,15 @@ void main() {
onRemove: () { routeA.log('onRemove 1'); } onRemove: () { routeA.log('onRemove 1'); }
)); ));
final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
await tester.pumpWidget(new Navigator( await tester.pumpWidget(
key: navigatorKey, new Directionality(
onGenerateRoute: (_) => routeA textDirection: TextDirection.ltr,
)); child: new Navigator(
key: navigatorKey,
onGenerateRoute: (_) => routeA
),
),
);
final NavigatorState host = navigatorKey.currentState; final NavigatorState host = navigatorKey.currentState;
await runNavigatorTest( await runNavigatorTest(
tester, tester,

View File

@ -14,6 +14,7 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
fit: StackFit.expand, fit: StackFit.expand,
children: <Widget>[ children: <Widget>[
const Semantics( const Semantics(

View File

@ -21,6 +21,7 @@ void main() {
child: new Semantics( child: new Semantics(
container: true, container: true,
child: new Stack( child: new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
const Semantics( const Semantics(
checked: true, checked: true,
@ -52,6 +53,7 @@ void main() {
child: new Semantics( child: new Semantics(
container: true, container: true,
child: new Stack( child: new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
const Semantics( const Semantics(
label: 'label', label: 'label',

View File

@ -15,6 +15,7 @@ void main() {
final SemanticsTester semantics = new SemanticsTester(tester); final SemanticsTester semantics = new SemanticsTester(tester);
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Semantics( new Semantics(
label: 'layer#1', label: 'layer#1',
@ -33,6 +34,7 @@ void main() {
expect(semantics, isNot(includesNodeWith(label: 'layer#1'))); expect(semantics, isNot(includesNodeWith(label: 'layer#1')));
await tester.pumpWidget(new Stack( await tester.pumpWidget(new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Semantics( new Semantics(
label: 'layer#1', label: 'layer#1',

View File

@ -12,22 +12,8 @@ void main() {
// This is a smoketest to verify that adding a debugger doesn't crash. // This is a smoketest to verify that adding a debugger doesn't crash.
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
const Semantics(),
const Semantics(
container: true,
),
const Semantics(
label: 'label',
textDirection: TextDirection.ltr,
),
],
),
);
await tester.pumpWidget(
new SemanticsDebugger(
child: new Stack( child: new Stack(
children: <Widget>[ children: <Widget>[
const Semantics(), const Semantics(),
@ -43,6 +29,26 @@ void main() {
), ),
); );
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new SemanticsDebugger(
child: new Stack(
children: <Widget>[
const Semantics(),
const Semantics(
container: true,
),
const Semantics(
label: 'label',
textDirection: TextDirection.ltr,
),
],
),
),
),
);
expect(true, isTrue); // expect that we reach here without crashing expect(true, isTrue); // expect that we reach here without crashing
}); });
@ -51,71 +57,80 @@ void main() {
final GlobalKey key = new GlobalKey(); final GlobalKey key = new GlobalKey();
await tester.pumpWidget( await tester.pumpWidget(
new SemanticsDebugger( new Directionality(
child: new Stack( textDirection: TextDirection.ltr,
children: <Widget>[ child: new SemanticsDebugger(
const Semantics(label: 'label1', textDirection: TextDirection.ltr), child: new Stack(
new Positioned( children: <Widget>[
key: key, const Semantics(label: 'label1', textDirection: TextDirection.ltr),
left: 0.0, new Positioned(
top: 0.0, key: key,
width: 100.0, left: 0.0,
height: 100.0, top: 0.0,
child: const Semantics(label: 'label2', textDirection: TextDirection.ltr), width: 100.0,
), height: 100.0,
], child: const Semantics(label: 'label2', textDirection: TextDirection.ltr),
),
),
);
await tester.pumpWidget(
new SemanticsDebugger(
child: new Stack(
children: <Widget>[
const Semantics(label: 'label1', textDirection: TextDirection.ltr),
new Semantics(
container: true,
child: new Stack(
children: <Widget>[
new Positioned(
key: key,
left: 0.0,
top: 0.0,
width: 100.0,
height: 100.0,
child: const Semantics(label: 'label2', textDirection: TextDirection.ltr),
),
const Semantics(label: 'label3', textDirection: TextDirection.ltr),
],
), ),
), ],
], ),
), ),
), ),
); );
await tester.pumpWidget( await tester.pumpWidget(
new SemanticsDebugger( new Directionality(
child: new Stack( textDirection: TextDirection.ltr,
children: <Widget>[ child: new SemanticsDebugger(
const Semantics(label: 'label1', textDirection: TextDirection.ltr), child: new Stack(
new Semantics( children: <Widget>[
container: true, const Semantics(label: 'label1', textDirection: TextDirection.ltr),
child: new Stack( new Semantics(
children: <Widget>[ container: true,
new Positioned( child: new Stack(
children: <Widget>[
new Positioned(
key: key, key: key,
left: 0.0, left: 0.0,
top: 0.0, top: 0.0,
width: 100.0, width: 100.0,
height: 100.0, height: 100.0,
child: const Semantics(label: 'label2', textDirection: TextDirection.ltr)), child: const Semantics(label: 'label2', textDirection: TextDirection.ltr),
const Semantics(label: 'label3', textDirection: TextDirection.ltr), ),
const Semantics(label: 'label4', textDirection: TextDirection.ltr), const Semantics(label: 'label3', textDirection: TextDirection.ltr),
], ],
),
), ),
), ],
], ),
),
),
);
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new SemanticsDebugger(
child: new Stack(
children: <Widget>[
const Semantics(label: 'label1', textDirection: TextDirection.ltr),
new Semantics(
container: true,
child: new Stack(
children: <Widget>[
new Positioned(
key: key,
left: 0.0,
top: 0.0,
width: 100.0,
height: 100.0,
child: const Semantics(label: 'label2', textDirection: TextDirection.ltr)),
const Semantics(label: 'label3', textDirection: TextDirection.ltr),
const Semantics(label: 'label4', textDirection: TextDirection.ltr),
],
),
),
],
),
), ),
), ),
); );
@ -250,13 +265,16 @@ void main() {
bool didLongPress = false; bool didLongPress = false;
await tester.pumpWidget( await tester.pumpWidget(
new SemanticsDebugger( new Directionality(
child: new GestureDetector( textDirection: TextDirection.ltr,
onLongPress: () { child: new SemanticsDebugger(
expect(didLongPress, isFalse); child: new GestureDetector(
didLongPress = true; onLongPress: () {
}, expect(didLongPress, isFalse);
child: const Text('target', textDirection: TextDirection.ltr), didLongPress = true;
},
child: const Text('target', textDirection: TextDirection.ltr),
),
), ),
), ),
); );
@ -269,16 +287,19 @@ void main() {
double value = 0.75; double value = 0.75;
await tester.pumpWidget( await tester.pumpWidget(
new SemanticsDebugger( new Directionality(
child: new Directionality( textDirection: TextDirection.ltr,
textDirection: TextDirection.ltr, child: new SemanticsDebugger(
child: new Material( child: new Directionality(
child: new Center( textDirection: TextDirection.ltr,
child: new Slider( child: new Material(
value: value, child: new Center(
onChanged: (double newValue) { child: new Slider(
value = newValue; value: value,
}, onChanged: (double newValue) {
value = newValue;
},
),
), ),
), ),
), ),

View File

@ -19,11 +19,21 @@ class TestPaintingContext implements PaintingContext {
void main() { void main() {
testWidgets('Can construct an empty Stack', (WidgetTester tester) async { testWidgets('Can construct an empty Stack', (WidgetTester tester) async {
await tester.pumpWidget(new Stack()); await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Stack(),
),
);
}); });
testWidgets('Can construct an empty Centered Stack', (WidgetTester tester) async { testWidgets('Can construct an empty Centered Stack', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new Stack())); await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Center(child: new Stack()),
),
);
}); });
testWidgets('Can change position data', (WidgetTester tester) async { testWidgets('Can change position data', (WidgetTester tester) async {
@ -31,17 +41,18 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
alignment: FractionalOffset.topLeft,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
left: 10.0, left: 10.0,
child: new Container( child: new Container(
key: key, key: key,
width: 10.0, width: 10.0,
height: 10.0 height: 10.0,
) ),
) ),
] ],
) ),
); );
Element container; Element container;
@ -58,17 +69,18 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
alignment: FractionalOffset.topLeft,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
right: 10.0, right: 10.0,
child: new Container( child: new Container(
key: key, key: key,
width: 10.0, width: 10.0,
height: 10.0 height: 10.0,
) ),
) ),
] ],
) ),
); );
container = tester.element(find.byKey(key)); container = tester.element(find.byKey(key));
@ -85,7 +97,12 @@ void main() {
final Key key = const Key('container'); final Key key = const Key('container');
final Container container = new Container(key: key, width: 10.0, height: 10.0); final Container container = new Container(key: key, width: 10.0, height: 10.0);
await tester.pumpWidget(new Stack(children: <Widget>[ new Positioned(left: 10.0, child: container) ])); await tester.pumpWidget(
new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ new Positioned(left: 10.0, child: container) ],
),
);
Element containerElement = tester.element(find.byKey(key)); Element containerElement = tester.element(find.byKey(key));
StackParentData parentData; StackParentData parentData;
@ -97,7 +114,12 @@ void main() {
expect(parentData.width, isNull); expect(parentData.width, isNull);
expect(parentData.height, isNull); expect(parentData.height, isNull);
await tester.pumpWidget(new Stack(children: <Widget>[ container ])); await tester.pumpWidget(
new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ container ],
),
);
containerElement = tester.element(find.byKey(key)); containerElement = tester.element(find.byKey(key));
parentData = containerElement.renderObject.parentData; parentData = containerElement.renderObject.parentData;
@ -109,20 +131,23 @@ void main() {
expect(parentData.height, isNull); expect(parentData.height, isNull);
}); });
testWidgets('Can align non-positioned children', (WidgetTester tester) async { testWidgets('Can align non-positioned children (LTR)', (WidgetTester tester) async {
final Key child0Key = const Key('child0'); final Key child0Key = const Key('child0');
final Key child1Key = const Key('child1'); final Key child1Key = const Key('child1');
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new Stack( textDirection: TextDirection.ltr,
children: <Widget>[ child: new Center(
new Container(key: child0Key, width: 20.0, height: 20.0), child: new Stack(
new Container(key: child1Key, width: 10.0, height: 10.0) alignment: FractionalOffset.center,
], children: <Widget>[
alignment: const FractionalOffset(0.5, 0.5) new Container(key: child0Key, width: 20.0, height: 20.0),
) new Container(key: child1Key, width: 10.0, height: 10.0),
) ],
),
),
),
); );
final Element child0 = tester.element(find.byKey(child0Key)); final Element child0 = tester.element(find.byKey(child0Key));
@ -132,14 +157,88 @@ void main() {
final Element child1 = tester.element(find.byKey(child1Key)); final Element child1 = tester.element(find.byKey(child1Key));
final StackParentData child1RenderObjectParentData = child1.renderObject.parentData; final StackParentData child1RenderObjectParentData = child1.renderObject.parentData;
expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0))); expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0)));
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Center(
child: new Stack(
alignment: FractionalOffsetDirectional.bottomEnd,
children: <Widget>[
new Container(key: child0Key, width: 20.0, height: 20.0),
new Container(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
expect(child0RenderObjectParentData.offset, equals(const Offset(0.0, 0.0)));
expect(child1RenderObjectParentData.offset, equals(const Offset(10.0, 10.0)));
});
testWidgets('Can align non-positioned children (RTL)', (WidgetTester tester) async {
final Key child0Key = const Key('child0');
final Key child1Key = const Key('child1');
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new Center(
child: new Stack(
alignment: FractionalOffset.center,
children: <Widget>[
new Container(key: child0Key, width: 20.0, height: 20.0),
new Container(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
final Element child0 = tester.element(find.byKey(child0Key));
final StackParentData child0RenderObjectParentData = child0.renderObject.parentData;
expect(child0RenderObjectParentData.offset, equals(const Offset(0.0, 0.0)));
final Element child1 = tester.element(find.byKey(child1Key));
final StackParentData child1RenderObjectParentData = child1.renderObject.parentData;
expect(child1RenderObjectParentData.offset, equals(const Offset(5.0, 5.0)));
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.rtl,
child: new Center(
child: new Stack(
alignment: FractionalOffsetDirectional.bottomEnd,
children: <Widget>[
new Container(key: child0Key, width: 20.0, height: 20.0),
new Container(key: child1Key, width: 10.0, height: 10.0),
],
),
),
),
);
expect(child0RenderObjectParentData.offset, equals(const Offset(0.0, 0.0)));
expect(child1RenderObjectParentData.offset, equals(const Offset(0.0, 10.0)));
}); });
testWidgets('Can construct an empty IndexedStack', (WidgetTester tester) async { testWidgets('Can construct an empty IndexedStack', (WidgetTester tester) async {
await tester.pumpWidget(new IndexedStack()); await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new IndexedStack(),
),
);
}); });
testWidgets('Can construct an empty Centered IndexedStack', (WidgetTester tester) async { testWidgets('Can construct an empty Centered IndexedStack', (WidgetTester tester) async {
await tester.pumpWidget(new Center(child: new IndexedStack())); await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new Center(child: new IndexedStack()),
),
);
}); });
testWidgets('Can construct an IndexedStack', (WidgetTester tester) async { testWidgets('Can construct an IndexedStack', (WidgetTester tester) async {
@ -153,10 +252,16 @@ void main() {
child: new Text('$i', textDirection: TextDirection.ltr), child: new Text('$i', textDirection: TextDirection.ltr),
painter: new TestCallbackPainter( painter: new TestCallbackPainter(
onPaint: () { itemsPainted.add(i); } onPaint: () { itemsPainted.add(i); }
) ),
); );
}); });
return new Center(child: new IndexedStack(children: items, index: index)); return new Center(
child: new IndexedStack(
alignment: FractionalOffset.topLeft,
children: items,
index: index,
),
);
} }
await tester.pumpWidget(buildFrame(0)); await tester.pumpWidget(buildFrame(0));
@ -182,7 +287,14 @@ void main() {
final List<Widget> items = new List<Widget>.generate(itemCount, (int i) { final List<Widget> items = new List<Widget>.generate(itemCount, (int i) {
return new GestureDetector(child: new Text('$i', textDirection: TextDirection.ltr), onTap: () { itemsTapped.add(i); }); return new GestureDetector(child: new Text('$i', textDirection: TextDirection.ltr), onTap: () { itemsTapped.add(i); });
}); });
return new Center(child: new IndexedStack(children: items, key: key, index: index)); return new Center(
child: new IndexedStack(
alignment: FractionalOffset.topLeft,
children: items,
key: key,
index: index,
),
);
} }
await tester.pumpWidget(buildFrame(0)); await tester.pumpWidget(buildFrame(0));
@ -205,15 +317,16 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
left: 10.0, left: 10.0,
width: 11.0, width: 11.0,
height: 12.0, height: 12.0,
child: new DecoratedBox(key: key, decoration: kBoxDecoration) child: new DecoratedBox(key: key, decoration: kBoxDecoration),
) ),
] ],
) ),
); );
Element box; Element box;
@ -236,15 +349,16 @@ void main() {
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Stack(
textDirection: TextDirection.ltr,
children: <Widget>[ children: <Widget>[
new Positioned( new Positioned(
right: 10.0, right: 10.0,
width: 11.0, width: 11.0,
height: 12.0, height: 12.0,
child: new DecoratedBox(key: key, decoration: kBoxDecoration) child: new DecoratedBox(key: key, decoration: kBoxDecoration),
) ),
] ],
) ),
); );
box = tester.element(find.byKey(key)); box = tester.element(find.byKey(key));
@ -266,19 +380,22 @@ void main() {
bool tapped; bool tapped;
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new IndexedStack( textDirection: TextDirection.ltr,
index: null, child: new Center(
children: <Widget>[ child: new IndexedStack(
new GestureDetector( index: null,
behavior: HitTestBehavior.opaque, children: <Widget>[
onTap: () { print("HELLO"); tapped = true; }, new GestureDetector(
child: const SizedBox( behavior: HitTestBehavior.opaque,
width: 200.0, onTap: () { print("HELLO"); tapped = true; },
height: 200.0, child: const SizedBox(
width: 200.0,
height: 200.0,
),
), ),
), ],
], ),
), ),
), ),
); );
@ -291,24 +408,27 @@ void main() {
testWidgets('Stack clip test', (WidgetTester tester) async { testWidgets('Stack clip test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new Stack( textDirection: TextDirection.ltr,
children: <Widget>[ child: new Center(
new Container( child: new Stack(
width: 100.0, children: <Widget>[
height: 100.0 new Container(
), width: 100.0,
new Positioned( height: 100.0,
top: 0.0, ),
left: 0.0, new Positioned(
child: new Container( top: 0.0,
width: 200.0, left: 0.0,
height: 200.0 child: new Container(
) width: 200.0,
) height: 200.0,
] ),
) ),
) ],
),
),
),
); );
RenderBox box = tester.renderObject(find.byType(Stack)); RenderBox box = tester.renderObject(find.byType(Stack));
@ -317,25 +437,28 @@ void main() {
expect(context.invocations.first.memberName, equals(#pushClipRect)); expect(context.invocations.first.memberName, equals(#pushClipRect));
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new Stack( textDirection: TextDirection.ltr,
overflow: Overflow.visible, child: new Center(
children: <Widget>[ child: new Stack(
new Container( overflow: Overflow.visible,
width: 100.0, children: <Widget>[
height: 100.0 new Container(
), width: 100.0,
new Positioned( height: 100.0,
top: 0.0, ),
left: 0.0, new Positioned(
child: new Container( top: 0.0,
width: 200.0, left: 0.0,
height: 200.0 child: new Container(
) width: 200.0,
) height: 200.0,
] ),
) ),
) ],
),
),
),
); );
box = tester.renderObject(find.byType(Stack)); box = tester.renderObject(find.byType(Stack));
@ -347,23 +470,26 @@ void main() {
testWidgets('Stack sizing: default', (WidgetTester tester) async { testWidgets('Stack sizing: default', (WidgetTester tester) async {
final List<String> logs = <String>[]; final List<String> logs = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
new Center( new Directionality(
child: new ConstrainedBox( textDirection: TextDirection.ltr,
constraints: const BoxConstraints( child: new Center(
minWidth: 2.0, child: new ConstrainedBox(
maxWidth: 3.0, constraints: const BoxConstraints(
minHeight: 5.0, minWidth: 2.0,
maxHeight: 7.0, maxWidth: 3.0,
), minHeight: 5.0,
child: new Stack( maxHeight: 7.0,
children: <Widget>[ ),
new LayoutBuilder( child: new Stack(
builder: (BuildContext context, BoxConstraints constraints) { children: <Widget>[
logs.add(constraints.toString()); new LayoutBuilder(
return const Placeholder(); builder: (BuildContext context, BoxConstraints constraints) {
}, logs.add(constraints.toString());
), return const Placeholder();
], },
),
],
),
), ),
), ),
), ),
@ -374,24 +500,27 @@ void main() {
testWidgets('Stack sizing: explicit', (WidgetTester tester) async { testWidgets('Stack sizing: explicit', (WidgetTester tester) async {
final List<String> logs = <String>[]; final List<String> logs = <String>[];
Widget buildStack(StackFit sizing) { Widget buildStack(StackFit sizing) {
return new Center( return new Directionality(
child: new ConstrainedBox( textDirection: TextDirection.ltr,
constraints: const BoxConstraints( child: new Center(
minWidth: 2.0, child: new ConstrainedBox(
maxWidth: 3.0, constraints: const BoxConstraints(
minHeight: 5.0, minWidth: 2.0,
maxHeight: 7.0, maxWidth: 3.0,
), minHeight: 5.0,
child: new Stack( maxHeight: 7.0,
fit: sizing, ),
children: <Widget>[ child: new Stack(
new LayoutBuilder( fit: sizing,
builder: (BuildContext context, BoxConstraints constraints) { children: <Widget>[
logs.add(constraints.toString()); new LayoutBuilder(
return const Placeholder(); builder: (BuildContext context, BoxConstraints constraints) {
}, logs.add(constraints.toString());
), return const Placeholder();
], },
),
],
),
), ),
), ),
); );
@ -412,27 +541,37 @@ void main() {
testWidgets('Positioned.directional control test', (WidgetTester tester) async { testWidgets('Positioned.directional control test', (WidgetTester tester) async {
final Key key = new UniqueKey(); final Key key = new UniqueKey();
await tester.pumpWidget(new Stack( await tester.pumpWidget(
children: <Widget>[ new Directionality(
new Positioned.directional( textDirection: TextDirection.ltr,
textDirection: TextDirection.rtl, child: new Stack(
start: 50.0, children: <Widget>[
child: new Container(key: key, width: 75.0, height: 175.0), new Positioned.directional(
textDirection: TextDirection.rtl,
start: 50.0,
child: new Container(key: key, width: 75.0, height: 175.0),
),
],
), ),
], ),
)); );
expect(tester.getTopLeft(find.byKey(key)), const Offset(675.0, 0.0)); expect(tester.getTopLeft(find.byKey(key)), const Offset(675.0, 0.0));
await tester.pumpWidget(new Stack( await tester.pumpWidget(
children: <Widget>[ new Directionality(
new Positioned.directional( textDirection: TextDirection.ltr,
textDirection: TextDirection.ltr, child: new Stack(
start: 50.0, children: <Widget>[
child: new Container(key: key, width: 75.0, height: 175.0), new Positioned.directional(
textDirection: TextDirection.ltr,
start: 50.0,
child: new Container(key: key, width: 75.0, height: 175.0),
),
],
), ),
], ),
)); );
expect(tester.getTopLeft(find.byKey(key)), const Offset(50.0, 0.0)); expect(tester.getTopLeft(find.byKey(key)), const Offset(50.0, 0.0));
}); });

View File

@ -13,38 +13,41 @@ void main() {
testWidgets('Transform origin', (WidgetTester tester) async { testWidgets('Transform origin', (WidgetTester tester) async {
bool didReceiveTap = false; bool didReceiveTap = false;
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
top: 100.0, children: <Widget>[
left: 100.0, new Positioned(
child: new Container( top: 100.0,
width: 100.0, left: 100.0,
height: 100.0, child: new Container(
color: const Color(0xFF0000FF), width: 100.0,
height: 100.0,
color: const Color(0xFF0000FF),
),
), ),
), new Positioned(
new Positioned( top: 100.0,
top: 100.0, left: 100.0,
left: 100.0, child: new Container(
child: new Container( width: 100.0,
width: 100.0, height: 100.0,
height: 100.0, child: new Transform(
child: new Transform( transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0),
transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0), origin: const Offset(100.0, 50.0),
origin: const Offset(100.0, 50.0), child: new GestureDetector(
child: new GestureDetector( onTap: () {
onTap: () { didReceiveTap = true;
didReceiveTap = true; },
}, child: new Container(
child: new Container( color: const Color(0xFF00FFFF),
color: const Color(0xFF00FFFF), ),
), ),
), ),
), ),
), ),
), ],
], ),
), ),
); );
@ -58,38 +61,41 @@ void main() {
testWidgets('Transform alignment', (WidgetTester tester) async { testWidgets('Transform alignment', (WidgetTester tester) async {
bool didReceiveTap = false; bool didReceiveTap = false;
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
new Positioned( child: new Stack(
top: 100.0, children: <Widget>[
left: 100.0, new Positioned(
child: new Container( top: 100.0,
width: 100.0, left: 100.0,
height: 100.0, child: new Container(
color: const Color(0xFF0000FF), width: 100.0,
height: 100.0,
color: const Color(0xFF0000FF),
),
), ),
), new Positioned(
new Positioned( top: 100.0,
top: 100.0, left: 100.0,
left: 100.0, child: new Container(
child: new Container( width: 100.0,
width: 100.0, height: 100.0,
height: 100.0, child: new Transform(
child: new Transform( transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0),
transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0), alignment: const FractionalOffset(1.0, 0.5),
alignment: const FractionalOffset(1.0, 0.5), child: new GestureDetector(
child: new GestureDetector( onTap: () {
onTap: () { didReceiveTap = true;
didReceiveTap = true; },
}, child: new Container(
child: new Container( color: const Color(0xFF00FFFF),
color: const Color(0xFF00FFFF), ),
), ),
), ),
), ),
), ),
), ],
], ),
), ),
); );
@ -102,40 +108,45 @@ void main() {
testWidgets('Transform offset + alignment', (WidgetTester tester) async { testWidgets('Transform offset + alignment', (WidgetTester tester) async {
bool didReceiveTap = false; bool didReceiveTap = false;
await tester.pumpWidget(new Stack( await tester.pumpWidget(
children: <Widget>[ new Directionality(
new Positioned( textDirection: TextDirection.ltr,
top: 100.0, child: new Stack(
left: 100.0, children: <Widget>[
child: new Container( new Positioned(
width: 100.0, top: 100.0,
height: 100.0, left: 100.0,
color: const Color(0xFF0000FF), child: new Container(
), width: 100.0,
), height: 100.0,
new Positioned( color: const Color(0xFF0000FF),
top: 100.0, ),
left: 100.0, ),
child: new Container( new Positioned(
width: 100.0, top: 100.0,
height: 100.0, left: 100.0,
child: new Transform( child: new Container(
transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0), width: 100.0,
origin: const Offset(100.0, 0.0), height: 100.0,
alignment: const FractionalOffset(0.0, 0.5), child: new Transform(
child: new GestureDetector( transform: new Matrix4.diagonal3Values(0.5, 0.5, 1.0),
onTap: () { origin: const Offset(100.0, 0.0),
didReceiveTap = true; alignment: const FractionalOffset(0.0, 0.5),
}, child: new GestureDetector(
child: new Container( onTap: () {
color: const Color(0xFF00FFFF), didReceiveTap = true;
},
child: new Container(
color: const Color(0xFF00FFFF),
),
),
), ),
), ),
), ),
), ],
), ),
], ),
)); );
expect(didReceiveTap, isFalse); expect(didReceiveTap, isFalse);
await tester.tapAt(const Offset(110.0, 110.0)); await tester.tapAt(const Offset(110.0, 110.0));

View File

@ -11,18 +11,8 @@ void main() {
testWidgets('WidgetInspector smoke test', (WidgetTester tester) async { testWidgets('WidgetInspector smoke test', (WidgetTester tester) async {
// This is a smoke test to verify that adding the inspector doesn't crash. // This is a smoke test to verify that adding the inspector doesn't crash.
await tester.pumpWidget( await tester.pumpWidget(
new Stack( new Directionality(
children: <Widget>[ textDirection: TextDirection.ltr,
const Text('a', textDirection: TextDirection.ltr),
const Text('b', textDirection: TextDirection.ltr),
const Text('c', textDirection: TextDirection.ltr),
],
),
);
await tester.pumpWidget(
new WidgetInspector(
selectButtonBuilder: null,
child: new Stack( child: new Stack(
children: <Widget>[ children: <Widget>[
const Text('a', textDirection: TextDirection.ltr), const Text('a', textDirection: TextDirection.ltr),
@ -33,6 +23,22 @@ void main() {
), ),
); );
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new WidgetInspector(
selectButtonBuilder: null,
child: new Stack(
children: <Widget>[
const Text('a', textDirection: TextDirection.ltr),
const Text('b', textDirection: TextDirection.ltr),
const Text('c', textDirection: TextDirection.ltr),
],
),
),
),
);
expect(true, isTrue); // Expect that we reach here without crashing. expect(true, isTrue); // Expect that we reach here without crashing.
}); });
@ -172,14 +178,17 @@ void main() {
bool didLongPress = false; bool didLongPress = false;
await tester.pumpWidget( await tester.pumpWidget(
new WidgetInspector( new Directionality(
selectButtonBuilder: null, textDirection: TextDirection.ltr,
child: new GestureDetector( child: new WidgetInspector(
onLongPress: () { selectButtonBuilder: null,
expect(didLongPress, isFalse); child: new GestureDetector(
didLongPress = true; onLongPress: () {
}, expect(didLongPress, isFalse);
child: const Text('target', textDirection: TextDirection.ltr), didLongPress = true;
},
child: const Text('target', textDirection: TextDirection.ltr),
),
), ),
), ),
); );
@ -208,27 +217,30 @@ void main() {
); );
} }
await tester.pumpWidget( await tester.pumpWidget(
new WidgetInspector( new Directionality(
key: inspectorKey, textDirection: TextDirection.ltr,
selectButtonBuilder: null, child: new WidgetInspector(
child: new Overlay( key: inspectorKey,
initialEntries: <OverlayEntry>[ selectButtonBuilder: null,
new OverlayEntry( child: new Overlay(
opaque: false, initialEntries: <OverlayEntry>[
maintainState: true, new OverlayEntry(
builder: (BuildContext _) => createSubtree(width: 94.0), opaque: false,
), maintainState: true,
new OverlayEntry( builder: (BuildContext _) => createSubtree(width: 94.0),
opaque: true, ),
maintainState: true, new OverlayEntry(
builder: (BuildContext _) => createSubtree(width: 95.0), opaque: true,
), maintainState: true,
new OverlayEntry( builder: (BuildContext _) => createSubtree(width: 95.0),
opaque: false, ),
maintainState: true, new OverlayEntry(
builder: (BuildContext _) => createSubtree(width: 96.0, key: clickTarget), opaque: false,
), maintainState: true,
], builder: (BuildContext _) => createSubtree(width: 96.0, key: clickTarget),
),
],
),
), ),
), ),
); );