plasmoid/test/widget_test.dart

172 lines
6.8 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:plasmoid/main.dart';
import 'package:plasmoid/preferences.dart';
import 'package:plasmoid/settings.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
Map<String, Object?> _app(String name) => {
'app_name': name,
'package_name': 'com.example.${name.toLowerCase()}',
'apk_file_path': '',
'version_name': '1',
'version_code': 1,
'data_dir': '',
'system_app': false,
'install_time': 0,
'update_time': 0,
'is_enabled': true,
'category': -1,
};
void main() {
final launched = <String>[];
var installed = ['Alpha', 'Bravo', 'Charlie'];
setUp(() async {
launched.clear();
installed = ['Alpha', 'Bravo', 'Charlie'];
GoogleFonts.config.allowRuntimeFetching = false;
SharedPreferences.setMockInitialValues({'sortLastUsed': false});
await SharedPreferencesService().initialize();
final messenger = TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger;
messenger.setMockMethodCallHandler(const MethodChannel('g123k/device_apps'), (call) async {
switch (call.method) {
case 'getInstalledApps':
return installed.map(_app).toList();
case 'openApp':
launched.add((call.arguments as Map)['package_name'] as String);
return true;
}
return null;
});
messenger.setMockStreamHandler(const EventChannel('g123k/device_apps_events'), MockStreamHandler.inline(onListen: (_, __) {}));
});
Future<void> pumpLauncher(WidgetTester tester) async {
await tester.pumpWidget(ChangeNotifierProvider(
create: (_) => AppSettings(),
child: MaterialApp(home: AppLauncherScreen()),
));
await tester.pumpAndSettle();
}
Future<void> press(WidgetTester tester, LogicalKeyboardKey key) async {
await tester.sendKeyEvent(key);
await tester.pumpAndSettle();
}
Future<void> hold(WidgetTester tester, LogicalKeyboardKey key) async {
await tester.sendKeyDownEvent(key);
await tester.pump(const Duration(seconds: 1));
await tester.sendKeyUpEvent(key);
await tester.pumpAndSettle();
}
ListTile tile(WidgetTester tester, String name) =>
tester.widget<ListTile>(find.ancestor(of: find.text(name), matching: find.byType(ListTile)));
EditableText searchField(WidgetTester tester) => tester.widget<EditableText>(find.byType(EditableText));
testWidgets('down enters the list and up/down move the selection', (tester) async {
await pumpLauncher(tester);
expect(searchField(tester).focusNode.hasFocus, isTrue);
await press(tester, LogicalKeyboardKey.arrowDown);
expect(searchField(tester).focusNode.hasFocus, isFalse);
expect(tile(tester, 'Alpha').selected, isTrue);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowDown);
expect(tile(tester, 'Charlie').selected, isTrue);
await press(tester, LogicalKeyboardKey.arrowUp);
expect(tile(tester, 'Bravo').selected, isTrue);
await press(tester, LogicalKeyboardKey.select);
expect(launched, ['com.example.bravo']);
});
testWidgets('left returns focus to the search field', (tester) async {
await pumpLauncher(tester);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowLeft);
expect(searchField(tester).focusNode.hasFocus, isTrue);
expect(tile(tester, 'Alpha').selected, isFalse);
});
testWidgets('right clears the search text, then opens and focuses the menu', (tester) async {
await pumpLauncher(tester);
await tester.enterText(find.byType(TextField), 'al');
await tester.pumpAndSettle();
await press(tester, LogicalKeyboardKey.arrowRight);
expect(searchField(tester).controller.text, isEmpty);
await press(tester, LogicalKeyboardKey.arrowRight);
expect(find.text('Refresh App List'), findsOneWidget);
final focused = FocusManager.instance.primaryFocus!.context!;
expect(find.descendant(of: find.byWidget(focused.widget), matching: find.text('Refresh App List')), findsOneWidget);
});
testWidgets('right in the list opens the menu', (tester) async {
await pumpLauncher(tester);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowRight);
expect(find.text('Refresh App List'), findsOneWidget);
});
testWidgets('long left pins and long right demotes the selected app', (tester) async {
await pumpLauncher(tester);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowDown);
await press(tester, LogicalKeyboardKey.arrowDown);
await hold(tester, LogicalKeyboardKey.arrowLeft);
expect(SharedPreferencesService().getBool('isPinned_com.example.charlie', false), isTrue);
expect(tile(tester, 'Charlie').selected, isTrue);
expect(searchField(tester).focusNode.hasFocus, isFalse);
await hold(tester, LogicalKeyboardKey.arrowRight);
expect(SharedPreferencesService().getBool('isPinned_com.example.charlie', false), isFalse);
await hold(tester, LogicalKeyboardKey.arrowRight);
expect(SharedPreferencesService().getBool('isDemoted_com.example.charlie', false), isTrue);
expect(tile(tester, 'Charlie').selected, isTrue);
expect(find.text('Refresh App List'), findsNothing);
});
testWidgets('long center toggles the context menu with focus on it', (tester) async {
await pumpLauncher(tester);
await press(tester, LogicalKeyboardKey.arrowDown);
await hold(tester, LogicalKeyboardKey.select);
expect(find.text('Edit Tags'), findsOneWidget);
expect(find.text('Edit Tags for Alpha'), findsNothing);
final focused = FocusManager.instance.primaryFocus!.context!;
expect(find.descendant(of: find.byWidget(focused.widget), matching: find.text('Edit Tags')), findsOneWidget);
await hold(tester, LogicalKeyboardKey.select);
expect(find.text('Edit Tags'), findsNothing);
expect(launched, isEmpty);
});
testWidgets('moving the selection scrolls it into view', (tester) async {
installed = [for (var i = 10; i < 70; i++) 'App$i'];
await pumpLauncher(tester);
await press(tester, LogicalKeyboardKey.arrowDown);
for (var i = 0; i < 40; i++) {
await press(tester, LogicalKeyboardKey.arrowDown);
}
expect(tile(tester, 'App50').selected, isTrue);
expect(tester.getRect(find.text('App50')).bottom, lessThanOrEqualTo(tester.view.physicalSize.height / tester.view.devicePixelRatio));
await press(tester, LogicalKeyboardKey.arrowLeft);
await press(tester, LogicalKeyboardKey.arrowDown);
expect(tile(tester, 'App10').selected, isTrue);
});
}