163 lines
5.5 KiB
Rust
163 lines
5.5 KiB
Rust
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));
|
|
}
|
|
}
|