Render startup immediately and defer native work with a smooth home transition

This commit is contained in:
Codex
2026-10-14 17:26:24 +08:00
parent bb7a7a2e58
commit ce21cdc10c
17 changed files with 641 additions and 144 deletions
+74
View File
@@ -0,0 +1,74 @@
import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:hepan_everyday/app/app_controller.dart';
import 'package:hepan_everyday/domain/app_settings.dart';
import 'package:hepan_everyday/domain/app_snapshot.dart';
import 'package:hepan_everyday/domain/course_occurrence.dart';
import 'package:hepan_everyday/services/notification_service.dart';
import '../support/fakes.dart';
class WaitingNotifications extends FakeNotifications {
final pending = Completer<ReminderResult>();
@override
Future<ReminderResult> reconcile(
List<CourseOccurrence> events,
AppSettings settings,
DateTime now,
) {
reconciliations++;
return pending.future;
}
}
void main() {
test(
'data-only startup finishes before slow native reminder work starts',
() async {
final notifications = WaitingNotifications();
final calendar = FakeCalendar();
final snapshot = AppSnapshot();
final controller = AppController(
MemoryStore(snapshot),
notifications,
calendar,
DateTime.now,
);
await controller.initialize(reconcileServices: false);
expect(controller.snapshot, same(snapshot));
expect(notifications.reconciliations, 0);
expect(calendar.synchronizations, 0);
final background = controller.refreshServices();
await Future<void>.delayed(Duration.zero);
expect(notifications.reconciliations, 1);
notifications.pending.complete(const ReminderResult(ReminderStatus.off));
await background;
controller.dispose();
},
);
test(
'failed saved-data read still exposes recovery without starting services',
() async {
final store = BrokenStore();
final notifications = FakeNotifications();
final controller = AppController(
store,
notifications,
FakeCalendar(),
DateTime.now,
);
await controller.initialize(reconcileServices: false);
expect(controller.storageReady, isFalse);
expect(controller.lastError, contains('保存文件读取失败'));
expect(notifications.reconciliations, 0);
controller.dispose();
},
);
}
class BrokenStore extends MemoryStore {
@override
Future<AppSnapshot?> load() => Future.error(const FormatException('invalid'));
}