Jaime Blasco
Committed by GitHub

test: route tests (#268)

* test: route tests

* fix: format files
... ... @@ -13,7 +13,7 @@ jobs:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
working_directory: sheet
min_coverage: 70 # Working to reach 100% XD
min_coverage: 75 # Working to reach 100% XD
pana:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/pana.yml@v1
... ...
export 'src/route/base_route_extended.dart';
export 'src/route/cupertino/sheet_route.dart';
export 'src/route/cupertino/sheet_route.dart'
hide CupertinoSheetBottomRouteTransition;
export 'src/route/delegated_transitions_route.dart';
export 'src/route/sheet_route.dart';
... ...
... ... @@ -67,15 +67,13 @@ class _PageBasedMaterialPageRoute<T> extends MaterialExtendedPageRoute<T> {
}) : super(
settings: page,
builder: (BuildContext context) => page.child,
) {
assert(opaque);
}
);
MaterialExtendedPage<T> get _page => settings as MaterialExtendedPage<T>;
@override
Widget buildContent(BuildContext context) {
return _page.child;
return builder(context);
}
@override
... ... @@ -143,14 +141,17 @@ class CupertinoExtendedPage<T> extends Page<T> {
class _PageBasedCupertinoPageRoute<T> extends CupertinoExtendedPageRoute<T> {
_PageBasedCupertinoPageRoute({
required CupertinoExtendedPage<T> page,
}) : super(builder: (BuildContext context) => page.child) {
assert(opaque);
}
}) : super(
settings: page,
builder: (BuildContext context) => page.child,
);
CupertinoExtendedPage<T> get _page => settings as CupertinoExtendedPage<T>;
@override
Widget buildContent(BuildContext context) => _page.child;
Widget buildContent(BuildContext context) {
return builder(context);
}
@override
String? get title => _page.title;
... ...
... ... @@ -214,7 +214,7 @@ class CupertinoSheetRoute<T> extends SheetRoute<T> {
curve: Interval(0, initialExtent, curve: Curves.linear),
);
return _CupertinoSheetBottomRouteTransition(
return CupertinoSheetBottomRouteTransition(
body: child,
sheetAnimation: delayAnimation,
secondaryAnimation: secondaryAnimation,
... ... @@ -223,8 +223,9 @@ class CupertinoSheetRoute<T> extends SheetRoute<T> {
}
/// Animation for previous route when a [CupertinoSheetRoute] enters/exits
class _CupertinoSheetBottomRouteTransition extends StatelessWidget {
const _CupertinoSheetBottomRouteTransition({
@visibleForTesting
class CupertinoSheetBottomRouteTransition extends StatelessWidget {
const CupertinoSheetBottomRouteTransition({
Key? key,
required this.sheetAnimation,
required this.secondaryAnimation,
... ...
... ... @@ -129,9 +129,8 @@ class SheetRoute<T> extends PageRoute<T> with DelegatedTransitionsRoute<T> {
@override
AnimationController createAnimationController() {
assert(_routeAnimationController == null);
assert(navigator?.overlay != null);
_routeAnimationController = AnimationController(
vsync: navigator!.overlay!,
vsync: navigator!,
duration: transitionDuration,
);
return _routeAnimationController!;
... ...
... ... @@ -6,6 +6,13 @@ const Key _childKey = Key('_sheet_child');
Finder findSheet() => find.byKey(_childKey);
extension BuildContextWidgetTester on WidgetTester {
/// Gets context that can be used to push a new route into the root navigator
/// Useful when we need to test bottom sheets or alerts
BuildContext get contextForRootNavigator =>
firstElement(find.byType(Navigator));
}
extension SheetTester on WidgetTester {
Future<void> pumpApp(Widget sheet, {VoidCallback? onButtonPressed}) async {
await pumpWidget(
... ... @@ -41,28 +48,28 @@ extension SheetTester on WidgetTester {
}
double getSheetTop() {
final Offset offset = getTopLeft(find.byKey(_childKey));
final Offset offset = getTopLeft(findSheet());
return offset.dy;
}
double getSheetExtent() {
final Rect rootRect = getRect(find.byType(Sheet));
final Offset offset = getTopLeft(find.byKey(_childKey));
final Offset offset = getTopLeft(findSheet());
return rootRect.bottom - offset.dy;
}
SheetController getSheetController() {
final BuildContext context = element(find.byKey(_childKey));
final BuildContext context = element(findSheet());
return Sheet.of(context)!.controller;
}
SheetPosition getSheetPosition() {
final BuildContext context = element(find.byKey(_childKey));
final BuildContext context = element(findSheet());
return Sheet.of(context)!.position;
}
double getSheetHeight() {
final Size rect = getSize(find.byKey(_childKey));
final Size rect = getSize(findSheet());
return rect.height;
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/route.dart';
import '../../helpers.dart';
void main() {
group('MaterialExtendedPageRoute', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpApp(SizedBox());
Navigator.of(tester.contextForRootNavigator).push(
MaterialExtendedPageRoute(builder: (context) => Text('child')),
);
await tester.pumpAndSettle();
expect(find.text('child'), findsOneWidget);
});
test('is a PreviousSheetRouteMixin', () {
expect(
MaterialExtendedPageRoute(builder: (context) => Text('child')),
isA<PreviousSheetRouteMixin>(),
);
});
test('is a DelegatedTransitionsRoute', () {
expect(
MaterialExtendedPageRoute(builder: (context) => Text('child')),
isA<DelegatedTransitionsRoute>(),
);
});
test('is a MaterialPageRoute', () {
expect(
MaterialExtendedPageRoute(builder: (context) => Text('child')),
isA<MaterialPageRoute>(),
);
});
});
group('MaterialExtendedPage', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
MaterialExtendedPage(child: Text('child')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(find.text('child'), findsOneWidget);
});
testWidgets('route is a MaterialExtendedPageRoute',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [MaterialPage(child: SizedBox())],
onPopPage: (route, result) => false,
);
},
));
expect(
MaterialExtendedPage(child: Text('child'))
.createRoute(tester.contextForRootNavigator),
isA<MaterialExtendedPageRoute>(),
);
});
testWidgets('params are passed to route', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [MaterialPage(child: SizedBox())],
onPopPage: (route, result) => false,
);
},
));
final page = MaterialExtendedPage(
child: Text('child'),
fullscreenDialog: true,
maintainState: false,
);
expect(
page.createRoute(tester.contextForRootNavigator),
isA<MaterialExtendedPageRoute>()
.having(
(p) => p.fullscreenDialog,
'fullscreenDialog',
isTrue,
)
.having(
(p) => p.settings,
'settings',
page,
)
.having(
(p) => p.maintainState,
'maintainState',
isFalse,
),
);
});
});
group('CupertinoExtendedPageRoute', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpApp(SizedBox());
Navigator.of(tester.contextForRootNavigator).push(
CupertinoExtendedPageRoute(builder: (context) => Text('child')),
);
await tester.pumpAndSettle();
expect(find.text('child'), findsOneWidget);
});
test('is a PreviousSheetRouteMixin', () {
expect(
CupertinoExtendedPageRoute(builder: (context) => Text('child')),
isA<PreviousSheetRouteMixin>(),
);
});
test('is a DelegatedTransitionsRoute', () {
expect(
CupertinoExtendedPageRoute(builder: (context) => Text('child')),
isA<DelegatedTransitionsRoute>(),
);
});
test('is a CupertinoPageRoute', () {
expect(
CupertinoExtendedPageRoute(builder: (context) => Text('child')),
isA<CupertinoPageRoute>(),
);
});
});
group('CupertinoExtendedPage', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
CupertinoExtendedPage(child: Text('child')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(find.text('child'), findsOneWidget);
});
testWidgets('route is a CupertinoExtendedPageRoute',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [MaterialPage(child: SizedBox())],
onPopPage: (route, result) => false,
);
},
));
expect(
CupertinoExtendedPage(child: Text('child'))
.createRoute(tester.contextForRootNavigator),
isA<CupertinoExtendedPageRoute>(),
);
});
testWidgets('params are passed to route', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [MaterialPage(child: SizedBox())],
onPopPage: (route, result) => false,
);
},
));
final page = CupertinoExtendedPage(
child: Text('child'),
title: 'Title',
fullscreenDialog: true,
maintainState: false,
);
expect(
page.createRoute(tester.contextForRootNavigator),
isA<CupertinoExtendedPageRoute>()
.having(
(p) => p.fullscreenDialog,
'fullscreenDialog',
isTrue,
)
.having(
(p) => p.settings,
'settings',
page,
)
.having(
(p) => p.maintainState,
'maintainState',
isFalse,
)
.having(
(p) => p.title,
'title',
equals('Title'),
),
);
});
});
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/route.dart';
import 'package:sheet/src/route/cupertino/sheet_route.dart';
import '../../../helpers.dart';
void main() {
group('CupertinoSheetRoute', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpApp(SizedBox());
Navigator.of(tester.contextForRootNavigator).push(
CupertinoSheetRoute(builder: (context) => Text('Sheet')),
);
await tester.pumpAndSettle();
expect(findSheet(), findsOneWidget);
expect(find.text('Sheet'), findsOneWidget);
});
testWidgets('animates previous route when using MaterialExtendedPageRoute',
(WidgetTester tester) async {
await tester.pumpApp(SizedBox());
final controller = Navigator.of(tester.contextForRootNavigator);
controller.push(
MaterialExtendedPageRoute(builder: (context) => SizedBox()),
);
await tester.pumpAndSettle();
controller.push(
CupertinoSheetRoute(builder: (context) => Text('Sheet')),
);
await tester.pumpAndSettle();
expect(find.byType(CupertinoSheetBottomRouteTransition), findsOneWidget);
});
testWidgets('animates previous route when using CupertinoExtendedPageRoute',
(WidgetTester tester) async {
await tester.pumpApp(SizedBox());
final controller = Navigator.of(tester.contextForRootNavigator);
controller.push(
CupertinoExtendedPageRoute(builder: (context) => SizedBox()),
);
await tester.pumpAndSettle();
controller.push(
CupertinoSheetRoute(builder: (context) => Text('Sheet')),
);
await tester.pumpAndSettle();
expect(find.byType(CupertinoSheetBottomRouteTransition), findsOneWidget);
});
});
group('CupertinoSheetPage', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
MaterialPage(child: SizedBox()),
CupertinoSheetPage(child: Text('Sheet')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(findSheet(), findsOneWidget);
expect(find.text('Sheet'), findsOneWidget);
});
testWidgets('animates previous route when using MaterialExtendedPage',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
MaterialExtendedPage(child: SizedBox()),
CupertinoSheetPage(child: Text('Sheet')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(find.byType(CupertinoSheetBottomRouteTransition), findsOneWidget);
});
testWidgets('animates previous route when using CupertinoExtendedPage',
(WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
CupertinoExtendedPage(child: SizedBox()),
CupertinoSheetPage(child: Text('Sheet')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(find.byType(CupertinoSheetBottomRouteTransition), findsOneWidget);
});
});
}
... ...
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/route.dart';
import '../../helpers.dart';
void main() {
group('SheetRoute', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpApp(SizedBox());
Navigator.of(tester.contextForRootNavigator).push(
SheetRoute(builder: (context) => Text('Sheet')),
);
await tester.pumpAndSettle();
expect(findSheet(), findsOneWidget);
expect(find.text('Sheet'), findsOneWidget);
});
});
group('SheetPage', () {
testWidgets('renders', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
builder: (context, child) {
return Navigator(
pages: [
MaterialPage(child: SizedBox()),
SheetPage(child: Text('Sheet')),
],
onPopPage: (route, result) => false,
);
},
));
await tester.pumpAndSettle();
expect(findSheet(), findsOneWidget);
expect(find.text('Sheet'), findsOneWidget);
});
});
}
... ...
... ... @@ -2,77 +2,67 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../../../helpers.dart';
void main() {
group('SheetController.animation', () {
testWidgets('is 0 when starts in minExtent', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 400,
initialExtent: 100,
child: SizedBox(height: 400),
),
),
);
expect(tester.getSheetController().animation.value, 0);
});
testWidgets('is 1 when starts in maxExtent', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 400,
initialExtent: 400,
child: SizedBox(height: 400),
),
),
);
expect(tester.getSheetController().animation.value, 1);
});
testWidgets('is 0.5 when is between minExtent and maxExtent',
(tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 300,
initialExtent: 200,
child: SizedBox(height: 300),
),
),
);
expect(tester.getSheetController().animation.value, 0.5);
});
testWidgets('is 1 when minExtent equals maxExtent', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 100,
child: SizedBox(height: 100),
),
),
);
expect(tester.getSheetController().animation.value, 1);
});
testWidgets('updates to 0 when it goes to minExtent', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 400,
initialExtent: 400,
fit: SheetFit.expand,
child: SizedBox(),
),
),
);
expect(tester.getSheetController().animation.value, 1);
tester.getSheetController().relativeJumpTo(0);
... ... @@ -81,15 +71,13 @@ void main() {
});
testWidgets('updates to 1 when it goes to maxExtent', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 400,
initialExtent: 100,
child: SizedBox(height: 400),
),
),
);
expect(tester.getSheetController().animation.value, 0);
tester.getSheetController().relativeJumpTo(1);
... ... @@ -97,15 +85,13 @@ void main() {
});
testWidgets('updates linearly', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: Sheet(
await tester.pumpApp(
Sheet(
minExtent: 100,
maxExtent: 300,
initialExtent: 100,
child: SizedBox(height: 300),
),
),
);
tester.getSheetController().relativeJumpTo(0.5);
await tester.pumpAndSettle();
... ...
... ... @@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('bounce', () {
... ...
... ... @@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('fit', () {
... ...
... ... @@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('Initial extent', () {
... ...
... ... @@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('Sheet linear drags', () {
... ...
... ... @@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('Sheet with resizable', () {
... ...
... ... @@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../screen_size_test.dart';
import '../../../helpers.dart';
import '../../../screen_size_test.dart';
void main() {
group('SheetController', () {
... ...
... ... @@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:sheet/sheet.dart';
import '../helpers.dart';
import '../../../helpers.dart';
void main() {
group('SheetPosition', () {
... ...