Skip to content

Commit ad20c16

Browse files
unhappychoiceclaude
andcommitted
test: add mock data providers for screen tests
- MockAnalyticsDataProvider with sample analytics data - MockRecordsDataProvider with 3 sample session records - MockAnimationDataProvider with complete SessionResult 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 09513fb commit ad20c16

File tree

4 files changed

+263
-0
lines changed

4 files changed

+263
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
use gittype::presentation::game::models::ScreenDataProvider;
2+
use gittype::presentation::game::screens::analytics_screen::{AnalyticsData, LangStats, RepoStats};
3+
use gittype::Result;
4+
use std::collections::HashMap;
5+
6+
pub struct MockAnalyticsDataProvider;
7+
8+
impl ScreenDataProvider for MockAnalyticsDataProvider {
9+
fn provide(&self) -> Result<Box<dyn std::any::Any>> {
10+
let mut repository_stats = HashMap::new();
11+
repository_stats.insert(
12+
"test/repo1".to_string(),
13+
RepoStats {
14+
avg_cpm: 350.0,
15+
avg_wpm: 70.0,
16+
avg_accuracy: 95.0,
17+
total_sessions: 10,
18+
total_keystrokes: 1000,
19+
total_mistakes: 50,
20+
total_duration_ms: 60000,
21+
avg_score: 500.0,
22+
best_cpm: 400.0,
23+
best_accuracy: 98.0,
24+
stages_completed: 8,
25+
stages_attempted: 10,
26+
stages_skipped: 0,
27+
},
28+
);
29+
30+
let mut language_stats = HashMap::new();
31+
language_stats.insert(
32+
"Rust".to_string(),
33+
LangStats {
34+
avg_cpm: 340.0,
35+
avg_wpm: 68.0,
36+
avg_accuracy: 94.0,
37+
total_sessions: 5,
38+
total_keystrokes: 500,
39+
total_mistakes: 30,
40+
total_duration_ms: 30000,
41+
avg_score: 480.0,
42+
best_cpm: 380.0,
43+
best_accuracy: 97.0,
44+
stages_completed: 15,
45+
stages_attempted: 20,
46+
stages_skipped: 0,
47+
},
48+
);
49+
50+
let data = AnalyticsData {
51+
total_sessions: 10,
52+
avg_cpm: 350.0,
53+
avg_accuracy: 95.0,
54+
total_time_hours: 1.0,
55+
cpm_trend: vec![
56+
("Day 1".to_string(), 300.0),
57+
("Day 2".to_string(), 350.0),
58+
("Day 3".to_string(), 400.0),
59+
],
60+
accuracy_trend: vec![
61+
("Day 1".to_string(), 90.0),
62+
("Day 2".to_string(), 95.0),
63+
("Day 3".to_string(), 97.0),
64+
],
65+
top_repositories: vec![
66+
("test/repo1".to_string(), 350.0),
67+
("test/repo2".to_string(), 300.0),
68+
],
69+
top_languages: vec![
70+
("Rust".to_string(), 340.0, 20),
71+
("Python".to_string(), 300.0, 15),
72+
],
73+
daily_sessions: HashMap::new(),
74+
best_cpm: 400.0,
75+
total_mistakes: 50,
76+
avg_session_duration: 6.0,
77+
current_streak: 3,
78+
repository_stats,
79+
language_stats,
80+
};
81+
82+
Ok(Box::new(data))
83+
}
84+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
use gittype::domain::models::SessionResult;
2+
use gittype::presentation::game::models::ScreenDataProvider;
3+
use gittype::presentation::game::screens::animation_screen::AnimationData;
4+
use gittype::Result;
5+
use std::time::{Duration, Instant};
6+
7+
pub struct MockAnimationDataProvider;
8+
9+
impl ScreenDataProvider for MockAnimationDataProvider {
10+
fn provide(&self) -> Result<Box<dyn std::any::Any>> {
11+
let session_result = SessionResult {
12+
session_start_time: Instant::now(),
13+
session_duration: Duration::from_secs(60),
14+
valid_session_duration: Duration::from_secs(55),
15+
invalid_session_duration: Duration::from_secs(5),
16+
stages_completed: 3,
17+
stages_attempted: 3,
18+
stages_skipped: 0,
19+
stage_results: vec![],
20+
overall_accuracy: 96.0,
21+
overall_wpm: 75.0,
22+
overall_cpm: 375.0,
23+
valid_keystrokes: 500,
24+
valid_mistakes: 20,
25+
invalid_keystrokes: 0,
26+
invalid_mistakes: 0,
27+
best_stage_wpm: 80.0,
28+
worst_stage_wpm: 70.0,
29+
best_stage_accuracy: 98.0,
30+
worst_stage_accuracy: 94.0,
31+
session_score: 1200.0,
32+
session_successful: true,
33+
};
34+
35+
Ok(Box::new(AnimationData { session_result }))
36+
}
37+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod analytics_screen_mock;
2+
pub mod animation_screen_mock;
3+
pub mod records_screen_mock;
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
use chrono::{TimeZone, Utc};
2+
use gittype::domain::models::storage::{SessionResultData, StoredRepository, StoredSession};
3+
use gittype::presentation::game::models::ScreenDataProvider;
4+
use gittype::presentation::game::screens::records_screen::RecordsScreenData;
5+
use gittype::presentation::game::screens::session_detail_screen::SessionDisplayData;
6+
use gittype::Result;
7+
8+
pub struct MockRecordsDataProvider;
9+
10+
impl ScreenDataProvider for MockRecordsDataProvider {
11+
fn provide(&self) -> Result<Box<dyn std::any::Any>> {
12+
let repositories = vec![
13+
StoredRepository {
14+
id: 1,
15+
user_name: "unhappychoice".to_string(),
16+
repository_name: "gittype".to_string(),
17+
remote_url: "https://github.com/unhappychoice/gittype".to_string(),
18+
},
19+
StoredRepository {
20+
id: 2,
21+
user_name: "rails".to_string(),
22+
repository_name: "rails".to_string(),
23+
remote_url: "https://github.com/rails/rails".to_string(),
24+
},
25+
];
26+
27+
let sessions = vec![
28+
SessionDisplayData {
29+
session: StoredSession {
30+
id: 1,
31+
repository_id: Some(1),
32+
started_at: Utc.with_ymd_and_hms(2024, 10, 7, 12, 30, 0).unwrap(),
33+
completed_at: Some(Utc.with_ymd_and_hms(2024, 10, 7, 12, 31, 0).unwrap()),
34+
branch: Some("main".to_string()),
35+
commit_hash: Some("abc123".to_string()),
36+
is_dirty: false,
37+
game_mode: "default".to_string(),
38+
difficulty_level: Some("Normal".to_string()),
39+
max_stages: Some(3),
40+
time_limit_seconds: None,
41+
},
42+
repository: Some(repositories[0].clone()),
43+
session_result: Some(SessionResultData {
44+
keystrokes: 500,
45+
mistakes: 20,
46+
duration_ms: 60000,
47+
wpm: 75.0,
48+
cpm: 375.0,
49+
accuracy: 96.0,
50+
stages_completed: 3,
51+
stages_attempted: 3,
52+
stages_skipped: 0,
53+
score: 1200.0,
54+
rank_name: Some("Advanced".to_string()),
55+
tier_name: Some("Gold".to_string()),
56+
rank_position: Some(5),
57+
rank_total: Some(100),
58+
position: Some(5),
59+
total: Some(100),
60+
}),
61+
},
62+
SessionDisplayData {
63+
session: StoredSession {
64+
id: 2,
65+
repository_id: Some(2),
66+
started_at: Utc.with_ymd_and_hms(2024, 10, 6, 15, 20, 0).unwrap(),
67+
completed_at: Some(Utc.with_ymd_and_hms(2024, 10, 6, 15, 22, 0).unwrap()),
68+
branch: Some("main".to_string()),
69+
commit_hash: Some("def456".to_string()),
70+
is_dirty: false,
71+
game_mode: "default".to_string(),
72+
difficulty_level: Some("Hard".to_string()),
73+
max_stages: Some(3),
74+
time_limit_seconds: None,
75+
},
76+
repository: Some(repositories[1].clone()),
77+
session_result: Some(SessionResultData {
78+
keystrokes: 650,
79+
mistakes: 35,
80+
duration_ms: 120000,
81+
wpm: 65.0,
82+
cpm: 325.0,
83+
accuracy: 94.6,
84+
stages_completed: 3,
85+
stages_attempted: 3,
86+
stages_skipped: 0,
87+
score: 980.0,
88+
rank_name: Some("Intermediate".to_string()),
89+
tier_name: Some("Silver".to_string()),
90+
rank_position: Some(15),
91+
rank_total: Some(100),
92+
position: Some(15),
93+
total: Some(100),
94+
}),
95+
},
96+
SessionDisplayData {
97+
session: StoredSession {
98+
id: 3,
99+
repository_id: Some(1),
100+
started_at: Utc.with_ymd_and_hms(2024, 10, 5, 9, 10, 0).unwrap(),
101+
completed_at: Some(Utc.with_ymd_and_hms(2024, 10, 5, 9, 11, 0).unwrap()),
102+
branch: Some("develop".to_string()),
103+
commit_hash: Some("ghi789".to_string()),
104+
is_dirty: false,
105+
game_mode: "default".to_string(),
106+
difficulty_level: Some("Easy".to_string()),
107+
max_stages: Some(3),
108+
time_limit_seconds: None,
109+
},
110+
repository: Some(repositories[0].clone()),
111+
session_result: Some(SessionResultData {
112+
keystrokes: 400,
113+
mistakes: 15,
114+
duration_ms: 50000,
115+
wpm: 80.0,
116+
cpm: 400.0,
117+
accuracy: 96.2,
118+
stages_completed: 3,
119+
stages_attempted: 3,
120+
stages_skipped: 0,
121+
score: 1300.0,
122+
rank_name: Some("Expert".to_string()),
123+
tier_name: Some("Platinum".to_string()),
124+
rank_position: Some(3),
125+
rank_total: Some(100),
126+
position: Some(3),
127+
total: Some(100),
128+
}),
129+
},
130+
];
131+
132+
let data = RecordsScreenData {
133+
sessions,
134+
repositories,
135+
};
136+
137+
Ok(Box::new(data))
138+
}
139+
}

0 commit comments

Comments
 (0)