mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-08-24 01:08:09 +08:00

Instead we're going to move back to standard exceptions. Using a custom Result class has created far far more problems - The Stacktraces aren't always right - Sometimes one forgets to check the Result error - All other exception throwing code needing to be converted to Results - Non idiomatic Dart code I think it's better to just go back to exceptions. They have their problems, but overall, I think it's a better approach.
301 lines
9.2 KiB
Dart
301 lines
9.2 KiB
Dart
/*
|
|
* SPDX-FileCopyrightText: 2022 Vishesh Handa <me@vhanda.in>
|
|
*
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
*/
|
|
import 'dart:io';
|
|
|
|
import 'package:dart_git/git.dart';
|
|
import 'package:dart_git/plumbing/git_hash.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:gitjournal/change_notifiers.dart';
|
|
import 'package:gitjournal/editors/common_types.dart';
|
|
import 'package:gitjournal/editors/note_body_editor.dart';
|
|
import 'package:gitjournal/editors/note_editor.dart';
|
|
import 'package:gitjournal/editors/note_title_editor.dart';
|
|
import 'package:gitjournal/l10n.dart';
|
|
import 'package:gitjournal/repository.dart';
|
|
import 'package:gitjournal/repository_manager.dart';
|
|
import 'package:gitjournal/settings/app_config.dart';
|
|
import 'package:path/path.dart' as p;
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../lib.dart';
|
|
|
|
void main() {
|
|
late GitJournalRepo repo;
|
|
late RepositoryManager repoManager;
|
|
late SharedPreferences pref;
|
|
late String repoPath;
|
|
|
|
setUpAll(gjSetupAllTests);
|
|
|
|
Future<void> _setup(
|
|
String head, {
|
|
Map<String, Object> sharedPrefValues = const {},
|
|
}) async {
|
|
var td = await TestData.load(
|
|
headHash: GitHash(head),
|
|
sharedPrefValues: sharedPrefValues,
|
|
);
|
|
|
|
repo = td.repo;
|
|
repoManager = td.repoManager;
|
|
pref = td.pref;
|
|
repoPath = td.repoPath;
|
|
}
|
|
|
|
Widget _buildApp(Widget widget) {
|
|
return GitJournalChangeNotifiers(
|
|
appConfig: AppConfig(),
|
|
repoManager: repoManager,
|
|
pref: pref,
|
|
child: Builder(builder: (context) {
|
|
return MaterialApp(
|
|
home: widget,
|
|
localizationsDelegates: gitJournalLocalizationDelegates,
|
|
supportedLocales: gitJournalSupportedLocales,
|
|
);
|
|
}),
|
|
);
|
|
}
|
|
|
|
testWidgets('New Note Title as FileName', (tester) async {
|
|
await tester.runAsync(
|
|
() async => await _setup('7fc65b59170bdc91013eb56cdc65fa3307f2e7de'),
|
|
);
|
|
|
|
var widget = NoteEditor.newNote(
|
|
repo.rootFolder,
|
|
repo.rootFolder,
|
|
EditorType.Markdown,
|
|
existingText: "",
|
|
existingImages: const [],
|
|
);
|
|
|
|
await tester.pumpWidget(_buildApp(widget));
|
|
await tester.pumpAndSettle();
|
|
|
|
var titleFinder = find.byType(NoteTitleEditor);
|
|
expect(titleFinder, findsOneWidget);
|
|
|
|
await tester.enterText(titleFinder, "Fake-Title");
|
|
await tester.pump();
|
|
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
|
|
await tester.tap(saveButtonFinder);
|
|
await tester.pumpAndSettle();
|
|
await tester.pumpAndSettle(const Duration(seconds: 1));
|
|
|
|
var file = File(p.join(repoPath, 'Fake-Title.md'));
|
|
expect(file.existsSync(), true);
|
|
});
|
|
|
|
testWidgets('New Note with Extra MetaData', (tester) async {
|
|
await tester.runAsync(
|
|
() async => await _setup('7fc65b59170bdc91013eb56cdc65fa3307f2e7de'),
|
|
);
|
|
|
|
var widget = NoteEditor.newNote(
|
|
repo.rootFolder,
|
|
repo.rootFolder,
|
|
EditorType.Markdown,
|
|
existingText: "",
|
|
existingImages: const [],
|
|
newNoteExtraProps: const {'foo': 1},
|
|
);
|
|
|
|
await tester.pumpWidget(_buildApp(widget));
|
|
await tester.pumpAndSettle();
|
|
|
|
var titleFinder = find.byType(NoteTitleEditor);
|
|
expect(titleFinder, findsOneWidget);
|
|
|
|
await tester.enterText(titleFinder, "Fake-Title");
|
|
await tester.pump();
|
|
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
|
|
await tester.runAsync(() async {
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
await tester.tap(saveButtonFinder);
|
|
await tester.pumpAndSettle();
|
|
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
});
|
|
|
|
var file = File(p.join(repoPath, 'Fake-Title.md'));
|
|
expect(file.existsSync(), true);
|
|
|
|
var x = file.readAsStringSync();
|
|
expect(x.length, isNonZero);
|
|
|
|
var note = repo.rootFolder.getNoteWithSpec('Fake-Title.md')!;
|
|
expect(note.extraProps.length, 1);
|
|
expect(note.extraProps['foo'], 1);
|
|
});
|
|
|
|
testWidgets('Existing Note Rename and Exit', (tester) async {
|
|
await tester.runAsync(
|
|
() async => await _setup('7fc65b59170bdc91013eb56cdc65fa3307f2e7de'),
|
|
);
|
|
|
|
// FIXME: Use a proper size of a mobile, also set the DPI
|
|
await tester.binding.setSurfaceSize(const Size(10800, 23400));
|
|
await tester.pumpAndSettle();
|
|
|
|
var note = repo.rootFolder.getNoteWithSpec('doc.md')!;
|
|
var widget = NoteEditor.fromNote(note, repo.rootFolder);
|
|
|
|
await tester.pumpWidget(_buildApp(widget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Rename the note
|
|
var menuButton = find.byIcon(Icons.more_vert);
|
|
expect(menuButton, findsOneWidget);
|
|
await tester.tap(menuButton);
|
|
await tester.pumpAndSettle();
|
|
|
|
var editFileNameButton = find.byKey(const ValueKey('EditFileNameButton'));
|
|
expect(editFileNameButton, findsOneWidget);
|
|
await tester.tap(editFileNameButton);
|
|
await tester.pumpAndSettle();
|
|
|
|
var dialog = find.byType(AlertDialog);
|
|
expect(dialog, findsOneWidget);
|
|
|
|
await tester.showKeyboard(dialog);
|
|
tester.testTextInput.updateEditingValue(
|
|
const TextEditingValue(text: 'bugs.md'),
|
|
);
|
|
|
|
var renameButton = find.byKey(const ValueKey('RenameYes'));
|
|
expect(renameButton, findsOneWidget);
|
|
await tester.tap(renameButton);
|
|
await tester.pumpAndSettle();
|
|
|
|
// Exit the editor
|
|
await tester.runAsync(() async {
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
await tester.tap(saveButtonFinder);
|
|
await tester.pumpAndSettle();
|
|
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
});
|
|
|
|
// Check the FileSystem
|
|
expect(File(p.join(repoPath, 'doc.md')).existsSync(), false);
|
|
expect(File(p.join(repoPath, 'bugs.md')).existsSync(), true);
|
|
|
|
// Check the rootFolder
|
|
expect(repo.rootFolder.getNoteWithSpec('doc.md'), null);
|
|
expect(repo.rootFolder.getNoteWithSpec('bugs.md'), isNotNull);
|
|
expect(repo.rootFolder.getAllNotes().length, 5);
|
|
|
|
// Check the view
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsNothing);
|
|
});
|
|
|
|
testWidgets('Existing Note not modified', (tester) async {
|
|
var headHash = '7fc65b59170bdc91013eb56cdc65fa3307f2e7de';
|
|
await tester.runAsync(
|
|
() async => await _setup(headHash),
|
|
);
|
|
|
|
// FIXME: Use a proper size of a mobile, also set the DPI
|
|
await tester.binding.setSurfaceSize(const Size(10800, 23400));
|
|
await tester.pumpAndSettle();
|
|
|
|
var note = repo.rootFolder.getNoteWithSpec('doc.md')!;
|
|
var widget = NoteEditor.fromNote(note, repo.rootFolder);
|
|
|
|
await tester.pumpWidget(_buildApp(widget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Change the text
|
|
var bodyEditor = find.byType(NoteBodyEditor);
|
|
expect(bodyEditor, findsOneWidget);
|
|
|
|
await tester.showKeyboard(bodyEditor);
|
|
tester.testTextInput.updateEditingValue(
|
|
const TextEditingValue(text: '200 mgs of x\n'),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
|
|
// expect(find.byIcon(Icons.close), findsOneWidget);
|
|
// expect(find.byIcon(Icons.check), findsNothing);
|
|
|
|
late Finder saveButtonFinder;
|
|
saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
|
|
// Exit the editor
|
|
await tester.runAsync(() async {
|
|
await tester.tap(saveButtonFinder);
|
|
await tester.pumpAndSettle();
|
|
|
|
await Future.delayed(const Duration(milliseconds: 1000));
|
|
});
|
|
await tester.pumpAndSettle();
|
|
|
|
// Check the view
|
|
saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsNothing);
|
|
|
|
// Ensure nothing has changed
|
|
var gitRepo = GitRepository.load(repo.repoPath);
|
|
expect(gitRepo.headHash(), GitHash(headHash));
|
|
});
|
|
|
|
testWidgets('Editing a Note body with a heading', (tester) async {
|
|
await tester.runAsync(
|
|
() async => await _setup('fef4ef7341751cb583d768dc9a6b13deca552954'),
|
|
);
|
|
|
|
// FIXME: Use a proper size of a mobile, also set the DPI
|
|
await tester.binding.setSurfaceSize(const Size(10800, 23400));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Open the note
|
|
var note = repo.rootFolder.getNoteWithSpec('heading.md')!;
|
|
var noteHash = GitHash('737943ab9672d967afa91641207a9a3592a522bf');
|
|
var widget = NoteEditor.fromNote(note, repo.rootFolder);
|
|
expect(note.oid, noteHash);
|
|
|
|
await tester.pumpWidget(_buildApp(widget));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Make a modification to the body
|
|
var dialog = find.byType(NoteBodyEditor);
|
|
|
|
await tester.showKeyboard(dialog);
|
|
tester.testTextInput.updateEditingValue(
|
|
const TextEditingValue(text: '# dbg2e\n#dbg3'),
|
|
);
|
|
|
|
await tester.runAsync(() async {
|
|
// Save the Note
|
|
var saveButtonFinder = find.byKey(const ValueKey('NewEntry'));
|
|
expect(saveButtonFinder, findsOneWidget);
|
|
await tester.tap(saveButtonFinder);
|
|
await tester.pumpAndSettle();
|
|
|
|
// FIXME: Can this be avoided?
|
|
await Future.delayed(const Duration(milliseconds: 100));
|
|
});
|
|
|
|
note = repo.rootFolder.getNoteWithSpec('heading.md')!;
|
|
|
|
expect(note.oid, isNot(noteHash));
|
|
expect(note.title, "dbg1");
|
|
expect(note.body, '# dbg2e\n#dbg3');
|
|
});
|
|
}
|