284 lines
8.7 KiB
Dart
284 lines
8.7 KiB
Dart
// Copyright 2016 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';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:flutter/widgets.dart';
|
|
|
|
class TestPaintingContext implements PaintingContext {
|
|
final List<Invocation> invocations = <Invocation>[];
|
|
|
|
@override
|
|
void noSuchMethod(Invocation invocation) {
|
|
invocations.add(invocation);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
group('AnimatedSize', () {
|
|
testWidgets('animates forwards then backwards with stable-sized children', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(100.0));
|
|
expect(box.size.height, equals(100.0));
|
|
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 200.0,
|
|
height: 200.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(150.0));
|
|
expect(box.size.height, equals(150.0));
|
|
|
|
TestPaintingContext context = new TestPaintingContext();
|
|
box.paint(context, Offset.zero);
|
|
expect(context.invocations.first.memberName, equals(#pushClipRect));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(200.0));
|
|
expect(box.size.height, equals(200.0));
|
|
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(150.0));
|
|
expect(box.size.height, equals(150.0));
|
|
|
|
context = new TestPaintingContext();
|
|
box.paint(context, Offset.zero);
|
|
expect(context.invocations.first.memberName, equals(#paintChild));
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(100.0));
|
|
expect(box.size.height, equals(100.0));
|
|
});
|
|
|
|
testWidgets('clamps animated size to constraints', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new SizedBox (
|
|
width: 100.0,
|
|
height: 100.0,
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(100.0));
|
|
expect(box.size.height, equals(100.0));
|
|
|
|
// Attempt to animate beyond the outer SizedBox.
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new SizedBox (
|
|
width: 100.0,
|
|
height: 100.0,
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 200.0,
|
|
height: 200.0,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Verify that animated size is the same as the outer SizedBox.
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(100.0));
|
|
expect(box.size.height, equals(100.0));
|
|
});
|
|
|
|
testWidgets('tracks unstable child, then resumes animation when child stabilizes', (WidgetTester tester) async {
|
|
Future<Null> pumpMillis(int millis) async {
|
|
await tester.pump(new Duration(milliseconds: millis));
|
|
}
|
|
|
|
void verify({double size, RenderAnimatedSizeState state}) {
|
|
assert(size != null || state != null);
|
|
final RenderAnimatedSize box = tester.renderObject(find.byType(AnimatedSize));
|
|
if (size != null) {
|
|
expect(box.size.width, size);
|
|
expect(box.size.height, size);
|
|
}
|
|
if (state != null) {
|
|
expect(box.state, state);
|
|
}
|
|
}
|
|
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: new AnimatedContainer(
|
|
duration: const Duration(milliseconds: 100),
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
verify(size: 100.0, state: RenderAnimatedSizeState.stable);
|
|
|
|
// Animate child size from 100 to 200 slowly (100ms).
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: new AnimatedContainer(
|
|
duration: const Duration(milliseconds: 100),
|
|
width: 200.0,
|
|
height: 200.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
// Make sure animation proceeds at child's pace, with AnimatedSize
|
|
// tightly tracking the child's size.
|
|
verify(state: RenderAnimatedSizeState.stable);
|
|
await pumpMillis(1); // register change
|
|
verify(state: RenderAnimatedSizeState.changed);
|
|
await pumpMillis(49);
|
|
verify(size: 150.0, state: RenderAnimatedSizeState.unstable);
|
|
await pumpMillis(50);
|
|
verify(size: 200.0, state: RenderAnimatedSizeState.unstable);
|
|
|
|
// Stabilize size
|
|
await pumpMillis(50);
|
|
verify(size: 200.0, state: RenderAnimatedSizeState.stable);
|
|
|
|
// Quickly (in 1ms) change size back to 100
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: new AnimatedContainer(
|
|
duration: const Duration(milliseconds: 1),
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
verify(size: 200.0, state: RenderAnimatedSizeState.stable);
|
|
await pumpMillis(1); // register change
|
|
verify(state: RenderAnimatedSizeState.changed);
|
|
await pumpMillis(100);
|
|
verify(size: 150.0, state: RenderAnimatedSizeState.stable);
|
|
await pumpMillis(100);
|
|
verify(size: 100.0, state: RenderAnimatedSizeState.stable);
|
|
});
|
|
|
|
testWidgets('resyncs its animation controller', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const Center(
|
|
child: AnimatedSize(
|
|
duration: Duration(milliseconds: 200),
|
|
vsync: TestVSync(),
|
|
child: SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 200.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
|
|
final RenderBox box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, equals(150.0));
|
|
});
|
|
|
|
testWidgets('does not run animation unnecessarily', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
new Center(
|
|
child: new AnimatedSize(
|
|
duration: const Duration(milliseconds: 200),
|
|
vsync: tester,
|
|
child: const SizedBox(
|
|
width: 100.0,
|
|
height: 100.0,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
for (int i = 0; i < 20; i++) {
|
|
final RenderAnimatedSize box = tester.renderObject(find.byType(AnimatedSize));
|
|
expect(box.size.width, 100.0);
|
|
expect(box.size.height, 100.0);
|
|
expect(box.state, RenderAnimatedSizeState.stable);
|
|
expect(box.isAnimating, false);
|
|
await tester.pump(const Duration(milliseconds: 10));
|
|
}
|
|
});
|
|
});
|
|
}
|