mirror of
https://github.com/flutter/flutter.git
synced 2026-02-15 07:11:44 +08:00
Improve test coverage (#7430)
Also, make the exception handling for global key listeners slightly more robust.
This commit is contained in:
parent
42ccffca36
commit
2ee04c92bf
@ -151,7 +151,7 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
|
||||
void _register(Element element) {
|
||||
assert(() {
|
||||
if (_registry.containsKey(this)) {
|
||||
int oldCount = _debugDuplicates.putIfAbsent(this, () => 1);
|
||||
final int oldCount = _debugDuplicates.putIfAbsent(this, () => 1);
|
||||
assert(oldCount >= 1);
|
||||
_debugDuplicates[this] = oldCount + 1;
|
||||
}
|
||||
@ -163,7 +163,7 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
|
||||
void _unregister(Element element) {
|
||||
assert(() {
|
||||
if (_registry.containsKey(this) && _debugDuplicates.containsKey(this)) {
|
||||
int oldCount = _debugDuplicates[this];
|
||||
final int oldCount = _debugDuplicates[this];
|
||||
assert(oldCount >= 2);
|
||||
if (oldCount == 2) {
|
||||
_debugDuplicates.remove(this);
|
||||
@ -257,17 +257,19 @@ abstract class GlobalKey<T extends State<StatefulWidget>> extends Key {
|
||||
for (GlobalKey key in _removedKeys) {
|
||||
if (!_registry.containsKey(key) && _removeListeners.containsKey(key)) {
|
||||
Set<GlobalKeyRemoveListener> localListeners = new HashSet<GlobalKeyRemoveListener>.from(_removeListeners[key]);
|
||||
for (GlobalKeyRemoveListener listener in localListeners)
|
||||
listener(key);
|
||||
for (GlobalKeyRemoveListener listener in localListeners) {
|
||||
try {
|
||||
listener(key);
|
||||
} catch (e, stack) {
|
||||
_debugReportException('while notifying GlobalKey listener', e, stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e, stack) {
|
||||
_debugReportException('while notifying GlobalKey listeners', e, stack);
|
||||
} finally {
|
||||
_removedKeys.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// A global key with a debugging label.
|
||||
|
||||
@ -525,7 +525,6 @@ class _GestureSemantics extends SingleChildRenderObjectWidget {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void _handleVerticalDragUpdate(DragUpdateDetails updateDetails) {
|
||||
@ -553,7 +552,6 @@ class _GestureSemantics extends SingleChildRenderObjectWidget {
|
||||
return;
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -72,6 +72,20 @@ class MediaQueryData {
|
||||
return size.width > size.height ? Orientation.landscape : Orientation.portrait;
|
||||
}
|
||||
|
||||
MediaQueryData copyWith({
|
||||
Size size,
|
||||
double devicePixelRatio,
|
||||
double textScaleFactor,
|
||||
EdgeInsets padding,
|
||||
}) {
|
||||
return new MediaQueryData(
|
||||
size: size ?? this.size,
|
||||
devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio,
|
||||
textScaleFactor: textScaleFactor ?? this.textScaleFactor,
|
||||
padding: padding ?? this.padding,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType)
|
||||
|
||||
@ -6,8 +6,6 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'animation_tester.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -206,17 +204,17 @@ void main() {
|
||||
duration: const Duration(milliseconds: 100),
|
||||
vsync: const TestVSync(),
|
||||
);
|
||||
expect(controller.toString(), hasOneLineDescription);
|
||||
expect(controller, hasOneLineDescription);
|
||||
controller.forward();
|
||||
WidgetsBinding.instance.handleBeginFrame(const Duration(milliseconds: 10));
|
||||
WidgetsBinding.instance.handleBeginFrame(const Duration(milliseconds: 20));
|
||||
expect(controller.toString(), hasOneLineDescription);
|
||||
expect(controller, hasOneLineDescription);
|
||||
WidgetsBinding.instance.handleBeginFrame(const Duration(milliseconds: 30));
|
||||
expect(controller.toString(), hasOneLineDescription);
|
||||
expect(controller, hasOneLineDescription);
|
||||
controller.reverse();
|
||||
WidgetsBinding.instance.handleBeginFrame(const Duration(milliseconds: 40));
|
||||
WidgetsBinding.instance.handleBeginFrame(const Duration(milliseconds: 50));
|
||||
expect(controller.toString(), hasOneLineDescription);
|
||||
expect(controller, hasOneLineDescription);
|
||||
controller.stop();
|
||||
});
|
||||
|
||||
|
||||
@ -6,8 +6,6 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'animation_tester.dart';
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
@ -15,16 +13,16 @@ void main() {
|
||||
});
|
||||
|
||||
test('toString control test', () {
|
||||
expect(kAlwaysCompleteAnimation.toString(), hasOneLineDescription);
|
||||
expect(kAlwaysDismissedAnimation.toString(), hasOneLineDescription);
|
||||
expect(const AlwaysStoppedAnimation<double>(0.5).toString(), hasOneLineDescription);
|
||||
expect(kAlwaysCompleteAnimation, hasOneLineDescription);
|
||||
expect(kAlwaysDismissedAnimation, hasOneLineDescription);
|
||||
expect(const AlwaysStoppedAnimation<double>(0.5), hasOneLineDescription);
|
||||
CurvedAnimation curvedAnimation = new CurvedAnimation(
|
||||
parent: kAlwaysDismissedAnimation,
|
||||
curve: Curves.ease
|
||||
);
|
||||
expect(curvedAnimation.toString(), hasOneLineDescription);
|
||||
expect(curvedAnimation, hasOneLineDescription);
|
||||
curvedAnimation.reverseCurve = Curves.elasticOut;
|
||||
expect(curvedAnimation.toString(), hasOneLineDescription);
|
||||
expect(curvedAnimation, hasOneLineDescription);
|
||||
AnimationController controller = new AnimationController(
|
||||
duration: const Duration(milliseconds: 500),
|
||||
vsync: const TestVSync(),
|
||||
@ -37,7 +35,7 @@ void main() {
|
||||
curve: Curves.ease,
|
||||
reverseCurve: Curves.elasticOut
|
||||
);
|
||||
expect(curvedAnimation.toString(), hasOneLineDescription);
|
||||
expect(curvedAnimation, hasOneLineDescription);
|
||||
controller.stop();
|
||||
});
|
||||
|
||||
@ -45,9 +43,9 @@ void main() {
|
||||
ProxyAnimation animation = new ProxyAnimation();
|
||||
expect(animation.value, 0.0);
|
||||
expect(animation.status, AnimationStatus.dismissed);
|
||||
expect(animation.toString(), hasOneLineDescription);
|
||||
expect(animation, hasOneLineDescription);
|
||||
animation.parent = kAlwaysDismissedAnimation;
|
||||
expect(animation.toString(), hasOneLineDescription);
|
||||
expect(animation, hasOneLineDescription);
|
||||
});
|
||||
|
||||
test('ProxyAnimation set parent generates value changed', () {
|
||||
@ -88,7 +86,7 @@ void main() {
|
||||
expect(didReceiveCallback, isFalse);
|
||||
controller.value = 0.7;
|
||||
expect(didReceiveCallback, isFalse);
|
||||
expect(animation.toString(), hasOneLineDescription);
|
||||
expect(animation, hasOneLineDescription);
|
||||
});
|
||||
|
||||
test('TrainHoppingAnimation', () {
|
||||
@ -107,11 +105,11 @@ void main() {
|
||||
});
|
||||
expect(didSwitchTrains, isFalse);
|
||||
expect(animation.value, 0.5);
|
||||
expect(animation.toString(), hasOneLineDescription);
|
||||
expect(animation, hasOneLineDescription);
|
||||
nextTrain.value = 0.25;
|
||||
expect(didSwitchTrains, isTrue);
|
||||
expect(animation.value, 0.25);
|
||||
expect(animation.toString(), hasOneLineDescription);
|
||||
expect(animation, hasOneLineDescription);
|
||||
expect(animation.toString(), contains('no next'));
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,8 +6,6 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter/animation.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import 'animation_tester.dart';
|
||||
|
||||
void main() {
|
||||
test('Can chain tweens', () {
|
||||
Tween<double> tween = new Tween<double>(begin: 0.30, end: 0.50);
|
||||
|
||||
@ -9,7 +9,7 @@ void main() {
|
||||
test('HSVColor control test', () {
|
||||
const HSVColor color = const HSVColor.fromAHSV(0.7, 28.0, 0.3, 0.6);
|
||||
|
||||
expect(color.toString(), hasOneLineDescription);
|
||||
expect(color, hasOneLineDescription);
|
||||
expect(color.hashCode, equals(new HSVColor.fromAHSV(0.7, 28.0, 0.3, 0.6).hashCode));
|
||||
|
||||
expect(color.withAlpha(0.8), const HSVColor.fromAHSV(0.8, 28.0, 0.3, 0.6));
|
||||
|
||||
@ -9,7 +9,7 @@ void main() {
|
||||
test('EdgeInsets control test', () {
|
||||
const EdgeInsets insets = const EdgeInsets.fromLTRB(5.0, 7.0, 11.0, 13.0);
|
||||
|
||||
expect(insets.toString(), hasOneLineDescription);
|
||||
expect(insets, hasOneLineDescription);
|
||||
expect(insets.hashCode, equals(new EdgeInsets.fromLTRB(5.0, 7.0, 11.0, 13.0).hashCode));
|
||||
|
||||
expect(insets.topLeft, const Offset(5.0, 7.0));
|
||||
|
||||
81
packages/flutter/test/widgets/framework_test.dart
Normal file
81
packages/flutter/test/widgets/framework_test.dart
Normal file
@ -0,0 +1,81 @@
|
||||
// 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';
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('UniqueKey control test', (WidgetTester tester) async {
|
||||
Key key = new UniqueKey();
|
||||
expect(key, hasOneLineDescription);
|
||||
expect(key, isNot(equals(new UniqueKey())));
|
||||
});
|
||||
|
||||
testWidgets('ObjectKey control test', (WidgetTester tester) async {
|
||||
Object a = new Object();
|
||||
Object b = new Object();
|
||||
Key keyA = new ObjectKey(a);
|
||||
Key keyA2 = new ObjectKey(a);
|
||||
Key keyB = new ObjectKey(b);
|
||||
|
||||
expect(keyA, hasOneLineDescription);
|
||||
expect(keyA, equals(keyA2));
|
||||
expect(keyA.hashCode, equals(keyA2.hashCode));
|
||||
expect(keyA, isNot(equals(keyB)));
|
||||
});
|
||||
|
||||
testWidgets('GlobalKey duplication', (WidgetTester tester) async {
|
||||
Key key = new GlobalKey(debugLabel: 'problematic');
|
||||
|
||||
await tester.pumpWidget(new Stack(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
key: const ValueKey<int>(1),
|
||||
),
|
||||
new Container(
|
||||
key: const ValueKey<int>(2),
|
||||
),
|
||||
new Container(
|
||||
key: key
|
||||
),
|
||||
],
|
||||
));
|
||||
|
||||
await tester.pumpWidget(new Stack(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
key: const ValueKey<int>(1),
|
||||
child: new SizedBox(key: key),
|
||||
),
|
||||
new Container(
|
||||
key: const ValueKey<int>(2),
|
||||
child: new Placeholder(key: key),
|
||||
),
|
||||
],
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNotNull);
|
||||
});
|
||||
|
||||
testWidgets('GlobalKey notification exception handling', (WidgetTester tester) async {
|
||||
GlobalKey key = new GlobalKey();
|
||||
|
||||
await tester.pumpWidget(new Container(key: key));
|
||||
|
||||
GlobalKey.registerRemoveListener(key, (GlobalKey key) {
|
||||
throw new Exception('Misbehaving listener');
|
||||
});
|
||||
|
||||
bool didReceiveCallback = false;
|
||||
GlobalKey.registerRemoveListener(key, (GlobalKey key) {
|
||||
expect(didReceiveCallback, isFalse);
|
||||
didReceiveCallback = true;
|
||||
});
|
||||
|
||||
await tester.pumpWidget(new Placeholder());
|
||||
|
||||
expect(tester.takeException(), isNotNull);
|
||||
expect(didReceiveCallback, isTrue);
|
||||
});
|
||||
}
|
||||
@ -14,7 +14,10 @@ void main() {
|
||||
await tester.pumpWidget(
|
||||
new Builder(
|
||||
builder: (BuildContext context) {
|
||||
size = MediaQuery.of(context).size;
|
||||
final MediaQueryData data = MediaQuery.of(context);
|
||||
expect(data, hasOneLineDescription);
|
||||
expect(data.hashCode, equals(data.copyWith().hashCode));
|
||||
size = data.size;
|
||||
return new Container();
|
||||
}
|
||||
)
|
||||
|
||||
13
packages/flutter/test/widgets/performance_overlay_test.dart
Normal file
13
packages/flutter/test/widgets/performance_overlay_test.dart
Normal file
@ -0,0 +1,13 @@
|
||||
// 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/widgets.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Performance overlay smoke test', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new PerformanceOverlay());
|
||||
await tester.pumpWidget(new PerformanceOverlay.allEnabled());
|
||||
});
|
||||
}
|
||||
22
packages/flutter/test/widgets/placeholder_test.dart
Normal file
22
packages/flutter/test/widgets/placeholder_test.dart
Normal file
@ -0,0 +1,22 @@
|
||||
// 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/widgets.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Placeholder control test', (WidgetTester tester) async {
|
||||
GlobalKey<PlaceholderState> key = new GlobalKey<PlaceholderState>();
|
||||
|
||||
await tester.pumpWidget(new Placeholder(key: key));
|
||||
|
||||
key.currentState.child = new Text('target');
|
||||
|
||||
expect(find.text('target'), findsNothing);
|
||||
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('target'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
@ -18,6 +18,7 @@ void sendFakeKeyEvent(Map<String, dynamic> data) {
|
||||
|
||||
void main() {
|
||||
testWidgets('Can dispose without keyboard', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(new RawKeyboardListener(child: new Container()));
|
||||
await tester.pumpWidget(new RawKeyboardListener(child: new Container()));
|
||||
await tester.pumpWidget(new Container());
|
||||
});
|
||||
|
||||
@ -96,6 +96,11 @@ Future<Null> runNavigatorTest(
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Route settings', (WidgetTester tester) async {
|
||||
RouteSettings settings = const RouteSettings(name: 'A');
|
||||
expect(settings, hasOneLineDescription);
|
||||
});
|
||||
|
||||
testWidgets('Route management - push, replace, pop', (WidgetTester tester) async {
|
||||
GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();
|
||||
await tester.pumpWidget(new Navigator(
|
||||
@ -320,6 +325,7 @@ void main() {
|
||||
'B: didChangeNext C',
|
||||
]
|
||||
);
|
||||
expect(routeC.isActive, isTrue);
|
||||
TestRoute routeB;
|
||||
await runNavigatorTest(
|
||||
tester,
|
||||
|
||||
@ -14,13 +14,13 @@ void main() {
|
||||
children: <Widget>[
|
||||
new Semantics(),
|
||||
new Semantics(
|
||||
container: true
|
||||
container: true,
|
||||
),
|
||||
new Semantics(
|
||||
label: 'label'
|
||||
label: 'label',
|
||||
),
|
||||
]
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -29,20 +29,21 @@ void main() {
|
||||
children: <Widget>[
|
||||
new Semantics(),
|
||||
new Semantics(
|
||||
container: true
|
||||
container: true,
|
||||
),
|
||||
new Semantics(
|
||||
label: 'label'
|
||||
label: 'label',
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(true, isTrue); // expect that we reach here without crashing
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger reparents subtree', (WidgetTester tester) async {
|
||||
testWidgets('SemanticsDebugger reparents subtree',
|
||||
(WidgetTester tester) async {
|
||||
GlobalKey key = new GlobalKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -51,12 +52,16 @@ void main() {
|
||||
children: <Widget>[
|
||||
new Semantics(label: 'label1'),
|
||||
new Positioned(
|
||||
key: key, left: 0.0, top: 0.0, width: 100.0, height: 100.0,
|
||||
child: new Semantics(label: 'label2')
|
||||
key: key,
|
||||
left: 0.0,
|
||||
top: 0.0,
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
child: new Semantics(label: 'label2'),
|
||||
),
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -69,16 +74,20 @@ void main() {
|
||||
child: new Stack(
|
||||
children: <Widget>[
|
||||
new Positioned(
|
||||
key: key, left: 0.0, top: 0.0, width: 100.0, height: 100.0,
|
||||
child: new Semantics(label: 'label2')
|
||||
key: key,
|
||||
left: 0.0,
|
||||
top: 0.0,
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
child: new Semantics(label: 'label2'),
|
||||
),
|
||||
new Semantics(label: 'label3'),
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -91,19 +100,180 @@ void main() {
|
||||
child: new Stack(
|
||||
children: <Widget>[
|
||||
new Positioned(
|
||||
key: key, left: 0.0, top: 0.0, width: 100.0, height: 100.0,
|
||||
child: new Semantics(label: 'label2')
|
||||
),
|
||||
key: key,
|
||||
left: 0.0,
|
||||
top: 0.0,
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
child: new Semantics(label: 'label2')),
|
||||
new Semantics(label: 'label3'),
|
||||
new Semantics(label: 'label4'),
|
||||
]
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger interaction test',
|
||||
(WidgetTester tester) async {
|
||||
final List<String> log = <String>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
new SemanticsDebugger(
|
||||
child: new Material(
|
||||
child: new Block(children: <Widget>[
|
||||
new RaisedButton(
|
||||
onPressed: () {
|
||||
log.add('top');
|
||||
},
|
||||
child: new Text('TOP'),
|
||||
),
|
||||
new RaisedButton(
|
||||
onPressed: () {
|
||||
log.add('bottom');
|
||||
},
|
||||
child: new Text('BOTTOM'),
|
||||
),
|
||||
]),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('TOP'));
|
||||
expect(log, equals(<String>['top']));
|
||||
log.clear();
|
||||
|
||||
await tester.tap(find.text('BOTTOM'));
|
||||
expect(log, equals(<String>['bottom']));
|
||||
log.clear();
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger scroll test', (WidgetTester tester) async {
|
||||
Key childKey = new UniqueKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
new SemanticsDebugger(
|
||||
child: new Block(
|
||||
children: <Widget>[
|
||||
new Container(
|
||||
key: childKey,
|
||||
height: 5000.0,
|
||||
decoration:
|
||||
new BoxDecoration(backgroundColor: Colors.green[500]),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(tester.getTopLeft(find.byKey(childKey)).y, equals(0.0));
|
||||
|
||||
await tester.fling(find.byType(Block), const Offset(0.0, -200.0), 200.0);
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getTopLeft(find.byKey(childKey)).y, equals(-480.0));
|
||||
|
||||
await tester.fling(find.byType(Block), const Offset(200.0, 0.0), 200.0);
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getTopLeft(find.byKey(childKey)).y, equals(-480.0));
|
||||
|
||||
await tester.fling(find.byType(Block), const Offset(-200.0, 0.0), 200.0);
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getTopLeft(find.byKey(childKey)).y, equals(-480.0));
|
||||
|
||||
await tester.fling(find.byType(Block), const Offset(0.0, 200.0), 200.0);
|
||||
await tester.pump();
|
||||
|
||||
expect(tester.getTopLeft(find.byKey(childKey)).y, equals(0.0));
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger long press', (WidgetTester tester) async {
|
||||
bool didLongPress = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
new SemanticsDebugger(
|
||||
child: new GestureDetector(
|
||||
onLongPress: () {
|
||||
expect(didLongPress, isFalse);
|
||||
didLongPress = true;
|
||||
},
|
||||
child: new Text('target'),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.longPress(find.text('target'));
|
||||
expect(didLongPress, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger slider', (WidgetTester tester) async {
|
||||
double value = 0.75;
|
||||
|
||||
await tester.pumpWidget(
|
||||
new SemanticsDebugger(
|
||||
child: new Material(
|
||||
child: new Center(
|
||||
child: new Slider(
|
||||
value: value,
|
||||
onChanged: (double newValue) {
|
||||
value = newValue;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.fling(find.byType(Slider), const Offset(-100.0, 0.0), 100.0);
|
||||
expect(value, equals(0.65));
|
||||
});
|
||||
|
||||
testWidgets('SemanticsDebugger checkbox', (WidgetTester tester) async {
|
||||
Key keyTop = new UniqueKey();
|
||||
Key keyBottom = new UniqueKey();
|
||||
|
||||
bool valueTop = false;
|
||||
bool valueBottom = true;
|
||||
|
||||
await tester.pumpWidget(
|
||||
new SemanticsDebugger(
|
||||
child: new Material(
|
||||
child: new Block(
|
||||
children: <Widget>[
|
||||
new Checkbox(
|
||||
key: keyTop,
|
||||
value: valueTop,
|
||||
onChanged: (bool newValue) {
|
||||
valueTop = newValue;
|
||||
},
|
||||
),
|
||||
new Checkbox(
|
||||
key: keyBottom,
|
||||
value: valueBottom,
|
||||
onChanged: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.byKey(keyTop));
|
||||
|
||||
expect(valueTop, isTrue);
|
||||
valueTop = false;
|
||||
expect(valueTop, isFalse);
|
||||
|
||||
await tester.tap(find.byKey(keyBottom));
|
||||
|
||||
expect(valueTop, isFalse);
|
||||
expect(valueTop, isFalse);
|
||||
});
|
||||
}
|
||||
|
||||
88
packages/flutter/test/widgets/status_transitions_test.dart
Normal file
88
packages/flutter/test/widgets/status_transitions_test.dart
Normal file
@ -0,0 +1,88 @@
|
||||
// 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/widgets.dart';
|
||||
|
||||
class TestStatusTransitionWidget extends StatusTransitionWidget {
|
||||
TestStatusTransitionWidget({
|
||||
Key key,
|
||||
this.builder,
|
||||
Animation<double> animation,
|
||||
}) : super(key: key, animation: animation);
|
||||
|
||||
final WidgetBuilder builder;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => builder(context);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Status transition control test', (WidgetTester tester) async {
|
||||
bool didBuild = false;
|
||||
final AnimationController controller = new AnimationController(
|
||||
duration: const Duration(seconds: 1),
|
||||
vsync: const TestVSync(),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(new TestStatusTransitionWidget(
|
||||
animation: controller,
|
||||
builder: (BuildContext context) {
|
||||
expect(didBuild, isFalse);
|
||||
didBuild = true;
|
||||
return new Container();
|
||||
},
|
||||
));
|
||||
|
||||
expect(didBuild, isTrue);
|
||||
didBuild = false;
|
||||
|
||||
controller.forward();
|
||||
|
||||
expect(didBuild, isFalse);
|
||||
await tester.pump();
|
||||
expect(didBuild, isTrue);
|
||||
didBuild = false;
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isFalse);
|
||||
await tester.pump(const Duration(milliseconds: 850));
|
||||
expect(didBuild, isFalse);
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isTrue);
|
||||
didBuild = false;
|
||||
controller.forward();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isFalse);
|
||||
controller.stop();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isFalse);
|
||||
|
||||
final AnimationController anotherController = new AnimationController(
|
||||
duration: const Duration(seconds: 1),
|
||||
vsync: const TestVSync(),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(new TestStatusTransitionWidget(
|
||||
animation: anotherController,
|
||||
builder: (BuildContext context) {
|
||||
expect(didBuild, isFalse);
|
||||
didBuild = true;
|
||||
return new Container();
|
||||
},
|
||||
));
|
||||
|
||||
expect(didBuild, isTrue);
|
||||
didBuild = false;
|
||||
controller.reverse();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isFalse);
|
||||
anotherController.forward();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
expect(didBuild, isTrue);
|
||||
didBuild = false;
|
||||
|
||||
controller.stop();
|
||||
anotherController.stop();
|
||||
});
|
||||
}
|
||||
@ -15,4 +15,5 @@ export 'src/matchers.dart';
|
||||
export 'src/test_async_utils.dart';
|
||||
export 'src/stack_manipulation.dart';
|
||||
export 'src/test_pointer.dart';
|
||||
export 'src/test_vsync.dart';
|
||||
export 'src/widget_tester.dart';
|
||||
|
||||
@ -4,7 +4,12 @@
|
||||
|
||||
import 'package:flutter/scheduler.dart';
|
||||
|
||||
/// A [TickerProvider] that creates a standalone ticker.
|
||||
///
|
||||
/// Useful in tests that create an [AnimationController] outside of the widget
|
||||
/// tree.
|
||||
class TestVSync implements TickerProvider {
|
||||
/// Creates a ticker provider that creates standalone tickers.
|
||||
const TestVSync();
|
||||
|
||||
@override
|
||||
Loading…
x
Reference in New Issue
Block a user