| // 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/src/foundation/assertions.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| const List<Widget> children = <Widget>[ |
| SizedBox(width: 200.0, height: 150.0), |
| SizedBox(width: 200.0, height: 150.0), |
| SizedBox(width: 200.0, height: 150.0), |
| SizedBox(width: 200.0, height: 150.0), |
| ]; |
| |
| void expectRects(WidgetTester tester, List<Rect> expected) { |
| final Finder finder = find.byType(SizedBox); |
| finder.precache(); |
| final List<Rect> actual = <Rect>[]; |
| for (int i = 0; i < expected.length; ++i) { |
| final Finder current = finder.at(i); |
| expect(current, findsOneWidget); |
| actual.add(tester.getRect(finder.at(i))); |
| } |
| expect(() => finder.at(expected.length), throwsRangeError); |
| expect(actual, equals(expected)); |
| } |
| |
| void main() { |
| |
| testWidgets('ListBody down', (WidgetTester tester) async { |
| await tester.pumpWidget(Flex( |
| direction: Axis.vertical, |
| children: <Widget>[ ListBody(children: children) ], |
| )); |
| |
| expectRects( |
| tester, |
| <Rect>[ |
| const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0), |
| ], |
| ); |
| }); |
| |
| testWidgets('ListBody up', (WidgetTester tester) async { |
| await tester.pumpWidget(Flex( |
| direction: Axis.vertical, |
| children: <Widget>[ ListBody(reverse: true, children: children) ], |
| )); |
| |
| expectRects( |
| tester, |
| <Rect>[ |
| const Rect.fromLTWH(0.0, 450.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 300.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 150.0, 800.0, 150.0), |
| const Rect.fromLTWH(0.0, 0.0, 800.0, 150.0), |
| ], |
| ); |
| }); |
| |
| testWidgets('ListBody right', (WidgetTester tester) async { |
| await tester.pumpWidget(Flex( |
| textDirection: TextDirection.ltr, |
| direction: Axis.horizontal, |
| children: <Widget>[ |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: ListBody(mainAxis: Axis.horizontal, children: children), |
| ), |
| ], |
| )); |
| |
| expectRects( |
| tester, |
| <Rect>[ |
| const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0), |
| ], |
| ); |
| }); |
| |
| testWidgets('ListBody left', (WidgetTester tester) async { |
| await tester.pumpWidget(Flex( |
| textDirection: TextDirection.ltr, |
| direction: Axis.horizontal, |
| children: <Widget>[ |
| Directionality( |
| textDirection: TextDirection.rtl, |
| child: ListBody(mainAxis: Axis.horizontal, children: children), |
| ), |
| ], |
| )); |
| |
| expectRects( |
| tester, |
| <Rect>[ |
| const Rect.fromLTWH(600.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(400.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(200.0, 0.0, 200.0, 600.0), |
| const Rect.fromLTWH(0.0, 0.0, 200.0, 600.0), |
| ], |
| ); |
| }); |
| |
| testWidgets('Limited space along main axis error', (WidgetTester tester) async { |
| final FlutterExceptionHandler oldHandler = FlutterError.onError!; |
| final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; |
| FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); |
| try { |
| await tester.pumpWidget( |
| SizedBox( |
| width: 100, |
| height: 100, |
| child: Directionality( |
| textDirection: TextDirection.rtl, |
| child: ListBody( |
| mainAxis: Axis.horizontal, |
| children: children, |
| ), |
| ), |
| ), |
| ); |
| } finally { |
| FlutterError.onError = oldHandler; |
| } |
| expect(errors, isNotEmpty); |
| expect(errors.first.exception, isFlutterError); |
| expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes( |
| 'FlutterError\n' |
| ' RenderListBody must have unlimited space along its main axis.\n' |
| ' RenderListBody does not clip or resize its children, so it must\n' |
| ' be placed in a parent that does not constrain the main axis.\n' |
| ' You probably want to put the RenderListBody inside a\n' |
| ' RenderViewport with a matching main axis.\n', |
| )); |
| }); |
| |
| testWidgets('Nested ListBody unbounded cross axis error', (WidgetTester tester) async { |
| final FlutterExceptionHandler oldHandler = FlutterError.onError!; |
| final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; |
| FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); |
| try { |
| await tester.pumpWidget( |
| Flex( |
| textDirection: TextDirection.ltr, |
| direction: Axis.horizontal, |
| children: <Widget>[ |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: ListBody( |
| mainAxis: Axis.horizontal, |
| children: <Widget>[ |
| Flex( |
| textDirection: TextDirection.ltr, |
| direction: Axis.vertical, |
| children: <Widget>[ |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: ListBody( |
| children: children, |
| ), |
| ), |
| ], |
| ), |
| ], |
| ), |
| ), |
| ], |
| ), |
| ); |
| } finally { |
| FlutterError.onError = oldHandler; |
| } |
| expect(errors, isNotEmpty); |
| expect(errors.first.exception, isFlutterError); |
| expect((errors.first.exception as FlutterError).toStringDeep(), equalsIgnoringHashCodes( |
| 'FlutterError\n' |
| ' RenderListBody must have a bounded constraint for its cross axis.\n' |
| ' RenderListBody forces its children to expand to fit the\n' |
| " RenderListBody's container, so it must be placed in a parent that\n" |
| ' constrains the cross axis to a finite dimension.\n' |
| ' If you are attempting to nest a RenderListBody with one direction\n' |
| ' inside one of another direction, you will want to wrap the inner\n' |
| ' one inside a box that fixes the dimension in that direction, for\n' |
| ' example, a RenderIntrinsicWidth or RenderIntrinsicHeight object.\n' |
| ' This is relatively expensive, however.\n', |
| )); |
| }); |
| } |