From 7d368dcf0c00b45fef5b02c5cccb8aa5306234ba Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Tue, 14 Sep 2021 12:39:19 -0700 Subject: [PATCH] InteractiveViewer with a child of zero size (#90012) Asserts that the InteractiveViewer child can't have zero size. --- .../lib/src/widgets/interactive_viewer.dart | 4 +++ .../test/widgets/interactive_viewer_test.dart | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/packages/flutter/lib/src/widgets/interactive_viewer.dart b/packages/flutter/lib/src/widgets/interactive_viewer.dart index b5ae9b04f7e..1a6e9a60bde 100644 --- a/packages/flutter/lib/src/widgets/interactive_viewer.dart +++ b/packages/flutter/lib/src/widgets/interactive_viewer.dart @@ -512,6 +512,10 @@ class _InteractiveViewerState extends State with TickerProvid final RenderBox childRenderBox = _childKey.currentContext!.findRenderObject()! as RenderBox; final Size childSize = childRenderBox.size; final Rect boundaryRect = widget.boundaryMargin.inflateRect(Offset.zero & childSize); + assert( + !boundaryRect.isEmpty, + "InteractiveViewer's child must have nonzero dimensions.", + ); // Boundaries that are partially infinite are not allowed because Matrix4's // rotation and translation methods don't handle infinites well. assert( diff --git a/packages/flutter/test/widgets/interactive_viewer_test.dart b/packages/flutter/test/widgets/interactive_viewer_test.dart index 6015f42111b..871a2310f10 100644 --- a/packages/flutter/test/widgets/interactive_viewer_test.dart +++ b/packages/flutter/test/widgets/interactive_viewer_test.dart @@ -201,6 +201,42 @@ void main() { expect(transformationController.value, isNot(equals(Matrix4.identity()))); }); + testWidgets('child has no dimensions', (WidgetTester tester) async { + final TransformationController transformationController = TransformationController(); + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: InteractiveViewer( + constrained: false, + scaleEnabled: false, + transformationController: transformationController, + child: const SizedBox(width: 0.0, height: 0.0), + ), + ), + ), + ), + ); + + expect(transformationController.value, equals(Matrix4.identity())); + + // Interacting throws an error because the child has no size. + final Offset childOffset = tester.getTopLeft(find.byType(SizedBox)); + final Offset childInterior = Offset( + childOffset.dx + 20.0, + childOffset.dy + 20.0, + ); + final TestGesture gesture = await tester.startGesture(childOffset); + addTearDown(gesture.removePointer); + await tester.pump(); + await gesture.moveTo(childInterior); + await tester.pump(); + await gesture.up(); + await tester.pumpAndSettle(); + expect(transformationController.value, equals(Matrix4.identity())); + expect(tester.takeException(), isAssertionError); + }); + testWidgets('no boundary', (WidgetTester tester) async { final TransformationController transformationController = TransformationController(); const double minScale = 0.8;