import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:motorcycle_dash/core/theme/app_colors.dart'; import 'package:motorcycle_dash/core/theme/app_spacing.dart'; import 'package:motorcycle_dash/core/theme/app_typography.dart'; import 'package:motorcycle_dash/core/theme/theme.dart'; import 'package:motorcycle_dash/core/theme/theme_extensions.dart'; import 'package:motorcycle_dash/core/theme/theme_mode_provider.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); group('MotorSignal Design System - Tokens & Hierarchy', () { test('AppColors verifies dark and light semantic palette definitions', () { expect(AppColors.cyberCyan, const Color(0xFF00B4D8)); expect(AppColors.velocityBlue, const Color(0xFF0096C7)); expect(AppColors.raceRed, const Color(0xFFFF3B30)); expect(AppColors.darkBackground, const Color(0xFF0D0F13)); expect(AppColors.darkSurface, const Color(0xFF13171E)); expect(AppColors.lightBackground, const Color(0xFFF3F5F8)); expect(AppColors.lightSurface, const Color(0xFFE9EDF2)); }); test('AppTypography specifies authoritative multi-font system', () { expect(AppTypography.fontTelemetry, 'JetBrains Mono'); expect(AppTypography.fontHeadline, 'Sora'); expect(AppTypography.fontBody, 'Inter'); expect(AppTypography.speedometer.fontFamily, 'JetBrains Mono'); expect(AppTypography.speedometer.fontSize, 96); expect(AppTypography.speedometer.fontWeight, FontWeight.w900); expect(AppTypography.headingCompass.fontFamily, 'Sora'); expect(AppTypography.bodyMd.fontFamily, 'Inter'); expect(AppTypography.button.fontFamily, 'Sora'); }); test('AppSpacing and AppRadius conform to 4dp base grid and 48dp touch targets', () { expect(AppSpacing.xs, 4.0); expect(AppSpacing.sm, 8.0); expect(AppSpacing.md, 12.0); expect(AppSpacing.lg, 16.0); expect(AppSpacing.xl, 24.0); expect(AppSpacing.minTouchTarget, 48.0); expect(AppRadius.sm, 4.0); expect(AppRadius.md, 8.0); expect(AppRadius.lg, 12.0); expect(AppRadius.xl, 16.0); expect(AppRadius.full, 999.0); }); }); group('MotorSignalThemeColors Extension', () { test('Dark and Light presets have correct brightness semantics', () { const dark = MotorSignalThemeColors.dark; expect(dark.cyberCyan, AppColors.cyberCyan); expect(dark.launchGreen, AppColors.launchGreen); expect(dark.surfaceContainer, AppColors.darkSurfaceContainer); const light = MotorSignalThemeColors.light; expect(light.cyberCyan, AppColors.technicalBlue); expect(light.launchGreen, AppColors.launchGreen); expect(light.surfaceContainer, AppColors.lightSurfaceContainer); }); test('copyWith and lerp interpolate colors accurately', () { const dark = MotorSignalThemeColors.dark; final modified = dark.copyWith(cyberCyan: Colors.purple); expect(modified.cyberCyan, Colors.purple); expect(modified.velocityBlue, dark.velocityBlue); final lerped = dark.lerp(MotorSignalThemeColors.light, 0.5); expect(lerped, isA()); expect(lerped.cyberCyan, Color.lerp(dark.cyberCyan, MotorSignalThemeColors.light.cyberCyan, 0.5)); }); }); group('AppTheme ThemeData', () { test('darkTheme configures Material 3 dark brightness and extensions', () { final theme = AppTheme.darkTheme; expect(theme.useMaterial3, isTrue); expect(theme.brightness, Brightness.dark); expect(theme.scaffoldBackgroundColor, AppColors.darkBackground); expect(theme.colorScheme.primary, AppColors.darkPrimary); final ext = theme.extension(); expect(ext, isNotNull); expect(ext?.cyberCyan, AppColors.cyberCyan); }); test('lightTheme configures Material 3 light brightness and extensions', () { final theme = AppTheme.lightTheme; expect(theme.useMaterial3, isTrue); expect(theme.brightness, Brightness.light); expect(theme.scaffoldBackgroundColor, AppColors.lightBackground); expect(theme.colorScheme.primary, AppColors.lightPrimary); final ext = theme.extension(); expect(ext, isNotNull); expect(ext?.cyberCyan, AppColors.technicalBlue); }); }); group('ThemeMode & Persistence Provider', () { test('AppThemeModeNotifier defaults to ThemeMode.system and persists transitions', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final notifier = AppThemeModeNotifier(prefs); expect(notifier.state, ThemeMode.system); await notifier.setThemeMode(ThemeMode.dark); expect(notifier.state, ThemeMode.dark); expect(prefs.getString('app_theme_mode'), 'dark'); await notifier.setThemeMode(ThemeMode.light); expect(notifier.state, ThemeMode.light); expect(prefs.getString('app_theme_mode'), 'light'); await notifier.toggleTheme(); expect(notifier.state, ThemeMode.system); }); test('AppThemeModeNotifier restores saved theme from SharedPreferences', () async { SharedPreferences.setMockInitialValues({'app_theme_mode': 'light'}); final prefs = await SharedPreferences.getInstance(); final notifier = AppThemeModeNotifier(prefs); expect(notifier.state, ThemeMode.light); }); }); }