Skip to content

Commit c99e5c3

Browse files
jrollinclaude
andcommitted
fix: Isolate storage tests to prevent race conditions in CI
The test_load_empty_stats and test_save_and_load tests were sharing the same ~/.config/typer-cli/stats.json file, causing intermittent failures when tests ran in parallel in the CI environment. Changes: - Add Storage::with_path() test helper for custom file paths - Create create_test_storage() helper using tempfile for isolation - Update tests to use temporary directories instead of shared config - Add tempfile dev-dependency for test isolation - Improve test assertions with explicit session count checks This ensures tests run reliably in both parallel and serial execution, and prevents test interference in CI environments. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent f631a4f commit c99e5c3

File tree

3 files changed

+100
-8
lines changed

3 files changed

+100
-8
lines changed

Cargo.lock

Lines changed: 75 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ serde_json = "1.0"
1111
clap = { version = "4.5", features = ["derive"] }
1212
chrono = { version = "0.4", features = ["serde"] }
1313
rand = "0.8"
14+
15+
[dev-dependencies]
16+
tempfile = "3.14"

src/data/storage.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,15 @@ impl Storage {
1818
Ok(Self { file_path })
1919
}
2020

21+
/// Create a Storage instance with a custom file path (used for testing)
22+
#[cfg(test)]
23+
fn with_path(file_path: PathBuf) -> io::Result<Self> {
24+
if let Some(parent) = file_path.parent() {
25+
fs::create_dir_all(parent)?;
26+
}
27+
Ok(Self { file_path })
28+
}
29+
2130
/// Récupérer le dossier de configuration
2231
fn get_config_dir() -> io::Result<PathBuf> {
2332
let home = std::env::var("HOME").map_err(|_| {
@@ -71,6 +80,14 @@ mod tests {
7180
use crate::data::stats::SessionRecord;
7281
use std::time::Duration;
7382

83+
/// Helper to create a temporary test storage path
84+
fn create_test_storage() -> (Storage, tempfile::TempDir) {
85+
let temp_dir = tempfile::tempdir().unwrap();
86+
let file_path = temp_dir.path().join("test_stats.json");
87+
let storage = Storage::with_path(file_path).unwrap();
88+
(storage, temp_dir)
89+
}
90+
7491
#[test]
7592
fn test_storage_new() {
7693
let storage = Storage::new();
@@ -79,16 +96,16 @@ mod tests {
7996

8097
#[test]
8198
fn test_load_empty_stats() {
82-
let storage = Storage::new().unwrap();
83-
// Si le fichier n'existe pas, on devrait obtenir des stats vides
84-
// Note: ce test pourrait échouer si des stats existent déjà
99+
let (storage, _temp_dir) = create_test_storage();
100+
// When stats file doesn't exist, load should return empty stats
85101
let stats = storage.load();
86102
assert!(stats.is_ok());
103+
assert_eq!(stats.unwrap().session_count(), 0);
87104
}
88105

89106
#[test]
90107
fn test_save_and_load() {
91-
let storage = Storage::new().unwrap();
108+
let (storage, _temp_dir) = create_test_storage();
92109

93110
let mut stats = Stats::new();
94111
stats.add_session(SessionRecord::new(
@@ -105,6 +122,6 @@ mod tests {
105122

106123
// Charger
107124
let loaded_stats = storage.load().unwrap();
108-
assert!(loaded_stats.session_count() >= 1);
125+
assert_eq!(loaded_stats.session_count(), 1);
109126
}
110127
}

0 commit comments

Comments
 (0)