sb-api: label helpers wiring + gym/stat_value + policy constants (WI-2, issue #2)

This commit is contained in:
Jan-Peter von Hunnius 2026-10-03 12:08:21 +02:00
parent 5d5a594a7a
commit f0659421e7
7 changed files with 217 additions and 47 deletions

View file

@ -392,6 +392,27 @@ pub fn find_class_info(class: &Class) -> &'static ClassInfo {
.expect("invalid class")
}
/// Gym stat display order — pinned to the get_gym handler's fixed array
/// (routes/mod.rs:588–594), deliberately differs from TRAINING_GROUNDS order.
pub const GYM_STAT_DISPLAY_ORDER: &[&str] = &[
"strength",
"intelligence",
"dexterity",
"constitution",
"luck",
];
pub fn stat_value(stats: &CharacterStats, stat: &str) -> Option<i64> {
match stat {
"strength" => Some(stats.strength),
"intelligence" => Some(stats.intelligence),
"dexterity" => Some(stats.dexterity),
"constitution" => Some(stats.constitution),
"luck" => Some(stats.luck),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -631,4 +652,70 @@ mod tests {
assert_eq!(first.energy, second.energy);
assert_eq!(first.nerve, second.nerve);
}
#[test]
fn gym_display_order_covers_all_training_grounds() {
let stats = CharacterStats {
strength: 10,
intelligence: 11,
dexterity: 12,
constitution: 13,
luck: 14,
};
assert_eq!(GYM_STAT_DISPLAY_ORDER.len(), TRAINING_GROUNDS.len());
for name in GYM_STAT_DISPLAY_ORDER {
assert!(
TRAINING_GROUNDS.iter().any(|g| g.stat == *name),
"no training ground for stat {}",
name
);
assert!(
stat_value(&stats, name).is_some(),
"stat_value cannot resolve {}",
name
);
}
for ground in TRAINING_GROUNDS {
assert!(
GYM_STAT_DISPLAY_ORDER.contains(&ground.stat),
"gym display order missing stat {}",
ground.stat
);
}
}
#[test]
fn race_table_covers_all_variants() {
let all = [
Race::Human,
Race::Elf,
Race::Dwarf,
Race::Hobbit,
Race::HalfElf,
];
for race in &all {
assert!(RACES.iter().any(|r| &r.race == race));
let _ = find_race_info(race);
}
}
#[test]
fn class_table_covers_all_variants() {
let all = [
Class::Warrior,
Class::Paladin,
Class::Rogue,
Class::Bard,
Class::Hunter,
Class::Monk,
Class::Mage,
Class::Wizard,
Class::Conjurer,
Class::Sorcerer,
];
for class in &all {
assert!(CLASSES.iter().any(|c| &c.class == class));
let _ = find_class_info(class);
}
}
}