blob: d0f9d63fcd7e7b01da452021104f3ba032188fb8 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
class TestSingleChildLayoutDelegate extends SingleChildLayoutDelegate {
late BoxConstraints constraintsFromGetSize;
BoxConstraints? constraintsFromGetConstraintsForChild;
late Size sizeFromGetPositionForChild;
late Size childSizeFromGetPositionForChild;
@override
Size getSize(BoxConstraints constraints) {
if (!RenderObject.debugCheckingIntrinsics)
constraintsFromGetSize = constraints;
return const Size(200.0, 300.0);
}
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
assert(!RenderObject.debugCheckingIntrinsics);
constraintsFromGetConstraintsForChild = constraints;
return const BoxConstraints(minWidth: 100.0, maxWidth: 150.0, minHeight: 200.0, maxHeight: 400.0);
}
@override
Offset getPositionForChild(Size size, Size childSize) {
assert(!RenderObject.debugCheckingIntrinsics);
sizeFromGetPositionForChild = size;
childSizeFromGetPositionForChild = childSize;
return Offset.zero;
}
bool shouldRelayoutCalled = false;
bool shouldRelayoutValue = false;
@override
bool shouldRelayout(_) {
assert(!RenderObject.debugCheckingIntrinsics);
shouldRelayoutCalled = true;
return shouldRelayoutValue;
}
}
class FixedSizeLayoutDelegate extends SingleChildLayoutDelegate {
FixedSizeLayoutDelegate(this.size);
final Size size;
@override
Size getSize(BoxConstraints constraints) => size;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints.tight(size);
}
@override
bool shouldRelayout(FixedSizeLayoutDelegate oldDelegate) {
return size != oldDelegate.size;
}
}
class NotifierLayoutDelegate extends SingleChildLayoutDelegate {
NotifierLayoutDelegate(this.size) : super(relayout: size);
final ValueNotifier<Size> size;
@override
Size getSize(BoxConstraints constraints) => size.value;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints.tight(size.value);
}
@override
bool shouldRelayout(NotifierLayoutDelegate oldDelegate) {
return size != oldDelegate.size;
}
}
Widget buildFrame(SingleChildLayoutDelegate delegate) {
return Center(
child: CustomSingleChildLayout(
delegate: delegate,
child: Container(),
),
);
}
void main() {
testWidgets('Control test for CustomSingleChildLayout', (WidgetTester tester) async {
final TestSingleChildLayoutDelegate delegate = TestSingleChildLayoutDelegate();
await tester.pumpWidget(buildFrame(delegate));
expect(delegate.constraintsFromGetSize.minWidth, 0.0);
expect(delegate.constraintsFromGetSize.maxWidth, 800.0);
expect(delegate.constraintsFromGetSize.minHeight, 0.0);
expect(delegate.constraintsFromGetSize.maxHeight, 600.0);
expect(delegate.constraintsFromGetConstraintsForChild!.minWidth, 0.0);
expect(delegate.constraintsFromGetConstraintsForChild!.maxWidth, 800.0);
expect(delegate.constraintsFromGetConstraintsForChild!.minHeight, 0.0);
expect(delegate.constraintsFromGetConstraintsForChild!.maxHeight, 600.0);
expect(delegate.sizeFromGetPositionForChild.width, 200.0);
expect(delegate.sizeFromGetPositionForChild.height, 300.0);
expect(delegate.childSizeFromGetPositionForChild.width, 150.0);
expect(delegate.childSizeFromGetPositionForChild.height, 400.0);
});
testWidgets('Test SingleChildDelegate shouldRelayout method', (WidgetTester tester) async {
TestSingleChildLayoutDelegate delegate =
TestSingleChildLayoutDelegate();
await tester.pumpWidget(buildFrame(delegate));
// Layout happened because the delegate was set.
expect(delegate.constraintsFromGetConstraintsForChild, isNotNull); // i.e. layout happened
expect(delegate.shouldRelayoutCalled, isFalse);
// Layout did not happen because shouldRelayout() returned false.
delegate = TestSingleChildLayoutDelegate();
delegate.shouldRelayoutValue = false;
await tester.pumpWidget(buildFrame(delegate));
expect(delegate.shouldRelayoutCalled, isTrue);
expect(delegate.constraintsFromGetConstraintsForChild, isNull);
// Layout happened because shouldRelayout() returned true.
delegate = TestSingleChildLayoutDelegate();
delegate.shouldRelayoutValue = true;
await tester.pumpWidget(buildFrame(delegate));
expect(delegate.shouldRelayoutCalled, isTrue);
expect(delegate.constraintsFromGetConstraintsForChild, isNotNull);
});
testWidgets('Delegate can change size', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(FixedSizeLayoutDelegate(const Size(100.0, 200.0))));
RenderBox box = tester.renderObject(find.byType(CustomSingleChildLayout));
expect(box.size, equals(const Size(100.0, 200.0)));
await tester.pumpWidget(buildFrame(FixedSizeLayoutDelegate(const Size(150.0, 240.0))));
box = tester.renderObject(find.byType(CustomSingleChildLayout));
expect(box.size, equals(const Size(150.0, 240.0)));
});
testWidgets('Can use listener for relayout', (WidgetTester tester) async {
final ValueNotifier<Size> size = ValueNotifier<Size>(const Size(100.0, 200.0));
await tester.pumpWidget(buildFrame(NotifierLayoutDelegate(size)));
RenderBox box = tester.renderObject(find.byType(CustomSingleChildLayout));
expect(box.size, equals(const Size(100.0, 200.0)));
size.value = const Size(150.0, 240.0);
await tester.pump();
box = tester.renderObject(find.byType(CustomSingleChildLayout));
expect(box.size, equals(const Size(150.0, 240.0)));
});
}