testsAndMisc/horatio/horatio_app/test/app_test.dart
Krzysztof kuhy Rudnicki fa5ccdaa96 feat: annotations subsystem — core models, drift DB, cubits, and UI
Add the complete annotations feature for marking and annotating script text:

Core models (horatio_core):
- TextMark, LineNote, AnnotationSnapshot, MarkType, NoteCategory
- Script.id field + UUID generation in text_parser

Database layer (horatio_app):
- Drift tables: text_marks, line_notes, annotation_snapshots
- AppDatabase with AnnotationDao (full CRUD + streams + bulk replace)

State management:
- AnnotationCubit: mark/note CRUD, line selection, editing context
- AnnotationHistoryCubit: snapshot save/restore with stream updates

UI components:
- MarkOverlay: colored span rendering for text marks
- NoteIndicator: per-line note count badge
- MarkTypePicker: 6-type ActionChip selector
- NoteEditorSheet: category dropdown + text field bottom sheet
- AnnotationEditorScreen: full editor with long-press marks + note editing
- AnnotationHistoryScreen: snapshot timeline with restore dialog

Wiring:
- main.dart: async DB init with path_provider
- app.dart: RepositoryProvider<AnnotationDao>
- router.dart: /annotations + /annotation-history routes
- role_selection_screen: Annotate Script option
- run.sh: app_codegen step + coverage filtering for generated code

352 tests (105 core + 247 app), 100% branch coverage, zero dead code.
2026-03-29 17:59:26 +02:00

61 lines
1.8 KiB
Dart

import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:horatio_app/app.dart';
import 'package:horatio_app/router.dart';
import 'package:horatio_core/horatio_core.dart';
import 'helpers/test_database.dart';
void main() {
testWidgets('HoratioApp builds without crashing', (tester) async {
await tester.pumpWidget(HoratioApp(database: createTestDatabase()));
await tester.pumpAndSettle();
expect(find.text('Horatio'), findsOneWidget);
});
testWidgets('SrsReviewCubit is created when srs-review route is visited',
(tester) async {
await tester.pumpWidget(HoratioApp(database: createTestDatabase()));
await tester.pumpAndSettle();
unawaited(appRouter.push(RoutePaths.srsReview, extra: <SrsCard>[
SrsCard(id: 'c1', cueText: 'Cue', answerText: 'Ans'),
]));
await tester.pumpAndSettle();
expect(find.text('No review session active.'), findsOneWidget);
});
testWidgets('AnnotationDao is provided when annotation route is visited',
(tester) async {
final db = createTestDatabase();
await tester.pumpWidget(HoratioApp(database: db));
await tester.pumpAndSettle();
const role = Role(name: 'Hero');
const script = Script(
id: 'app-ann-id',
title: 'Ann Test',
roles: [role],
scenes: [
Scene(
lines: [
ScriptLine(
text: 'Hello.',
role: role,
sceneIndex: 0,
lineIndex: 0,
),
],
),
],
);
unawaited(appRouter.push(RoutePaths.annotations, extra: script));
await tester.pumpAndSettle();
expect(find.text('Annotate: Ann Test'), findsOneWidget);
// Close the database before teardown to cancel Drift stream timers.
await db.close();
});
}