Shuffle/app/test/helpers/pump_app.dart
cschlaefke adf61b3ba2 test: add pumpApp helpers, fakes and coverage matrix template
Refs #31

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-02 20:21:55 +01:00

103 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_riverpod/misc.dart' show Override;
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:shuffle/app.dart';
import 'package:shuffle/core/l10n/app_locale.dart';
import 'package:shuffle/core/theme/app_theme.dart';
import 'package:shuffle/l10n/app_localizations.dart';
import 'fakes.dart';
/// Pumpt ein einzelnes Widget ([home]) oder einen eigenen [router] in eine
/// Test-App mit AppTheme, l10n-Delegates, ProviderScope und fester [locale].
///
/// Genau eines von [home] und [router] ist anzugeben. Ohne [overrides]
/// gelten [testOverrides] (feste AppConfig, Supabase-Mock). Gibt den
/// [ProviderContainer] zurück, um Provider im Test zu lesen.
Future<ProviderContainer> pumpApp(
WidgetTester tester, {
Widget? home,
GoRouter? router,
Locale locale = const Locale('de'),
List<Override>? overrides,
ThemeMode themeMode = ThemeMode.light,
double? textScale,
bool settle = true,
}) async {
assert(
(home == null) != (router == null),
'Entweder home oder router angeben.',
);
final container = ProviderContainer.test(
overrides: overrides ?? testOverrides(),
);
Widget builder(BuildContext context, Widget? child) => textScale == null
? child!
: MediaQuery(
data: MediaQuery.of(context)
.copyWith(textScaler: TextScaler.linear(textScale)),
child: child!,
);
const delegates = <LocalizationsDelegate<dynamic>>[
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
];
final theme = AppTheme.light();
final darkTheme = AppTheme.dark();
await tester.pumpWidget(
UncontrolledProviderScope(
container: container,
child: router != null
? MaterialApp.router(
routerConfig: router,
theme: theme,
darkTheme: darkTheme,
themeMode: themeMode,
locale: locale,
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: delegates,
localeResolutionCallback: (l, _) => resolveAppLocale(l),
builder: builder,
)
: MaterialApp(
home: home,
theme: theme,
darkTheme: darkTheme,
themeMode: themeMode,
locale: locale,
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: delegates,
localeResolutionCallback: (l, _) => resolveAppLocale(l),
builder: builder,
),
),
);
if (settle) await tester.pumpAndSettle();
return container;
}
/// Pumpt die echte [ShuffleApp] (inkl. Router) mit der Gerätesprache
/// [deviceLocale]. Die Sprache wird nach dem Test automatisch zurückgesetzt.
Future<ProviderContainer> pumpShuffleApp(
WidgetTester tester, {
Locale deviceLocale = const Locale('en'),
List<Override>? overrides,
}) async {
tester.platformDispatcher.localesTestValue = [deviceLocale];
addTearDown(tester.platformDispatcher.clearLocalesTestValue);
final container = ProviderContainer.test(
overrides: overrides ?? testOverrides(),
);
await tester.pumpWidget(
UncontrolledProviderScope(container: container, child: const ShuffleApp()),
);
await tester.pumpAndSettle();
return container;
}