mod application; mod commands; mod domain; mod errors; mod events; pub use application::*; pub use commands::*; pub use domain::*; pub use errors::*; pub use events::*; #[cfg(test)] mod tests { use super::*; #[test] fn create_initial_player_progression_starts_from_level_one() { let snapshot = create_initial_player_progression("user_001".to_string(), 10).expect("should build"); assert_eq!(snapshot.level, 1); assert_eq!(snapshot.total_xp, 0); assert_eq!(snapshot.current_level_xp, 0); assert_eq!(snapshot.xp_to_next_level, 60); assert_eq!(snapshot.last_granted_source, None); } #[test] fn grant_player_experience_promotes_level_from_quest_reward() { let current = build_player_progression_snapshot("user_001".to_string(), 50, None, 10, 10) .expect("current snapshot should build"); let next = grant_player_experience( current, PlayerProgressionGrantInput { user_id: "user_001".to_string(), amount: 40, source: PlayerProgressionGrantSource::Quest, updated_at_micros: 20, }, ) .expect("grant should succeed"); assert_eq!(next.level, 2); assert_eq!(next.total_xp, 90); assert_eq!(next.current_level_xp, 30); assert_eq!(next.xp_to_next_level, 88); assert_eq!(next.pending_level_ups, 1); assert_eq!( next.last_granted_source, Some(PlayerProgressionGrantSource::Quest) ); } #[test] fn build_level_benchmark_matches_node_curve() { let benchmark = build_level_benchmark(5); assert_eq!(benchmark.level, 5); assert_eq!(benchmark.xp_to_next_level, 268); assert_eq!(benchmark.cumulative_xp_required, 472); assert_eq!(benchmark.reference_strength, 260); assert_eq!(benchmark.base_hp, 436); } #[test] fn chapter_boundary_pseudo_level_millis_grows_with_chapter_index() { let first = resolve_chapter_boundary_pseudo_level_millis(1, 3); let second = resolve_chapter_boundary_pseudo_level_millis(2, 3); let third = resolve_chapter_boundary_pseudo_level_millis(3, 3); assert!(second > first); assert!(third > second); } #[test] fn build_chapter_auto_level_profile_applies_role_offset() { let standard = build_chapter_auto_level_profile(ChapterAutoLevelProfileInput { chapter_id: "chapter-3".to_string(), chapter_index: 3, entry_pseudo_level_millis: 6_200, exit_pseudo_level_millis: 8_800, stage_progress_millis: 1_000, progression_role: ProgressionRole::HostileStandard, }) .expect("standard profile should build"); let boss = build_chapter_auto_level_profile(ChapterAutoLevelProfileInput { chapter_id: "chapter-3".to_string(), chapter_index: 3, entry_pseudo_level_millis: 6_200, exit_pseudo_level_millis: 8_800, stage_progress_millis: 1_000, progression_role: ProgressionRole::HostileBoss, }) .expect("boss profile should build"); assert_eq!(standard.progression_role, ProgressionRole::HostileStandard); assert_eq!(boss.progression_role, ProgressionRole::HostileBoss); assert!(boss.level >= standard.level + 2); assert_eq!(boss.source, LevelProfileSource::ChapterAuto); } #[test] fn build_hostile_experience_reward_matches_existing_fallback_expectation() { let level_profile = RuntimeEntityLevelProfile { level: 5, reference_strength: 260, chapter_id: None, chapter_index: None, progression_role: ProgressionRole::HostileStandard, source: LevelProfileSource::Manual, }; let reward = build_hostile_experience_reward(5, &level_profile, 1_000, None); let hp = resolve_hostile_battle_max_hp(&level_profile); assert_eq!(reward, 20); assert_eq!(hp, 48); } #[test] fn apply_chapter_progression_ledger_accumulates_actual_values() { let current = build_chapter_progression_snapshot(ChapterProgressionInput { user_id: "user_001".to_string(), chapter_id: "chapter-1".to_string(), chapter_index: 1, total_chapters: 3, entry_pseudo_level_millis: 1_000, exit_pseudo_level_millis: 5_000, entry_level: 1, exit_level: 5, planned_total_xp: 320, planned_quest_xp: 200, planned_hostile_xp: 120, expected_hostile_defeat_count: 3, level_at_entry: 1, pace_band: ChapterPaceBand::OpeningFast, updated_at_micros: 10, }) .expect("chapter snapshot should build"); let next = apply_chapter_progression_ledger( current, ChapterProgressionLedgerInput { user_id: "user_001".to_string(), chapter_id: "chapter-1".to_string(), granted_quest_xp: 60, granted_hostile_xp: 20, hostile_defeat_increment: 1, level_at_exit: Some(2), updated_at_micros: 20, }, ) .expect("ledger apply should succeed"); assert_eq!(next.actual_quest_xp, 60); assert_eq!(next.actual_hostile_xp, 20); assert_eq!(next.actual_hostile_defeat_count, 1); assert_eq!(next.level_at_exit, Some(2)); } }