576 lines
16 KiB
Dart
576 lines
16 KiB
Dart
// 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/cupertino.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:flutter/gestures.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
|
|
void main() {
|
|
testWidgets('Switch can toggle on tap', (WidgetTester tester) async {
|
|
final Key switchKey = UniqueKey();
|
|
bool value = false;
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
key: switchKey,
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(value, isFalse);
|
|
await tester.tap(find.byKey(switchKey));
|
|
expect(value, isTrue);
|
|
});
|
|
|
|
testWidgets('Switch emits light haptic vibration on tap', (WidgetTester tester) async {
|
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
|
final Key switchKey = UniqueKey();
|
|
bool value = false;
|
|
|
|
final List<MethodCall> log = <MethodCall>[];
|
|
|
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
log.add(methodCall);
|
|
});
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
key: switchKey,
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.tap(find.byKey(switchKey));
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(1));
|
|
expect(log.single, isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
debugDefaultTargetPlatformOverride = null;
|
|
});
|
|
|
|
testWidgets('Using other widgets that rebuild the switch will not cause vibrations', (WidgetTester tester) async {
|
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
|
final Key switchKey = UniqueKey();
|
|
final Key switchKey2 = UniqueKey();
|
|
bool value = false;
|
|
bool value2 = false;
|
|
final List<MethodCall> log = <MethodCall>[];
|
|
|
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
log.add(methodCall);
|
|
});
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: Column(
|
|
children: <Widget>[
|
|
CupertinoSwitch(
|
|
key: switchKey,
|
|
value: value,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
CupertinoSwitch(
|
|
key: switchKey2,
|
|
value: value2,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value2 = newValue;
|
|
});
|
|
},
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.tap(find.byKey(switchKey));
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(1));
|
|
expect(log[0], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
|
|
await tester.tap(find.byKey(switchKey2));
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(2));
|
|
expect(log[1], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
|
|
await tester.tap(find.byKey(switchKey));
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(3));
|
|
expect(log[2], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
|
|
await tester.tap(find.byKey(switchKey2));
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(4));
|
|
expect(log[3], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
debugDefaultTargetPlatformOverride = null;
|
|
});
|
|
|
|
testWidgets('Haptic vibration triggers on drag', (WidgetTester tester) async {
|
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
|
bool value = false;
|
|
final List<MethodCall> log = <MethodCall>[];
|
|
|
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
log.add(methodCall);
|
|
});
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
|
|
expect(value, isTrue);
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(1));
|
|
expect(log[0], isMethodCall('HapticFeedback.vibrate', arguments: 'HapticFeedbackType.lightImpact'));
|
|
debugDefaultTargetPlatformOverride = null;
|
|
});
|
|
|
|
testWidgets('No haptic vibration triggers from a programmatic value change', (WidgetTester tester) async {
|
|
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
|
|
final Key switchKey = UniqueKey();
|
|
bool value = false;
|
|
|
|
final List<MethodCall> log = <MethodCall>[];
|
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
|
log.add(methodCall);
|
|
});
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: Column(
|
|
children: <Widget>[
|
|
CupertinoButton(
|
|
child: const Text('Button'),
|
|
onPressed: () {
|
|
setState(() {
|
|
value = !value;
|
|
});
|
|
},
|
|
),
|
|
CupertinoSwitch(
|
|
key: switchKey,
|
|
value: value,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(value, isFalse);
|
|
|
|
await tester.tap(find.byType(CupertinoButton));
|
|
expect(value, isTrue);
|
|
await tester.pump();
|
|
|
|
expect(log, hasLength(0));
|
|
debugDefaultTargetPlatformOverride = null;
|
|
});
|
|
|
|
testWidgets('Switch can drag (LTR)', (WidgetTester tester) async {
|
|
bool value = false;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
value: value,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(value, isFalse);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-48.0, 0.0));
|
|
|
|
expect(value, isFalse);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(48.0, 0.0));
|
|
|
|
expect(value, isTrue);
|
|
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(48.0, 0.0));
|
|
|
|
expect(value, isTrue);
|
|
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-48.0, 0.0));
|
|
|
|
expect(value, isFalse);
|
|
});
|
|
|
|
testWidgets('Switch can drag with dragStartBehavior', (WidgetTester tester) async {
|
|
bool value = false;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(value, isFalse);
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-30.0, 0.0));
|
|
expect(value, isFalse);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
|
|
expect(value, isTrue);
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
|
|
expect(value, isTrue);
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-30.0, 0.0));
|
|
expect(value, isFalse);
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.start,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
final Rect switchRect = tester.getRect(find.byType(CupertinoSwitch));
|
|
|
|
TestGesture gesture = await tester.startGesture(switchRect.center);
|
|
// We have to execute the drag in two frames because the first update will
|
|
// just set the start position.
|
|
await gesture.moveBy(const Offset(20.0, 0.0));
|
|
await gesture.moveBy(const Offset(20.0, 0.0));
|
|
expect(value, isTrue);
|
|
await gesture.up();
|
|
await tester.pump();
|
|
|
|
gesture = await tester.startGesture(switchRect.center);
|
|
await gesture.moveBy(const Offset(20.0, 0.0));
|
|
await gesture.moveBy(const Offset(20.0, 0.0));
|
|
expect(value, isTrue);
|
|
await gesture.up();
|
|
await tester.pump();
|
|
|
|
gesture = await tester.startGesture(switchRect.center);
|
|
await gesture.moveBy(const Offset(-20.0, 0.0));
|
|
await gesture.moveBy(const Offset(-20.0, 0.0));
|
|
expect(value, isFalse);
|
|
});
|
|
|
|
testWidgets('Switch can drag (RTL)', (WidgetTester tester) async {
|
|
bool value = false;
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.rtl,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: CupertinoSwitch(
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(value, isFalse);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
|
|
|
|
expect(value, isFalse);
|
|
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-30.0, 0.0));
|
|
|
|
expect(value, isTrue);
|
|
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(-30.0, 0.0));
|
|
|
|
expect(value, isTrue);
|
|
|
|
await tester.pump();
|
|
await tester.drag(find.byType(CupertinoSwitch), const Offset(30.0, 0.0));
|
|
|
|
expect(value, isFalse);
|
|
});
|
|
|
|
testWidgets('Switch is translucent when disabled', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: null,
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
expect(find.byType(Opacity), findsOneWidget);
|
|
expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 0.5);
|
|
});
|
|
|
|
testWidgets('Switch is opaque when enabled', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {},
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
expect(find.byType(Opacity), findsOneWidget);
|
|
expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 1.0);
|
|
});
|
|
|
|
testWidgets('Switch turns translucent after becoming disabled', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {},
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
const Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: null,
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
expect(find.byType(Opacity), findsOneWidget);
|
|
expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 0.5);
|
|
});
|
|
|
|
testWidgets('Switch turns opaque after becoming enabled', (WidgetTester tester) async {
|
|
await tester.pumpWidget(
|
|
const Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: null,
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: Center(
|
|
child: CupertinoSwitch(
|
|
value: false,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {},
|
|
),
|
|
)
|
|
),
|
|
);
|
|
|
|
expect(find.byType(Opacity), findsOneWidget);
|
|
expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 1.0);
|
|
});
|
|
|
|
testWidgets('Switch renders correctly before, during, and after being tapped', (WidgetTester tester) async {
|
|
final Key switchKey = UniqueKey();
|
|
bool value = false;
|
|
await tester.pumpWidget(
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: StatefulBuilder(
|
|
builder: (BuildContext context, StateSetter setState) {
|
|
return Center(
|
|
child: RepaintBoundary(
|
|
child: CupertinoSwitch(
|
|
key: switchKey,
|
|
value: value,
|
|
dragStartBehavior: DragStartBehavior.down,
|
|
onChanged: (bool newValue) {
|
|
setState(() {
|
|
value = newValue;
|
|
});
|
|
},
|
|
)
|
|
)
|
|
);
|
|
},
|
|
),
|
|
),
|
|
);
|
|
|
|
await expectLater(
|
|
find.byKey(switchKey),
|
|
matchesGoldenFile(
|
|
'switch.tap.off.png',
|
|
version: 0,
|
|
),
|
|
);
|
|
|
|
await tester.tap(find.byKey(switchKey));
|
|
expect(value, isTrue);
|
|
|
|
// Kick off animation, then advance to intermediate frame.
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 60));
|
|
await expectLater(
|
|
find.byKey(switchKey),
|
|
matchesGoldenFile(
|
|
'switch.tap.turningOn.png',
|
|
version: 0,
|
|
),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
await expectLater(
|
|
find.byKey(switchKey),
|
|
matchesGoldenFile(
|
|
'switch.tap.on.png',
|
|
version: 0,
|
|
),
|
|
);
|
|
});
|
|
|
|
}
|