Commit 2b742289 authored by Adam Barth's avatar Adam Barth Committed by GitHub

Fix several minor bugs and add many tests (#7506)

* MultiTapGestureRecognizer previously would assert if there was no
   competition.
 * GestureArenaTeam would always select the first recongizer as the
   winner even if a later recognizer actually accepted the pointer
   sequence.
 * debugPrintStack would fail a type check if maxFrames was non-null.
 * FractionalOffset.lerp would throw a null-pointer exception if its
   second argument was null.

Also, add a number of tests for previously untested lines of code.
parent ecc49726
......@@ -339,7 +339,7 @@ class FlutterError extends AssertionError {
void debugPrintStack({ String label, int maxFrames }) {
if (label != null)
debugPrint(label);
List<String> lines = StackTrace.current.toString().trimRight().split('\n');
Iterable<String> lines = StackTrace.current.toString().trimRight().split('\n');
if (maxFrames != null)
lines = lines.take(maxFrames);
debugPrint(FlutterError.defaultStackFilter(lines).join('\n'));
......
......@@ -49,6 +49,7 @@ class PointerEventConverter {
final Point position = new Point(datum.physicalX, datum.physicalY) / devicePixelRatio;
final Duration timeStamp = datum.timeStamp;
final PointerDeviceKind kind = datum.kind;
assert(datum.change != null);
switch (datum.change) {
case ui.PointerChange.add:
assert(!_pointers.containsKey(datum.device));
......@@ -325,10 +326,6 @@ class PointerEventConverter {
radiusMax: datum.radiusMax
);
break;
default:
// TODO(ianh): once https://github.com/flutter/flutter/issues/720 is
// done, add real support for PointerAddedEvent and PointerRemovedEvent
assert(false);
}
}
}
......
......@@ -221,12 +221,6 @@ class DoubleTapGestureRecognizer extends GestureRecognizer {
String toStringShort() => 'double tap';
}
enum _TapResolution {
tap,
cancel
}
/// TapGesture represents a full gesture resulting from a single tap sequence,
/// as part of a [MultiTapGestureRecognizer]. Tap gestures are passive, meaning
/// that they will not preempt any other arena member in play.
......@@ -246,7 +240,7 @@ class _TapGesture extends _TapTracker {
if (longTapDelay > Duration.ZERO) {
_timer = new Timer(longTapDelay, () {
_timer = null;
gestureRecognizer._handleLongTap(event.pointer, _lastPosition);
gestureRecognizer._dispatchLongTap(event.pointer, _lastPosition);
});
}
}
......@@ -289,7 +283,7 @@ class _TapGesture extends _TapTracker {
void reject() {
stopTrackingPointer(handleEvent);
gestureRecognizer._resolveTap(pointer, _TapResolution.cancel, null);
gestureRecognizer._dispatchCancel(pointer);
}
void cancel() {
......@@ -303,9 +297,8 @@ class _TapGesture extends _TapTracker {
void _check() {
if (_wonArena && _finalPosition != null)
gestureRecognizer._resolveTap(pointer, _TapResolution.tap, _finalPosition);
gestureRecognizer._dispatchTap(pointer, _finalPosition);
}
}
/// Recognizes taps on a per-pointer basis.
......@@ -365,31 +358,33 @@ class MultiTapGestureRecognizer extends GestureRecognizer {
@override
void acceptGesture(int pointer) {
assert(_gestureMap.containsKey(pointer));
_gestureMap[pointer]?.accept();
assert(!_gestureMap.containsKey(pointer));
_gestureMap[pointer].accept();
}
@override
void rejectGesture(int pointer) {
assert(_gestureMap.containsKey(pointer));
_gestureMap[pointer]?.reject();
_gestureMap[pointer].reject();
assert(!_gestureMap.containsKey(pointer));
}
void _resolveTap(int pointer, _TapResolution resolution, Point globalPosition) {
void _dispatchCancel(int pointer) {
assert(_gestureMap.containsKey(pointer));
_gestureMap.remove(pointer);
if (resolution == _TapResolution.tap) {
if (onTapUp != null)
invokeCallback/*<Null>*/('onTapUp', () => onTapUp(pointer, new TapUpDetails(globalPosition: globalPosition))); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
if (onTap != null)
invokeCallback/*<Null>*/('onTap', () => onTap(pointer)); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
} else {
if (onTapCancel != null)
invokeCallback/*<Null>*/('onTapCancel', () => onTapCancel(pointer)); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
}
if (onTapCancel != null)
invokeCallback/*<Null>*/('onTapCancel', () => onTapCancel(pointer)); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
}
void _dispatchTap(int pointer, Point globalPosition) {
assert(_gestureMap.containsKey(pointer));
_gestureMap.remove(pointer);
if (onTapUp != null)
invokeCallback/*<Null>*/('onTapUp', () => onTapUp(pointer, new TapUpDetails(globalPosition: globalPosition))); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
if (onTap != null)
invokeCallback/*<Null>*/('onTap', () => onTap(pointer)); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
}
void _handleLongTap(int pointer, Point lastPosition) {
void _dispatchLongTap(int pointer, Point lastPosition) {
assert(_gestureMap.containsKey(pointer));
if (onLongTapDown != null)
invokeCallback/*<Null>*/('onLongTapDown', () => onLongTapDown(pointer, new TapDownDetails(globalPosition: lastPosition))); // ignore: STRONG_MODE_INVALID_CAST_FUNCTION_EXPR, https://github.com/dart-lang/sdk/issues/27504
......@@ -397,7 +392,7 @@ class MultiTapGestureRecognizer extends GestureRecognizer {
@override
void dispose() {
List<_TapGesture> localGestures = new List<_TapGesture>.from(_gestureMap.values);
final List<_TapGesture> localGestures = new List<_TapGesture>.from(_gestureMap.values);
for (_TapGesture gesture in localGestures)
gesture.cancel();
// Rejection of each gesture should cause it to be removed from our map
......
......@@ -33,9 +33,11 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
assert(_pointer == pointer);
assert(_winner != null || _members.isNotEmpty);
_close();
_winner ??= _members.removeAt(0);
for (GestureArenaMember member in _members)
member.rejectGesture(pointer);
_winner ??= _members[0];
for (GestureArenaMember member in _members) {
if (member != _winner)
member.rejectGesture(pointer);
}
_winner.acceptGesture(pointer);
}
......@@ -72,7 +74,7 @@ class _CombiningGestureArenaMember extends GestureArenaMember {
_entry.resolve(disposition);
} else {
assert(disposition == GestureDisposition.accepted);
_winner ?? member;
_winner ??= member;
_entry.resolve(disposition);
}
}
......
......@@ -141,7 +141,7 @@ class FractionalOffset {
if (a == null)
return new FractionalOffset(b.dx * t, b.dy * t);
if (b == null)
return new FractionalOffset(b.dx * (1.0 - t), b.dy * (1.0 - t));
return new FractionalOffset(a.dx * (1.0 - t), a.dy * (1.0 - t));
return new FractionalOffset(ui.lerpDouble(a.dx, b.dx, t), ui.lerpDouble(a.dy, b.dy, t));
}
......
......@@ -112,4 +112,40 @@ void main() {
expect(animation, hasOneLineDescription);
expect(animation.toString(), contains('no next'));
});
test('AnimationMean control test', () {
AnimationController left = new AnimationController(
value: 0.5,
vsync: const TestVSync(),
);
AnimationController right = new AnimationController(
vsync: const TestVSync(),
);
AnimationMean mean = new AnimationMean(left: left, right: right);
expect(mean, hasOneLineDescription);
expect(mean.value, equals(0.25));
List<double> log = <double>[];
void logValue() {
log.add(mean.value);
}
mean.addListener(logValue);
right.value = 1.0;
expect(mean.value, equals(0.75));
expect(log, equals(<double>[0.75]));
log.clear();
mean.removeListener(logValue);
left.value = 0.0;
expect(mean.value, equals(0.50));
expect(log, isEmpty);
});
}
......@@ -41,4 +41,12 @@ void main() {
expect(tween.lerp(0.5), 7);
expect(tween.lerp(0.7), 8);
});
test('RectTween', () {
Rect a = new Rect.fromLTWH(5.0, 3.0, 7.0, 11.0);
Rect b = new Rect.fromLTWH(8.0, 12.0, 14.0, 18.0);
RectTween tween = new RectTween(begin: a, end: b);
expect(tween.lerp(0.5), equals(Rect.lerp(a, b, 0.5)));
expect(tween, hasOneLineDescription);
});
}
// Copyright 2017 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/foundation.dart';
import 'package:test/test.dart';
import 'capture_output.dart';
void main() {
test('debugPrintStack', () {
final List<String> log = captureOutput(() {
debugPrintStack(label: 'Example label', maxFrames: 7);
});
expect(log[0], contains('Example label'));
expect(log[1], contains('debugPrintStack'));
});
test('debugPrintStack', () {
final List<String> log = captureOutput(() {
final FlutterErrorDetails details = new FlutterErrorDetails(
exception: 'Example exception',
stack: StackTrace.current,
library: 'Example library',
context: 'Example context',
informationCollector: (StringBuffer information) {
information.writeln('Example information');
},
);
FlutterError.dumpErrorToConsole(details);
});
expect(log[0], contains('EXAMPLE LIBRARY'));
expect(log[1], contains('Example context'));
expect(log[2], contains('Example exception'));
final String joined = log.join('\n');
expect(joined, contains('captureOutput'));
expect(joined, contains('\nExample information\n'));
});
}
// Copyright 2017 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/foundation.dart';
import 'package:test/test.dart';
enum _TestEnum {
a, b, c, d, e, f, g, h,
}
void main() {
test('BitField control test', () {
BitField<_TestEnum> field = new BitField<_TestEnum>(8);
expect(field[_TestEnum.d], isFalse);
field[_TestEnum.d] = true;
field[_TestEnum.e] = true;
expect(field[_TestEnum.c], isFalse);
expect(field[_TestEnum.d], isTrue);
expect(field[_TestEnum.e], isTrue);
field[_TestEnum.e] = false;
expect(field[_TestEnum.c], isFalse);
expect(field[_TestEnum.d], isTrue);
expect(field[_TestEnum.e], isFalse);
field.reset();
expect(field[_TestEnum.c], isFalse);
expect(field[_TestEnum.d], isFalse);
expect(field[_TestEnum.e], isFalse);
field.reset(true);
expect(field[_TestEnum.c], isTrue);
expect(field[_TestEnum.d], isTrue);
expect(field[_TestEnum.e], isTrue);
});
test('BitField.filed control test', () {
BitField<_TestEnum> field1 = new BitField<_TestEnum>.filled(8, true);
expect(field1[_TestEnum.d], isTrue);
BitField<_TestEnum> field2 = new BitField<_TestEnum>.filled(8, false);
expect(field2[_TestEnum.d], isFalse);
});
}
......@@ -72,4 +72,22 @@ void main() {
expect(integers, equals(<int>[1, 2, 3, 4, 5]));
expect(yieldCount, equals(5));
});
test('The Caching Iterable: take and skip', () {
Iterable<int> integers = new CachingIterable<int>(range(1, 5).iterator);
expect(yieldCount, equals(0));
Iterable<int> secondTwo = integers.skip(1).take(2);
expect(yieldCount, equals(0));
expect(secondTwo, equals(<int>[2, 3]));
expect(yieldCount, equals(3));
Iterable<int> result = integers.takeWhile((int i) => i < 4).skipWhile((int i) => i < 3);
expect(result, equals(<int>[3]));
expect(yieldCount, equals(4));
expect(integers, equals(<int>[1, 2, 3, 4, 5]));
expect(yieldCount, equals(5));
});
}
// Copyright 2017 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 'dart:async';
import 'dart:ui' show VoidCallback;
List<String> captureOutput(VoidCallback fn) {
List<String> log = <String>[];
runZoned(fn, zoneSpecification: new ZoneSpecification(
print: (Zone self,
ZoneDelegate parent,
Zone zone,
String line) {
log.add(line);
},
));
return log;
}
......@@ -84,7 +84,7 @@ void main() {
log.clear();
});
testWidgets('ChangeNotifier with mutating listener', (WidgetTester tester) async {
test('ChangeNotifier with mutating listener', () {
final TestNotifier test = new TestNotifier();
final List<String> log = <String>[];
......@@ -114,7 +114,7 @@ void main() {
log.clear();
});
testWidgets('Merging change notifiers', (WidgetTester tester) async {
test('Merging change notifiers', () {
final TestNotifier source1 = new TestNotifier();
final TestNotifier source2 = new TestNotifier();
final TestNotifier source3 = new TestNotifier();
......@@ -147,7 +147,7 @@ void main() {
log.clear();
});
testWidgets('Merging change notifiers ignores null', (WidgetTester tester) async {
test('Merging change notifiers ignores null', () {
final TestNotifier source1 = new TestNotifier();
final TestNotifier source2 = new TestNotifier();
final List<String> log = <String>[];
......@@ -161,4 +161,24 @@ void main() {
expect(log, <String>['listener', 'listener']);
log.clear();
});
test('Can dispose merged notifier', () {
final TestNotifier source1 = new TestNotifier();
final TestNotifier source2 = new TestNotifier();
final List<String> log = <String>[];
final ChangeNotifier merged = new Listenable.merge(<Listenable>[source1, source2]);
final VoidCallback listener = () { log.add('listener'); };
merged.addListener(listener);
source1.notify();
source2.notify();
expect(log, <String>['listener', 'listener']);
log.clear();
merged.dispose();
source1.notify();
source2.notify();
expect(log, isEmpty);
});
}
......@@ -2,26 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:quiver/testing/async.dart';
import 'package:test/test.dart';
List<String> captureOutput(VoidCallback fn) {
List<String> log = <String>[];
runZoned(fn, zoneSpecification: new ZoneSpecification(
print: (Zone self,
ZoneDelegate parent,
Zone zone,
String line) {
log.add(line);
},
));
return log;
}
import 'capture_output.dart';
void main() {
test('debugPrint', () {
......
......@@ -13,7 +13,7 @@ class TestDrag extends Drag {
void main() {
setUp(ensureGestureBinding);
testGesture('Should recognize pan', (GestureTester tester) {
testGesture('MultiDrag control test', (GestureTester tester) {
DelayedMultiDragGestureRecognizer drag = new DelayedMultiDragGestureRecognizer();
bool didStartDrag = false;
......
// Copyright 2017 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/gestures.dart';
import 'gesture_tester.dart';
class TestDrag extends Drag {
}
void main() {
setUp(ensureGestureBinding);
testGesture('Should recognize pan', (GestureTester tester) {
MultiTapGestureRecognizer tap = new MultiTapGestureRecognizer(longTapDelay: kLongPressTimeout);
List<String> log = <String>[];
tap.onTapDown = (int pointer, TapDownDetails details) { log.add('tap-down $pointer'); };
tap.onTapUp = (int pointer, TapUpDetails details) { log.add('tap-up $pointer'); };
tap.onTap = (int pointer) { log.add('tap $pointer'); };
tap.onLongTapDown = (int pointer, TapDownDetails details) { log.add('long-tap-down $pointer'); };
tap.onTapCancel = (int pointer) { log.add('tap-cancel $pointer'); };
TestPointer pointer5 = new TestPointer(5);
PointerDownEvent down5 = pointer5.down(const Point(10.0, 10.0));
tap.addPointer(down5);
tester.closeArena(5);
expect(log, <String>['tap-down 5']);
log.clear();
tester.route(down5);
expect(log, isEmpty);
TestPointer pointer6 = new TestPointer(6);
PointerDownEvent down6 = pointer6.down(const Point(15.0, 15.0));
tap.addPointer(down6);
tester.closeArena(6);
expect(log, <String>['tap-down 6']);
log.clear();
tester.route(down6);
expect(log, isEmpty);
tester.route(pointer5.move(const Point(11.0, 12.0)));
expect(log, isEmpty);
tester.route(pointer6.move(const Point(14.0, 13.0)));
expect(log, isEmpty);
tester.route(pointer5.up());
expect(log, <String>[
'tap-up 5',
'tap 5',
]);
log.clear();
tester.async.elapse(kLongPressTimeout + kPressTimeout);
expect(log, <String>['long-tap-down 6']);
log.clear();
tester.route(pointer6.move(const Point(4.0, 3.0)));
expect(log, <String>['tap-cancel 6']);
log.clear();
tester.route(pointer6.up());
expect(log, isEmpty);
tap.dispose();
});
}
// Copyright 2017 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/gestures.dart';
import 'gesture_tester.dart';
void main() {
setUp(ensureGestureBinding);
testGesture('GestureArenaTeam rejection test', (GestureTester tester) {
GestureArenaTeam team = new GestureArenaTeam();
HorizontalDragGestureRecognizer horizontalDrag = new HorizontalDragGestureRecognizer()..team = team;
VerticalDragGestureRecognizer verticalDrag = new VerticalDragGestureRecognizer()..team = team;
TapGestureRecognizer tap = new TapGestureRecognizer();
expect(horizontalDrag.team, equals(team));
expect(verticalDrag.team, equals(team));
expect(tap.team, isNull);
List<String> log = <String>[];
horizontalDrag.onStart = (DragStartDetails details) { log.add('hoizontal-drag-start'); };
verticalDrag.onStart = (DragStartDetails details) { log.add('vertical-drag-start'); };
tap.onTap = () { log.add('tap'); };
void test(Offset delta) {
Point origin = const Point(10.0, 10.0);
TestPointer pointer = new TestPointer(5);
PointerDownEvent down = pointer.down(origin);
horizontalDrag.addPointer(down);
verticalDrag.addPointer(down);
tap.addPointer(down);
expect(log, isEmpty);
tester.closeArena(5);
expect(log, isEmpty);
tester.route(down);
expect(log, isEmpty);
tester.route(pointer.move(origin + delta));
tester.route(pointer.up());
}
test(Offset.zero);
expect(log, <String>['tap']);
log.clear();
test(const Offset(0.0, 30.0));
expect(log, <String>['vertical-drag-start']);
log.clear();
horizontalDrag.dispose();
verticalDrag.dispose();
tap.dispose();
});
}
......@@ -20,6 +20,9 @@ void main() {
expect(insets.collapsedSize, const Size(16.0, 20.0));
expect(insets.flipped, const EdgeInsets.fromLTRB(11.0, 13.0, 5.0, 7.0));
expect(insets.along(Axis.horizontal), equals(16.0));
expect(insets.along(Axis.vertical), equals(20.0));
expect(insets.inflateRect(new Rect.fromLTRB(23.0, 32.0, 124.0, 143.0)),
new Rect.fromLTRB(18.0, 25.0, 135.0, 156.0));
......@@ -42,5 +45,9 @@ void main() {
expect(EdgeInsets.lerp(a, b, 0.25), equals(b * 0.625));
expect(EdgeInsets.lerp(a, b, 0.25), equals(a + const EdgeInsets.all(2.5)));
expect(EdgeInsets.lerp(a, b, 0.25), equals(b - const EdgeInsets.all(7.5)));
expect(EdgeInsets.lerp(null, null, 0.25), isNull);
expect(EdgeInsets.lerp(null, b, 0.25), equals(b * 0.25));
expect(EdgeInsets.lerp(a, null, 0.25), equals(a * 0.75));
});
}
// 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/painting.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('FractionalOffset control test', () {
const FractionalOffset offset = const FractionalOffset(0.5, 0.25);
expect(offset, hasOneLineDescription);
expect(offset.hashCode, equals(new FractionalOffset(0.5, 0.25).hashCode));
expect(offset / 2.0, const FractionalOffset(0.25, 0.125));
expect(offset ~/ 2.0, const FractionalOffset(0.0, 0.0));
expect(offset % 5.0, const FractionalOffset(0.5, 0.25));
});
test('FractionalOffset.lerp()', () {
FractionalOffset a = FractionalOffset.topLeft;
FractionalOffset b = FractionalOffset.topCenter;
expect(FractionalOffset.lerp(a, b, 0.25), equals(new FractionalOffset(0.125, 0.0)));
expect(FractionalOffset.lerp(null, null, 0.25), isNull);
expect(FractionalOffset.lerp(null, b, 0.25), equals(b * 0.25));
expect(FractionalOffset.lerp(a, null, 0.25), equals(a * 0.75));
});
}
// Copyright 2017 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/physics.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('Clamped simulation', () {
GravitySimulation gravity = new GravitySimulation(9.81, 10.0, 0.0, 0.0);
ClampedSimulation clamped = new ClampedSimulation(gravity, xMin: 20.0, xMax: 100.0, dxMin: 7.0, dxMax: 11.0);
expect(clamped.x(0.0), equals(20.0));
expect(clamped.dx(0.0), equals(7.0));
expect(clamped.x(100.0), equals(100.0));
expect(clamped.dx(100.0), equals(11.0));
});
}
......@@ -70,6 +70,20 @@ void main() {
expect(friction.dx(1.0), closeTo(endVelocity, epsilon));
});
test('BoundedFrictionSimulation control test', () {
BoundedFrictionSimulation friction = new BoundedFrictionSimulation(0.3, 100.0, 400.0, 50.0, 150.0);
friction.tolerance = const Tolerance(velocity: 1.0);
expect(friction.isDone(0.0), false);
expect(friction.x(0.0), 100);
expect(friction.dx(0.0), 400.0);
expect(friction.x(1.0), equals(150.0));
expect(friction.isDone(1.0), true);
});
test('test_gravity', () {
GravitySimulation gravity = new GravitySimulation(200.0, 100.0, 600.0, 0.0);
......
// Copyright 2017 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/physics.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
test('Tolerance control test', () {
expect(Tolerance.defaultTolerance, hasOneLineDescription);
});
}
// 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/scheduler.dart';
import 'package:test/test.dart';
void main() {
test('debugAssertAllSchedulerVarsUnset control test', () {
expect(() {
debugAssertAllSchedulerVarsUnset('Example test');
}, isNot(throws));
debugPrintBeginFrameBanner = true;
expect(() {
debugAssertAllSchedulerVarsUnset('Example test');
}, throws);
debugPrintBeginFrameBanner = false;
debugPrintEndFrameBanner = true;
expect(() {
debugAssertAllSchedulerVarsUnset('Example test');
}, throws);
debugPrintEndFrameBanner = false;
expect(() {
debugAssertAllSchedulerVarsUnset('Example test');
}, isNot(throws));
});
}
......@@ -66,4 +66,17 @@ void main() {
expect(ticker.isTicking, isFalse);
expect(ticker.isActive, isFalse);
});
testWidgets('Ticker control test', (WidgetTester tester) async {
Ticker ticker;
void testFunction() {
ticker = new Ticker(null);
}
testFunction();
expect(ticker, hasOneLineDescription);
expect(ticker.toString(debugIncludeStack: true), contains('testFunction'));
});
}
......@@ -24,10 +24,10 @@ void main() {
vsync: tester,
child: const SizedBox(
width: 100.0,
height: 100.0
)
)
)
height: 100.0,
),
),
),
);
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
......@@ -41,10 +41,10 @@ void main() {
vsync: tester,
child: const SizedBox(
width: 200.0,
height: 200.0
)
)
)
height: 200.0,
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
......@@ -68,10 +68,10 @@ void main() {
vsync: tester,
child: const SizedBox(
width: 100.0,
height: 100.0
)
)
)
height: 100.0,
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
......@@ -100,11 +100,11 @@ void main() {
vsync: tester,
child: const SizedBox(
width: 100.0,
height: 100.0
)
)
)
)
height: 100.0,
),
),
),
),
);
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
......@@ -121,11 +121,11 @@ void main() {
vsync: tester,
child: const SizedBox(
width: 200.0,
height: 200.0
)
)
)
)
height: 200.0,
),
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
......@@ -143,10 +143,10 @@ void main() {
child: new AnimatedContainer(
duration: const Duration(milliseconds: 100),
width: 100.0,
height: 100.0
)
)
)
height: 100.0,
),
),
),
);
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
......@@ -161,10 +161,10 @@ void main() {
child: new AnimatedContainer(
duration: const Duration(milliseconds: 100),
width: 200.0,
height: 200.0
)
)
)
height: 200.0,
),
),
),
);
await tester.pump(const Duration(milliseconds: 1)); // register change
......@@ -176,4 +176,37 @@ void main() {
expect(box.size.width, equals(200.0));
expect(box.size.height, equals(200.0));
});
testWidgets('AnimatedSize resync', (WidgetTester tester) async {
await tester.pumpWidget(
new Center(
child: new AnimatedSize(
duration: const Duration(milliseconds: 200),
vsync: const TestVSync(),
child: new SizedBox(
width: 100.0,
height: 100.0,
),
),
),
);
await tester.pumpWidget(
new Center(
child: new AnimatedSize(
duration: const Duration(milliseconds: 200),
vsync: tester,
child: new SizedBox(
width: 200.0,
height: 100.0,
),
),
),
);
await tester.pump(const Duration(milliseconds: 100));
RenderBox box = tester.renderObject(find.byType(AnimatedSize));
expect(box.size.width, equals(150.0));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment