mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: customize command shortcuts (#2848)
This commit is contained in:
@ -0,0 +1,164 @@
|
||||
import 'dart:ffi';
|
||||
|
||||
import 'package:appflowy/plugins/document/presentation/editor_page.dart';
|
||||
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_cubit.dart';
|
||||
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockSettingsShortcutService extends Mock
|
||||
implements SettingsShortcutService {}
|
||||
|
||||
void main() {
|
||||
group("ShortcutsCubit", () {
|
||||
late SettingsShortcutService service;
|
||||
late ShortcutsCubit shortcutsCubit;
|
||||
|
||||
setUp(() async {
|
||||
service = MockSettingsShortcutService();
|
||||
when(
|
||||
() => service.saveAllShortcuts(any()),
|
||||
).thenAnswer((_) async => true);
|
||||
when(
|
||||
() => service.getCustomizeShortcuts(),
|
||||
).thenAnswer((_) async => []);
|
||||
when(
|
||||
() => service.updateCommandShortcuts(any(), any()),
|
||||
).thenAnswer((_) async => Void);
|
||||
|
||||
shortcutsCubit = ShortcutsCubit(service);
|
||||
});
|
||||
|
||||
test('initial state is correct', () {
|
||||
final shortcutsCubit = ShortcutsCubit(service);
|
||||
expect(shortcutsCubit.state, const ShortcutsState());
|
||||
});
|
||||
|
||||
group('fetchShortcuts', () {
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'calls getCustomizeShortcuts() once',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.fetchShortcuts(),
|
||||
verify: (_) {
|
||||
verify(() => service.getCustomizeShortcuts()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, failure] when getCustomizeShortcuts() throws',
|
||||
setUp: () {
|
||||
when(
|
||||
() => service.getCustomizeShortcuts(),
|
||||
).thenThrow(Exception('oops'));
|
||||
},
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.fetchShortcuts(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.failure)
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, success] when getCustomizeShortcuts() returns shortcuts',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.fetchShortcuts(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.success)
|
||||
.having(
|
||||
(w) => w.commandShortcutEvents,
|
||||
'shortcuts',
|
||||
commandShortcutEvents,
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
group('updateShortcut', () {
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'calls saveAllShortcuts() once',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.updateAllShortcuts(),
|
||||
verify: (_) {
|
||||
verify(() => service.saveAllShortcuts(any())).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, failure] when saveAllShortcuts() throws',
|
||||
setUp: () {
|
||||
when(
|
||||
() => service.saveAllShortcuts(any()),
|
||||
).thenThrow(Exception('oops'));
|
||||
},
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.updateAllShortcuts(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.failure)
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, success] when saveAllShortcuts() is successful',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.updateAllShortcuts(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.success)
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
group('resetToDefault', () {
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'calls saveAllShortcuts() once',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.resetToDefault(),
|
||||
verify: (_) {
|
||||
verify(() => service.saveAllShortcuts(any())).called(1);
|
||||
verify(() => service.getCustomizeShortcuts()).called(1);
|
||||
},
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, failure] when saveAllShortcuts() throws',
|
||||
setUp: () {
|
||||
when(
|
||||
() => service.saveAllShortcuts(any()),
|
||||
).thenThrow(Exception('oops'));
|
||||
},
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.resetToDefault(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.failure)
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<ShortcutsCubit, ShortcutsState>(
|
||||
'emits [updating, success] when getCustomizeShortcuts() returns shortcuts',
|
||||
build: () => shortcutsCubit,
|
||||
act: (cubit) => cubit.resetToDefault(),
|
||||
expect: () => <dynamic>[
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
isA<ShortcutsState>()
|
||||
.having((w) => w.status, 'status', ShortcutsStatus.success)
|
||||
.having(
|
||||
(w) => w.commandShortcutEvents,
|
||||
'shortcuts',
|
||||
commandShortcutEvents,
|
||||
),
|
||||
],
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io' show File;
|
||||
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_service.dart';
|
||||
import 'package:appflowy/workspace/application/settings/shortcuts/shortcuts_model.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:file/memory.dart';
|
||||
|
||||
void main() {
|
||||
late SettingsShortcutService service;
|
||||
late File mockFile;
|
||||
String shortcutsJson = '';
|
||||
|
||||
setUp(() async {
|
||||
final MemoryFileSystem fileSystem = MemoryFileSystem.test();
|
||||
mockFile = await fileSystem.file("shortcuts.json").create(recursive: true);
|
||||
service = SettingsShortcutService(file: mockFile);
|
||||
shortcutsJson = """{
|
||||
"commandShortcuts":[
|
||||
{
|
||||
"key":"move the cursor upward",
|
||||
"command":"alt+arrow up"
|
||||
},
|
||||
{
|
||||
"key":"move the cursor forward one character",
|
||||
"command":"alt+arrow left"
|
||||
},
|
||||
{
|
||||
"key":"move the cursor downward",
|
||||
"command":"alt+arrow down"
|
||||
}
|
||||
]
|
||||
}""";
|
||||
});
|
||||
|
||||
group("Settings Shortcut Service", () {
|
||||
test(
|
||||
"returns default standard shortcuts if file is empty",
|
||||
() async {
|
||||
expect(await service.getCustomizeShortcuts(), []);
|
||||
},
|
||||
);
|
||||
|
||||
test('returns updated shortcut event list from json', () {
|
||||
final commandShortcuts = service.getShortcutsFromJson(shortcutsJson);
|
||||
|
||||
final cursorUpShortcut = commandShortcuts
|
||||
.firstWhere((el) => el.key == "move the cursor upward");
|
||||
|
||||
final cursorDownShortcut = commandShortcuts
|
||||
.firstWhere((el) => el.key == "move the cursor downward");
|
||||
|
||||
expect(
|
||||
commandShortcuts.length,
|
||||
3,
|
||||
);
|
||||
expect(cursorUpShortcut.command, "alt+arrow up");
|
||||
expect(cursorDownShortcut.command, "alt+arrow down");
|
||||
});
|
||||
|
||||
test(
|
||||
"saveAllShortcuts saves shortcuts",
|
||||
() async {
|
||||
//updating one of standard command shortcut events.
|
||||
final currentCommandShortcuts = standardCommandShortcutEvents;
|
||||
const kKey = "scroll one page down";
|
||||
const oldCommand = "page down";
|
||||
const newCommand = "alt+page down";
|
||||
final commandShortcutEvent = currentCommandShortcuts
|
||||
.firstWhere((element) => element.key == kKey);
|
||||
|
||||
expect(commandShortcutEvent.command, oldCommand);
|
||||
|
||||
//updating the command.
|
||||
commandShortcutEvent.updateCommand(
|
||||
command: newCommand,
|
||||
);
|
||||
|
||||
//saving the updated shortcuts
|
||||
await service.saveAllShortcuts(currentCommandShortcuts);
|
||||
|
||||
//reading from the mock file the saved shortcut list.
|
||||
final savedDataInFile = await mockFile.readAsString();
|
||||
|
||||
//Check if the lists where properly converted to JSON and saved.
|
||||
final shortcuts = EditorShortcuts(
|
||||
commandShortcuts:
|
||||
currentCommandShortcuts.toCommandShortcutModelList(),
|
||||
);
|
||||
|
||||
expect(jsonEncode(shortcuts.toJson()), savedDataInFile);
|
||||
|
||||
//now checking if the modified command of "move the cursor upward" is "arrow up"
|
||||
final newCommandShortcuts =
|
||||
service.getShortcutsFromJson(savedDataInFile);
|
||||
|
||||
final updatedCommandEvent =
|
||||
newCommandShortcuts.firstWhere((el) => el.key == kKey);
|
||||
|
||||
expect(updatedCommandEvent.command, newCommand);
|
||||
},
|
||||
);
|
||||
|
||||
test('load shortcuts from file', () async {
|
||||
//updating one of standard command shortcut event.
|
||||
const kKey = "scroll one page up";
|
||||
const oldCommand = "page up";
|
||||
const newCommand = "alt+page up";
|
||||
final currentCommandShortcuts = standardCommandShortcutEvents;
|
||||
final commandShortcutEvent =
|
||||
currentCommandShortcuts.firstWhere((element) => element.key == kKey);
|
||||
|
||||
expect(commandShortcutEvent.command, oldCommand);
|
||||
|
||||
//updating the command.
|
||||
commandShortcutEvent.updateCommand(command: newCommand);
|
||||
|
||||
//saving the updated shortcuts
|
||||
service.saveAllShortcuts(currentCommandShortcuts);
|
||||
|
||||
//now directly fetching the shortcuts from loadShortcuts
|
||||
final commandShortcuts = await service.getCustomizeShortcuts();
|
||||
expect(
|
||||
commandShortcuts,
|
||||
currentCommandShortcuts.toCommandShortcutModelList(),
|
||||
);
|
||||
|
||||
final updatedCommandEvent =
|
||||
commandShortcuts.firstWhere((el) => el.key == kKey);
|
||||
|
||||
expect(updatedCommandEvent.command, newCommand);
|
||||
});
|
||||
|
||||
test('updateCommandShortcuts works properly', () async {
|
||||
//updating one of standard command shortcut event.
|
||||
const kKey = "move the cursor forward one character";
|
||||
const oldCommand = "arrow left";
|
||||
const newCommand = "alt+arrow left";
|
||||
final currentCommandShortcuts = standardCommandShortcutEvents;
|
||||
|
||||
//check if the current shortcut event's key is set to old command.
|
||||
final currentCommandEvent =
|
||||
currentCommandShortcuts.firstWhere((el) => el.key == kKey);
|
||||
|
||||
expect(currentCommandEvent.command, oldCommand);
|
||||
|
||||
final commandShortcutModelList =
|
||||
EditorShortcuts.fromJson(jsonDecode(shortcutsJson)).commandShortcuts;
|
||||
|
||||
//now calling the updateCommandShortcuts method
|
||||
await service.updateCommandShortcuts(
|
||||
currentCommandShortcuts,
|
||||
commandShortcutModelList,
|
||||
);
|
||||
|
||||
//check if the shortcut event's key is updated.
|
||||
final updatedCommandEvent =
|
||||
currentCommandShortcuts.firstWhere((el) => el.key == kKey);
|
||||
|
||||
expect(updatedCommandEvent.command, newCommand);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
extension on List<CommandShortcutEvent> {
|
||||
List<CommandShortcutModel> toCommandShortcutModelList() =>
|
||||
map((e) => CommandShortcutModel.fromCommandEvent(e)).toList();
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
import 'package:appflowy/workspace/application/settings/shortcuts/settings_shortcuts_cubit.dart';
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
// ignore: depend_on_referenced_packages
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockShortcutsCubit extends MockCubit<ShortcutsState>
|
||||
implements ShortcutsCubit {}
|
||||
|
||||
void main() {
|
||||
group(
|
||||
"CustomizeShortcutsView",
|
||||
() {
|
||||
group(
|
||||
"should be displayed in ViewState",
|
||||
() {
|
||||
late ShortcutsCubit mockShortcutsCubit;
|
||||
|
||||
setUp(() {
|
||||
mockShortcutsCubit = MockShortcutsCubit();
|
||||
});
|
||||
|
||||
testWidgets('Initial when cubit emits [ShortcutsStatus.Initial]',
|
||||
(widgetTester) async {
|
||||
when(() => mockShortcutsCubit.state)
|
||||
.thenReturn(const ShortcutsState());
|
||||
|
||||
await widgetTester.pumpWidget(
|
||||
BlocProvider.value(
|
||||
value: mockShortcutsCubit,
|
||||
child:
|
||||
const MaterialApp(home: SettingsCustomizeShortcutsView()),
|
||||
),
|
||||
);
|
||||
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'Updating when cubit emits [ShortcutsStatus.updating]',
|
||||
(widgetTester) async {
|
||||
when(() => mockShortcutsCubit.state).thenReturn(
|
||||
const ShortcutsState(status: ShortcutsStatus.updating),
|
||||
);
|
||||
|
||||
await widgetTester.pumpWidget(
|
||||
BlocProvider.value(
|
||||
value: mockShortcutsCubit,
|
||||
child:
|
||||
const MaterialApp(home: SettingsCustomizeShortcutsView()),
|
||||
),
|
||||
);
|
||||
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'Shows ShortcutsList when cubit emits [ShortcutsStatus.success]',
|
||||
(widgetTester) async {
|
||||
KeyEventResult dummyHandler(EditorState e) =>
|
||||
KeyEventResult.handled;
|
||||
|
||||
final dummyShortcuts = <CommandShortcutEvent>[
|
||||
CommandShortcutEvent(
|
||||
key: 'Copy',
|
||||
command: 'ctrl+c',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Paste',
|
||||
command: 'ctrl+v',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Undo',
|
||||
command: 'ctrl+z',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Redo',
|
||||
command: 'ctrl+y',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
];
|
||||
|
||||
when(() => mockShortcutsCubit.state).thenReturn(
|
||||
ShortcutsState(
|
||||
status: ShortcutsStatus.success,
|
||||
commandShortcutEvents: dummyShortcuts,
|
||||
),
|
||||
);
|
||||
await widgetTester.pumpWidget(
|
||||
BlocProvider.value(
|
||||
value: mockShortcutsCubit,
|
||||
child:
|
||||
const MaterialApp(home: SettingsCustomizeShortcutsView()),
|
||||
),
|
||||
);
|
||||
|
||||
await widgetTester.pump();
|
||||
|
||||
final listViewFinder = find.byType(ShortcutsListView);
|
||||
final foundShortcuts = widgetTester
|
||||
.widget<ShortcutsListView>(listViewFinder)
|
||||
.shortcuts;
|
||||
|
||||
expect(listViewFinder, findsOneWidget);
|
||||
expect(foundShortcuts, dummyShortcuts);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('Shows Error when cubit emits [ShortcutsStatus.failure]',
|
||||
(tester) async {
|
||||
when(() => mockShortcutsCubit.state).thenReturn(
|
||||
const ShortcutsState(
|
||||
status: ShortcutsStatus.failure,
|
||||
),
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
BlocProvider.value(
|
||||
value: mockShortcutsCubit,
|
||||
child:
|
||||
const MaterialApp(home: SettingsCustomizeShortcutsView()),
|
||||
),
|
||||
);
|
||||
expect(find.byType(ShortcutsErrorView), findsOneWidget);
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group("ShortcutsErrorView", () {
|
||||
testWidgets("displays correctly", (widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: ShortcutsErrorView(
|
||||
errorMessage: 'Error occured',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(FlowyText), findsOneWidget);
|
||||
expect(find.byType(FlowyIconButton), findsOneWidget);
|
||||
});
|
||||
});
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
KeyEventResult dummyHandler(EditorState e) => KeyEventResult.handled;
|
||||
|
||||
final shortcut = CommandShortcutEvent(
|
||||
key: 'Copy',
|
||||
command: 'ctrl+c',
|
||||
handler: dummyHandler,
|
||||
);
|
||||
|
||||
group("ShortcutsListTile", () {
|
||||
group(
|
||||
"should be displayed correctly",
|
||||
() {
|
||||
testWidgets('with key and command', (widgetTester) async {
|
||||
final sKey = Key(shortcut.key);
|
||||
|
||||
await widgetTester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ShortcutsListTile(shortcutEvent: shortcut),
|
||||
),
|
||||
);
|
||||
|
||||
final commandTextFinder = find.byKey(sKey);
|
||||
final foundCommand =
|
||||
widgetTester.widget<FlowyText>(commandTextFinder).text;
|
||||
|
||||
expect(commandTextFinder, findsOneWidget);
|
||||
expect(foundCommand, shortcut.key);
|
||||
|
||||
final btnFinder = find.byType(FlowyTextButton);
|
||||
final foundBtnText =
|
||||
widgetTester.widget<FlowyTextButton>(btnFinder).text;
|
||||
|
||||
expect(btnFinder, findsOneWidget);
|
||||
expect(foundBtnText, shortcut.command);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
group(
|
||||
"taps the button",
|
||||
() {
|
||||
testWidgets("opens AlertDialog correctly", (widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ShortcutsListTile(shortcutEvent: shortcut),
|
||||
),
|
||||
);
|
||||
|
||||
final btnFinder = find.byType(FlowyTextButton);
|
||||
final foundBtnText =
|
||||
widgetTester.widget<FlowyTextButton>(btnFinder).text;
|
||||
|
||||
expect(btnFinder, findsOneWidget);
|
||||
expect(foundBtnText, shortcut.command);
|
||||
|
||||
await widgetTester.tap(btnFinder);
|
||||
await widgetTester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AlertDialog), findsOneWidget);
|
||||
expect(find.byType(RawKeyboardListener), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("updates the text with new key event",
|
||||
(widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ShortcutsListTile(shortcutEvent: shortcut),
|
||||
),
|
||||
);
|
||||
|
||||
final btnFinder = find.byType(FlowyTextButton);
|
||||
|
||||
await widgetTester.tap(btnFinder);
|
||||
await widgetTester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(AlertDialog), findsOneWidget);
|
||||
expect(find.byType(RawKeyboardListener), findsOneWidget);
|
||||
|
||||
await widgetTester.sendKeyEvent(LogicalKeyboardKey.keyC);
|
||||
|
||||
expect(find.text('c'), findsOneWidget);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
import 'package:appflowy/workspace/presentation/settings/widgets/settings_customize_shortcuts_view.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
KeyEventResult dummyHandler(EditorState e) => KeyEventResult.handled;
|
||||
|
||||
final dummyShortcuts = [
|
||||
CommandShortcutEvent(
|
||||
key: 'Copy',
|
||||
command: 'ctrl+c',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Paste',
|
||||
command: 'ctrl+v',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Undo',
|
||||
command: 'ctrl+z',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
CommandShortcutEvent(
|
||||
key: 'Redo',
|
||||
command: 'ctrl+y',
|
||||
handler: dummyHandler,
|
||||
),
|
||||
];
|
||||
|
||||
group("ShortcutsListView", () {
|
||||
group("should be displayed correctly", () {
|
||||
testWidgets("with empty shortcut list", (widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: ShortcutsListView(shortcuts: []),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(FlowyText), findsNWidgets(3));
|
||||
//we expect three text widgets which are keybinding, command, and reset
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(find.byType(ShortcutsListTile), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets("with 1 item in shortcut list", (widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ShortcutsListView(shortcuts: [dummyShortcuts[0]]),
|
||||
),
|
||||
);
|
||||
|
||||
await widgetTester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(FlowyText), findsAtLeastNWidgets(3));
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(find.byType(ShortcutsListTile), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets("with populated shortcut list", (widgetTester) async {
|
||||
await widgetTester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ShortcutsListView(shortcuts: dummyShortcuts),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byType(FlowyText), findsAtLeastNWidgets(3));
|
||||
expect(find.byType(ListView), findsOneWidget);
|
||||
expect(
|
||||
find.byType(ShortcutsListTile),
|
||||
findsNWidgets(dummyShortcuts.length),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user