diff --git a/.planning/phases/01-foundation/01-01-PLAN.md b/.planning/phases/01-foundation/01-01-PLAN.md
index 37988cb..2d2e81b 100644
--- a/.planning/phases/01-foundation/01-01-PLAN.md
+++ b/.planning/phases/01-foundation/01-01-PLAN.md
@@ -15,6 +15,10 @@ files_modified:
- lib/core/theme/app_theme.dart
- lib/core/theme/theme_provider.dart
- lib/l10n/app_de.arb
+ - test/core/database/database_test.dart
+ - test/core/theme/theme_test.dart
+ - test/core/theme/color_scheme_test.dart
+ - test/l10n/localization_test.dart
autonomous: true
requirements:
- FOUND-01
@@ -60,6 +64,18 @@ must_haves:
- path: "lib/l10n/app_de.arb"
provides: "German localization strings"
contains: "tabHome"
+ - path: "test/core/database/database_test.dart"
+ provides: "Database unit and smoke tests (FOUND-01)"
+ contains: "schemaVersion"
+ - path: "test/core/theme/theme_test.dart"
+ provides: "Theme switching widget test (THEME-01)"
+ contains: "ThemeMode"
+ - path: "test/core/theme/color_scheme_test.dart"
+ provides: "ColorScheme unit tests (THEME-02)"
+ contains: "ColorScheme"
+ - path: "test/l10n/localization_test.dart"
+ provides: "Localization widget test (FOUND-03)"
+ contains: "AppLocalizations"
key_links:
- from: "lib/core/theme/theme_provider.dart"
to: "shared_preferences"
@@ -76,10 +92,10 @@ must_haves:
---
-Scaffold the Flutter project and build all core infrastructure: Drift database with migration workflow, Riverpod providers with code generation, theme definitions (sage & stone palette), and ARB localization strings.
+Scaffold the Flutter project and build all core infrastructure: Drift database with migration workflow, Riverpod providers with code generation, theme definitions (sage & stone palette), and ARB localization strings. Create Wave 0 test scaffolding for database, theme, and localization.
-Purpose: Establish every foundational dependency and pattern so Plan 02 can build the UI shell without any infrastructure work.
-Output: A Flutter project that compiles, has all dependencies resolved, code generation working, database initialized, and theme/localization ready for consumption by UI code.
+Purpose: Establish every foundational dependency and pattern so Plan 02 can build the UI shell without any infrastructure work. Tests provide fast feedback during execution.
+Output: A Flutter project that compiles, has all dependencies resolved, code generation working, database initialized, theme/localization ready for consumption by UI code, and test scaffolding in place.
@@ -164,16 +180,21 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
- Task 2: Create core infrastructure — database, providers, theme, and localization strings
+ Task 2: Create core infrastructure, localization strings, and Wave 0 test scaffolding
lib/core/database/database.dart,
lib/core/providers/database_provider.dart,
lib/core/theme/app_theme.dart,
lib/core/theme/theme_provider.dart,
- lib/l10n/app_de.arb
+ lib/l10n/app_de.arb,
+ lib/main.dart,
+ test/core/database/database_test.dart,
+ test/core/theme/theme_test.dart,
+ test/core/theme/color_scheme_test.dart,
+ test/l10n/localization_test.dart
-1. Create `lib/core/database/database.dart` — the Drift database class:
+1. Create `lib/core/database/database.dart` -- the Drift database class:
- Import `package:drift/drift.dart` and `package:drift_flutter/drift_flutter.dart`
- Add `part 'database.g.dart';`
- Define `@DriftDatabase(tables: [])` with empty tables list (tables added in Phase 2)
@@ -183,35 +204,35 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
- Static `_openConnection()` returns `driftDatabase(name: 'household_keeper', native: const DriftNativeOptions(databaseDirectory: getApplicationSupportDirectory))`
- Import `package:path_provider/path_provider.dart` for `getApplicationSupportDirectory`
-2. Create `lib/core/providers/database_provider.dart` — Riverpod provider for database:
+2. Create `lib/core/providers/database_provider.dart` -- Riverpod provider for database:
- Import riverpod_annotation and the database
- Add `part 'database_provider.g.dart';`
- Use `@Riverpod(keepAlive: true)` annotation (database must persist)
- Function `appDatabase(Ref ref)` returns `AppDatabase()`
- The provider creates the singleton database instance
-3. Create `lib/core/theme/app_theme.dart` — light and dark theme definitions:
+3. Create `lib/core/theme/app_theme.dart` -- light and dark theme definitions:
- Define `AppTheme` class with static methods `lightTheme()` and `darkTheme()` returning `ThemeData`
- Light ColorScheme: `ColorScheme.fromSeed(seedColor: Color(0xFF7A9A6D), brightness: Brightness.light, dynamicSchemeVariant: DynamicSchemeVariant.tonalSpot).copyWith(surface: Color(0xFFF5F0E8), surfaceContainerLowest: Color(0xFFFAF7F2), surfaceContainerLow: Color(0xFFF2EDE4), surfaceContainer: Color(0xFFEDE7DC), surfaceContainerHigh: Color(0xFFE7E0D5), surfaceContainerHighest: Color(0xFFE0D9CE))`
- Dark ColorScheme: Same seed, `Brightness.dark`, `.copyWith(surface: Color(0xFF2A2520), surfaceContainerLowest: Color(0xFF1E1A16), surfaceContainerLow: Color(0xFF322D27), surfaceContainer: Color(0xFF3A342E), surfaceContainerHigh: Color(0xFF433D36), surfaceContainerHighest: Color(0xFF4D463F))`
- Both ThemeData set `useMaterial3: true` and use the respective ColorScheme
-4. Create `lib/core/theme/theme_provider.dart` — Riverpod provider for theme mode:
+4. Create `lib/core/theme/theme_provider.dart` -- Riverpod provider for theme mode:
- Import riverpod_annotation, flutter/material.dart, shared_preferences
- Add `part 'theme_provider.g.dart';`
- `@riverpod class ThemeNotifier extends _$ThemeNotifier`
- `build()` method: read from SharedPreferences key `'theme_mode'`, parse to ThemeMode enum, default to `ThemeMode.system`
- `setThemeMode(ThemeMode mode)` method: update state, persist to SharedPreferences
- - Use `ref.read` pattern for async SharedPreferences access (NOT ref.watch — this is a Notifier, not build())
+ - Use `ref.read` pattern for async SharedPreferences access (NOT ref.watch -- this is a Notifier, not build())
- Helper: `_themeModeFromString(String? value)` and `_themeModeToString(ThemeMode mode)` for serialization
-5. Create `lib/l10n/app_de.arb` — German localization strings for all Phase 1 UI:
+5. Create `lib/l10n/app_de.arb` -- German localization strings for all Phase 1 UI:
```json
{
"@@locale": "de",
"appTitle": "HouseHoldKeaper",
- "tabHome": "Ubersicht",
- "tabRooms": "Raume",
+ "tabHome": "\u00dcbersicht",
+ "tabRooms": "R\u00e4ume",
"tabSettings": "Einstellungen",
"homeEmptyTitle": "Noch nichts zu tun!",
"homeEmptyMessage": "Lege zuerst einen Raum an, um Aufgaben zu planen.",
@@ -224,7 +245,7 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
"themeSystem": "System",
"themeLight": "Hell",
"themeDark": "Dunkel",
- "settingsSectionAbout": "Uber",
+ "settingsSectionAbout": "\u00dcber",
"aboutAppName": "HouseHoldKeaper",
"aboutTagline": "Dein Haushalt, entspannt organisiert.",
"aboutVersion": "Version {version}",
@@ -235,9 +256,9 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
}
}
```
- Note: Use proper German characters (umlauts) where appropriate. The tab labels "Ubersicht" should be "Ubersicht" and "Raume" should be "Raume" — but check CONTEXT.md which shows them without umlauts. Use umlauts in the ARB file: "Ubersicht", "Raume", "Uber" should actually be with umlauts if the font supports it. Per the CONTEXT.md the user specified "Ubersicht", "Raume", "Einstellungen" — follow exactly as specified there.
+ IMPORTANT: Use proper German umlauts throughout -- "Ubersicht" with umlaut (U+00DC), "Raume" with umlaut (U+00E4), "Uber" with umlaut (U+00DC). Per CONTEXT.md user decision: labels are "Ubersicht", "Raume", "Einstellungen" with umlauts.
-6. Remove the default `lib/main.dart` content and replace with a minimal placeholder that imports ProviderScope (just enough to verify compilation — full wiring happens in Plan 02):
+6. Remove the default `lib/main.dart` content and replace with a minimal placeholder that imports ProviderScope (just enough to verify compilation -- full wiring happens in Plan 02):
```dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -253,12 +274,41 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
8. Run Drift migration capture: `dart run drift_dev make-migrations`
This captures schema version 1 in `drift_schemas/` directory.
-9. Run `dart analyze` to verify riverpod_lint is active and no analysis issues exist.
+9. Create Wave 0 test files:
+
+ a. `test/core/database/database_test.dart` (covers FOUND-01):
+ - Test that `AppDatabase(NativeDatabase.memory())` opens successfully
+ - Test that `schemaVersion` equals 1
+ - Test that the database can be closed without error
+ - Use in-memory database (`NativeDatabase.memory()`) for test isolation
+
+ b. `test/core/theme/color_scheme_test.dart` (covers THEME-02):
+ - Test that `AppTheme.lightTheme()` has `Brightness.light`
+ - Test that `AppTheme.darkTheme()` has `Brightness.dark`
+ - Test that both use sage green seed: verify `primary` color is in the green hue range
+ - Test that light surface color is warm (0xFFF5F0E8)
+ - Test that dark surface color is warm charcoal (0xFF2A2520), not cold gray
+
+ c. `test/core/theme/theme_test.dart` (covers THEME-01):
+ - Widget test: wrap a `MaterialApp` with `ProviderScope` and verify that `ThemeNotifier` defaults to `ThemeMode.system`
+ - Test that calling `setThemeMode(ThemeMode.dark)` updates state
+ - Test that calling `setThemeMode(ThemeMode.light)` updates state
+ - Use `SharedPreferences.setMockInitialValues({})` for test isolation
+
+ d. `test/l10n/localization_test.dart` (covers FOUND-03):
+ - Widget test: create a `MaterialApp` with `AppLocalizations.localizationsDelegates`, `supportedLocales: [Locale('de')]`, `locale: Locale('de')`
+ - Pump a widget that reads `AppLocalizations.of(context)` and displays `tabHome`
+ - Verify the rendered text contains the expected German string (with umlaut)
+ - Test that all critical keys are non-empty: `appTitle`, `tabHome`, `tabRooms`, `tabSettings`
+
+10. Run `dart analyze` to verify riverpod_lint is active and no analysis issues exist.
+
+11. Run `flutter test` to verify all Wave 0 tests pass.
- cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart run build_runner build --delete-conflicting-outputs 2>&1 | tail -5 && dart analyze 2>&1 | tail -5 && echo "PASS: Codegen and analysis clean"
+ cd /home/jlmak/Projects/jlmak/HouseHoldKeaper && dart run build_runner build --delete-conflicting-outputs 2>&1 | tail -5 && dart analyze 2>&1 | tail -5 && flutter test 2>&1 | tail -10 && echo "PASS: Codegen, analysis, and tests clean"
- database.dart defines AppDatabase with schemaVersion 1. database_provider.dart exposes AppDatabase via @riverpod. app_theme.dart provides lightTheme() and darkTheme() with sage green seed and warm surface overrides. theme_provider.dart provides ThemeNotifier with shared_preferences persistence and ThemeMode.system default. app_de.arb contains all German strings for Phase 1 screens. All .g.dart files generated successfully. drift_dev make-migrations has captured schema v1. dart analyze passes cleanly.
+ database.dart defines AppDatabase with schemaVersion 1. database_provider.dart exposes AppDatabase via @riverpod. app_theme.dart provides lightTheme() and darkTheme() with sage green seed and warm surface overrides. theme_provider.dart provides ThemeNotifier with shared_preferences persistence and ThemeMode.system default. app_de.arb contains all German strings for Phase 1 screens with proper umlauts (Ubersicht, Raume, Uber). All .g.dart files generated successfully. drift_dev make-migrations has captured schema v1. dart analyze passes cleanly. All 4 Wave 0 test files created and passing: database_test.dart, color_scheme_test.dart, theme_test.dart, localization_test.dart.
@@ -268,6 +318,7 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
- `dart run build_runner build` completes without errors (generates .g.dart files)
- `dart run drift_dev make-migrations` completes (schema v1 captured)
- `dart analyze` reports no errors (riverpod_lint active)
+- `flutter test` passes (all Wave 0 tests green)
- `flutter build apk --debug` compiles (project structure valid)
@@ -277,9 +328,10 @@ Output: A Flutter project that compiles, has all dependencies resolved, code gen
- Riverpod providers created with @riverpod annotation and code generation
- Light and dark theme definitions with sage & stone ColorScheme palette
- ThemeMode provider with shared_preferences persistence
-- ARB localization file with all German strings for Phase 1
+- ARB localization file with all German strings for Phase 1 using proper umlauts
- All code generation (.g.dart files) succeeds
- dart analyze passes cleanly with riverpod_lint active
+- Wave 0 tests pass: database (FOUND-01), localization (FOUND-03), theme switching (THEME-01), color scheme (THEME-02)