
* comprehensive list of lints * add comments to commented out lint * fix unnecessary_this lints * exclude prefer_final_fields
184 lines
6.8 KiB
Dart
184 lines
6.8 KiB
Dart
// Copyright 2015 The Chromium 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_test/flutter_test.dart' hide TypeMatcher;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
class TestTransition extends AnimatedWidget {
|
|
TestTransition({
|
|
Key key,
|
|
this.childFirstHalf,
|
|
this.childSecondHalf,
|
|
Animation<double> animation
|
|
}) : super(key: key, listenable: animation);
|
|
|
|
final Widget childFirstHalf;
|
|
final Widget childSecondHalf;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final Animation<double> animation = listenable;
|
|
if (animation.value >= 0.5)
|
|
return childSecondHalf;
|
|
return childFirstHalf;
|
|
}
|
|
}
|
|
|
|
class TestRoute<T> extends PageRoute<T> {
|
|
TestRoute({ this.child, RouteSettings settings }) : super(settings: settings);
|
|
|
|
final Widget child;
|
|
|
|
@override
|
|
Duration get transitionDuration => const Duration(milliseconds: 150);
|
|
|
|
@override
|
|
Color get barrierColor => null;
|
|
|
|
@override
|
|
bool get maintainState => false;
|
|
|
|
@override
|
|
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
|
|
return child;
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
final Duration kTwoTenthsOfTheTransitionDuration = const Duration(milliseconds: 30);
|
|
final Duration kFourTenthsOfTheTransitionDuration = const Duration(milliseconds: 60);
|
|
|
|
testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) async {
|
|
|
|
final GlobalKey insideKey = new GlobalKey();
|
|
|
|
String state({ bool skipOffstage: true }) {
|
|
String result = '';
|
|
if (tester.any(find.text('A', skipOffstage: skipOffstage)))
|
|
result += 'A';
|
|
if (tester.any(find.text('B', skipOffstage: skipOffstage)))
|
|
result += 'B';
|
|
if (tester.any(find.text('C', skipOffstage: skipOffstage)))
|
|
result += 'C';
|
|
if (tester.any(find.text('D', skipOffstage: skipOffstage)))
|
|
result += 'D';
|
|
if (tester.any(find.text('E', skipOffstage: skipOffstage)))
|
|
result += 'E';
|
|
if (tester.any(find.text('F', skipOffstage: skipOffstage)))
|
|
result += 'F';
|
|
if (tester.any(find.text('G', skipOffstage: skipOffstage)))
|
|
result += 'G';
|
|
return result;
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
new MaterialApp(
|
|
onGenerateRoute: (RouteSettings settings) {
|
|
switch (settings.name) {
|
|
case '/':
|
|
return new TestRoute<Null>(
|
|
settings: settings,
|
|
child: new Builder(
|
|
key: insideKey,
|
|
builder: (BuildContext context) {
|
|
final PageRoute<Null> route = ModalRoute.of(context);
|
|
return new Column(
|
|
children: <Widget>[
|
|
new TestTransition(
|
|
childFirstHalf: const Text('A'),
|
|
childSecondHalf: const Text('B'),
|
|
animation: route.animation
|
|
),
|
|
new TestTransition(
|
|
childFirstHalf: const Text('C'),
|
|
childSecondHalf: const Text('D'),
|
|
animation: route.secondaryAnimation
|
|
),
|
|
]
|
|
);
|
|
}
|
|
)
|
|
);
|
|
case '/2': return new TestRoute<Null>(settings: settings, child: const Text('E'));
|
|
case '/3': return new TestRoute<Null>(settings: settings, child: const Text('F'));
|
|
case '/4': return new TestRoute<Null>(settings: settings, child: const Text('G'));
|
|
}
|
|
}
|
|
)
|
|
);
|
|
|
|
final NavigatorState navigator = insideKey.currentContext.ancestorStateOfType(const TypeMatcher<NavigatorState>());
|
|
|
|
expect(state(), equals('BC')); // transition ->1 is at 1.0
|
|
|
|
navigator.pushNamed('/2');
|
|
expect(state(), equals('BC')); // transition 1->2 is not yet built
|
|
await tester.pump();
|
|
expect(state(), equals('BC')); // transition 1->2 is at 0.0
|
|
expect(state(skipOffstage: false), equals('BCE')); // E is offstage
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BCE')); // transition 1->2 is at 0.4
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BDE')); // transition 1->2 is at 0.8
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('E')); // transition 1->2 is at 1.0
|
|
expect(state(skipOffstage: false), equals('E')); // B and C are gone, the route is inactive with maintainState=false
|
|
|
|
navigator.pop();
|
|
expect(state(), equals('E')); // transition 1<-2 is at 1.0, just reversed
|
|
await tester.pump();
|
|
await tester.pump();
|
|
|
|
expect(state(), equals('BDE')); // transition 1<-2 is at 1.0
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BDE')); // transition 1<-2 is at 0.6
|
|
|
|
navigator.pushNamed('/3');
|
|
expect(state(), equals('BDE')); // transition 1<-2 is at 0.6
|
|
await tester.pump();
|
|
expect(state(), equals('BDE')); // transition 1<-2 is at 0.6, 1->3 is at 0.0
|
|
expect(state(skipOffstage: false), equals('BDEF')); // F is offstage since we're at 0.0
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BCEF')); // transition 1<-2 is at 0.2, 1->3 is at 0.4
|
|
expect(state(skipOffstage: false), equals('BCEF')); // nothing secret going on here
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BDF')); // transition 1<-2 is done, 1->3 is at 0.8
|
|
|
|
navigator.pop();
|
|
expect(state(), equals('BDF')); // transition 1<-3 is at 0.8, just reversed
|
|
await tester.pump();
|
|
expect(state(), equals('BDF')); // transition 1<-3 is at 0.8
|
|
|
|
await tester.pump(kTwoTenthsOfTheTransitionDuration); // notice that dT=0.2 here, not 0.4
|
|
expect(state(), equals('BDF')); // transition 1<-3 is at 0.6
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BCF')); // transition 1<-3 is at 0.2
|
|
|
|
navigator.pushNamed('/4');
|
|
expect(state(), equals('BCF')); // transition 1<-3 is at 0.2, 1->4 is not yet built
|
|
await tester.pump();
|
|
expect(state(), equals('BCF')); // transition 1<-3 is at 0.2, 1->4 is at 0.0
|
|
expect(state(skipOffstage: false), equals('BCFG')); // G is offstage
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BCG')); // transition 1<-3 is done, 1->4 is at 0.4
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('BDG')); // transition 1->4 is at 0.8
|
|
|
|
await tester.pump(kFourTenthsOfTheTransitionDuration);
|
|
expect(state(), equals('G')); // transition 1->4 is done
|
|
expect(state(skipOffstage: false), equals('G')); // route 1 is not around any more
|
|
|
|
});
|
|
}
|