main() awaited all of configureDependencies() (open the encrypted DB, derive the social key, seed/scan the species catalog) before the first runApp, so nothing painted until init finished — startup jank visible as skipped frames. Now main() runs runApp immediately with a Bootstrap widget that shows a native-splash-matching green splash while the heavy work runs, then swaps in TaneApp. On failure it shows a localized error with a retry (configureDependencies is idempotent, so retry is safe). Adds a bootstrap i18n group (en/es/pt/ast) and a widget test for the splash/error frame.
33 lines
1 KiB
Dart
33 lines
1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:tane/bootstrap.dart';
|
|
import 'package:tane/i18n/strings.g.dart';
|
|
|
|
void main() {
|
|
setUp(() => LocaleSettings.setLocaleSync(AppLocale.en));
|
|
|
|
testWidgets('shows a spinner and no error while booting', (tester) async {
|
|
await tester.pumpWidget(
|
|
TranslationProvider(child: const BootstrapSplash(error: false)),
|
|
);
|
|
|
|
expect(find.byType(CircularProgressIndicator), findsOneWidget);
|
|
expect(find.text(t.bootstrap.failed), findsNothing);
|
|
expect(find.text(t.bootstrap.retry), findsNothing);
|
|
});
|
|
|
|
testWidgets('on error shows the message and a working retry', (tester) async {
|
|
var retries = 0;
|
|
await tester.pumpWidget(
|
|
TranslationProvider(
|
|
child: BootstrapSplash(error: true, onRetry: () => retries++),
|
|
),
|
|
);
|
|
|
|
expect(find.byType(CircularProgressIndicator), findsNothing);
|
|
expect(find.text(t.bootstrap.failed), findsOneWidget);
|
|
|
|
await tester.tap(find.text(t.bootstrap.retry));
|
|
expect(retries, 1);
|
|
});
|
|
}
|