172 lines
6.8 KiB
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);
|
|
});
|
|
}
|