feat: add unit tests (Rust parser+DB, Vitest frontend) and test workflow
This commit is contained in:
@ -0,0 +1,4 @@
|
||||
# Memory Index
|
||||
|
||||
- [TougliGui DB Schema](project_db_schema.md) — 7 tables SQLite, conventions migrate() idempotente, structure quest_previews
|
||||
- [Patterns Rust TougliGui](project_rust_patterns.md) — DbState/Mutex, Result<T,String>, placeholders SQL positionnels, pattern test_db() in-memory
|
||||
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: TougliGui DB Schema
|
||||
description: Tables SQLite créées par db::migrate() et conventions de la couche base de données
|
||||
type: project
|
||||
---
|
||||
|
||||
La fonction `db::migrate()` crée 7 tables via `execute_batch` avec `IF NOT EXISTS` (donc idempotente) :
|
||||
|
||||
- `profiles` (id TEXT PK, name TEXT UNIQUE, created_at TEXT)
|
||||
- `guides` (gid TEXT PK, name TEXT, data TEXT, last_synced_at TEXT)
|
||||
- `quest_completions` (profile_id, quest_name — PK composite, FK → profiles ON DELETE CASCADE)
|
||||
- `settings` (key TEXT PK, value TEXT)
|
||||
- `quest_step_progress` (profile_id, quest_name, step_index — PK composite, FK → profiles)
|
||||
- `resource_inventory` (profile_id, resource_name — PK composite, FK → profiles)
|
||||
- `quest_previews` (quest_url TEXT PK, indicators_json TEXT, cached_at TEXT DEFAULT datetime('now'))
|
||||
|
||||
**Why:** Connaissance nécessaire pour écrire les tests et vérifier les migrations.
|
||||
**How to apply:** Toute modification de schéma doit passer par `migrate()` avec `IF NOT EXISTS` ou une migration additive.
|
||||
@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Patterns Rust observés dans TougliGui
|
||||
description: Conventions de code Rust/Tauri utilisées dans le projet (state, erreurs, SQL, modules)
|
||||
type: project
|
||||
---
|
||||
|
||||
## State Tauri
|
||||
`DbState(pub Mutex<Connection>)` dans `commands.rs` — une seule connexion SQLite partagée via Mutex.
|
||||
|
||||
## Propagation d'erreurs
|
||||
Les commandes Tauri retournent `Result<T, String>` : `.map_err(|e| e.to_string())`. Pas de type d'erreur custom.
|
||||
|
||||
## Paramètres SQL positionnels
|
||||
rusqlite utilise `?1`, `?2`... (positionnels nommés) et non `?` (positionnels ordinals). Les fonctions `get_cached_previews` et `get_cached_urls` construisent dynamiquement les placeholders avec `format!("?{}", i)` pour les `IN (...)` variadic.
|
||||
|
||||
## Sérialisation JSON en DB
|
||||
`quest_previews.indicators_json` stocke un `Vec<CombatIndicator>` sérialisé via `serde_json`. Désérialisé au retour avec `serde_json::from_str`.
|
||||
|
||||
## Structure CombatIndicator (parser.rs)
|
||||
```rust
|
||||
pub struct CombatIndicator {
|
||||
pub combat_type: String,
|
||||
pub count: String,
|
||||
#[serde(default)] pub label: Option<String>,
|
||||
#[serde(default)] pub evitable: bool,
|
||||
}
|
||||
```
|
||||
|
||||
## Pattern tests unitaires DB
|
||||
```rust
|
||||
fn test_db() -> Connection {
|
||||
let conn = Connection::open_in_memory().unwrap();
|
||||
crate::db::migrate(&conn).unwrap();
|
||||
conn
|
||||
}
|
||||
```
|
||||
Chaque test crée sa propre DB in-memory → isolation totale, pas de cleanup nécessaire.
|
||||
|
||||
**Why:** Conventions observées directement dans le code source.
|
||||
**How to apply:** Respecter ces patterns dans tous les ajouts futurs pour maintenir la cohérence.
|
||||
Reference in New Issue
Block a user