diff --git a/packages/flutter/lib/src/widgets/scroll_view.dart b/packages/flutter/lib/src/widgets/scroll_view.dart index 489fe84ee1..d5a29b926a 100644 --- a/packages/flutter/lib/src/widgets/scroll_view.dart +++ b/packages/flutter/lib/src/widgets/scroll_view.dart @@ -81,6 +81,7 @@ abstract class ScrollView extends StatelessWidget { assert(!shrinkWrap || center == null), assert(anchor != null), assert(anchor >= 0.0 && anchor <= 1.0), + assert(semanticChildCount == null || semanticChildCount >= 0), primary = primary ?? controller == null && identical(scrollDirection, Axis.vertical), physics = physics ?? (primary == true || (primary == null && controller == null && identical(scrollDirection, Axis.vertical)) ? const AlwaysScrollableScrollPhysics() : null), super(key: key); @@ -943,7 +944,9 @@ class ListView extends BoxScrollView { double cacheExtent, int semanticChildCount, DragStartBehavior dragStartBehavior = DragStartBehavior.start, - }) : childrenDelegate = SliverChildBuilderDelegate( + }) : assert(itemCount == null || itemCount >= 0), + assert(semanticChildCount == null || semanticChildCount <= itemCount), + childrenDelegate = SliverChildBuilderDelegate( itemBuilder, childCount: itemCount, addAutomaticKeepAlives: addAutomaticKeepAlives, diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 179703bec2..06645fe495 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -88,6 +88,7 @@ class Scrollable extends StatefulWidget { assert(dragStartBehavior != null), assert(viewportBuilder != null), assert(excludeFromSemantics != null), + assert(semanticChildCount == null || semanticChildCount >= 0), super (key: key); /// The direction in which this widget scrolls. @@ -643,6 +644,7 @@ class _ScrollSemantics extends SingleChildRenderObjectWidget { @required this.semanticChildCount, Widget child, }) : assert(position != null), + assert(semanticChildCount == null || semanticChildCount >= 0), super(key: key, child: child); final ScrollPosition position; diff --git a/packages/flutter/test/widgets/scroll_view_test.dart b/packages/flutter/test/widgets/scroll_view_test.dart index 895dfcc26f..1f866f4a9d 100644 --- a/packages/flutter/test/widgets/scroll_view_test.dart +++ b/packages/flutter/test/widgets/scroll_view_test.dart @@ -559,4 +559,33 @@ void main() { expect(tester.takeException(), isInstanceOf()); expect(finder, findsOneWidget); }); + + testWidgets('ListView.builder asserts on negative childCount', (WidgetTester tester) async { + expect(() => ListView.builder( + itemBuilder: (BuildContext context, int index) { + return const SizedBox(); + }, + itemCount: -1, + ), throwsA(isInstanceOf())); + }); + + testWidgets('ListView.builder asserts on negative semanticChildCount', (WidgetTester tester) async { + expect(() => ListView.builder( + itemBuilder: (BuildContext context, int index) { + return const SizedBox(); + }, + itemCount: 1, + semanticChildCount: -1, + ), throwsA(isInstanceOf())); + }); + + testWidgets('ListView.builder asserts on nonsensical childCount/semanticChildCount', (WidgetTester tester) async { + expect(() => ListView.builder( + itemBuilder: (BuildContext context, int index) { + return const SizedBox(); + }, + itemCount: 1, + semanticChildCount: 4, + ), throwsA(isInstanceOf())); + }); }