scroll.server/services/game-service/tests/real_catalog.rs
scroll 812052bc3e initial import, client gets to the lobby
titan engine, logic model, auth/game/gateway services.
csv tables pulled out of the ipa are checked in so it runs out of the box.
2026-08-23 07:50:31 +03:00

99 lines
3.7 KiB
Rust

use std::path::{Path, PathBuf};
use game_service::{CardRef, Catalog, DataSelector};
use logic::table;
fn assets_root() -> Option<PathBuf> {
let root = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../assets")
.canonicalize()
.ok()?;
root.join("csv_logic/spells_characters.csv").is_file().then_some(root)
}
#[test]
fn the_shipped_client_tables_load_and_resolve_by_name() {
let Some(root) = assets_root() else {
eprintln!("assets/ is absent, skipping the shipped catalog check");
return;
};
let catalog = Catalog::load(Some(&root));
assert!(catalog.is_loaded(), "catalog failed to load from {root:?}");
let tables = catalog.tables();
assert_eq!(tables.loaded_files().len(), 44);
assert!(tables.skipped_files().is_empty(), "{:?}", tables.skipped_files());
assert_eq!(
tables.global_id_by_name(table::ARENAS, "TrainingCamp"),
Some(titan::GlobalId::new(table::ARENAS, 0))
);
assert_eq!(
tables.global_id_by_name(table::RESOURCES, "Gold"),
Some(titan::GlobalId::new(table::RESOURCES, 1))
);
assert_eq!(
tables.global_id_by_name(table::RESOURCES, "Diamonds"),
Some(titan::GlobalId::new(table::RESOURCES, 0))
);
let knight = tables.spell_by_name("Knight").expect("Knight");
assert_eq!(knight.global_id().class_id, table::SPELLS_CHARACTERS);
assert_eq!(knight.global_id().instance_id, 0);
let fireball = tables.spell_by_name("Fireball").expect("Fireball");
assert_eq!(fireball.global_id().class_id, table::SPELLS_OTHER);
let cannon = tables.spell_by_name("Cannon").expect("Cannon");
assert_eq!(cannon.global_id().class_id, table::SPELLS_BUILDINGS);
}
#[test]
fn continuation_rows_build_the_per_level_arrays() {
let Some(root) = assets_root() else {
return;
};
let catalog = Catalog::load(Some(&root));
let tables = catalog.tables();
let common = tables
.data_by_name(table::RARITIES, "Common")
.expect("Common rarity");
assert!(
common.array_size() > 1,
"rarities.csv uses continuation rows for the upgrade curve"
);
assert_eq!(common.int_at("UpgradeCost", 0), 5);
assert_eq!(common.int_at("UpgradeCost", 1), 20);
assert_eq!(common.int("LevelCount"), 12);
assert_eq!(
common.int_at("UpgradeCost", 999),
common.int_at("UpgradeCost", common.array_size() - 1),
"reading past the end clamps to the last level"
);
let newbie = tables
.treasure_chest_by_name("Newbie1")
.expect("Newbie1 chest");
assert_eq!(newbie.string("Arena"), "TrainingCamp");
let row = newbie.row().expect("row");
let guaranteed = newbie
.csv_table()
.column_index("GuaranteedSpells")
.expect("column");
assert_eq!(row.value_count(guaranteed), 2);
assert_eq!(row.string_at(guaranteed, 0), "Knight");
assert_eq!(row.string_at(guaranteed, 1), "Arrows");
}
#[test]
fn the_default_starter_profile_resolves_against_the_real_tables() {
let Some(root) = assets_root() else {
return;
};
let catalog = Catalog::load(Some(&root));
let starter = game_service::StarterProfile::default();
for card in starter.deck.iter().chain(starter.extra_collection.iter()) {
assert!(
catalog.resolve_card(card).is_some(),
"starter card {card:?} does not resolve"
);
}
let gold = catalog.resolve_resource(&DataSelector::named("Gold"));
assert_eq!(gold.name(), "Gold");
assert_eq!(
gold.global_id(),
Some(titan::GlobalId::new(table::RESOURCES, 1))
);
let arena = catalog.resolve_arena(&starter.arena);
assert_eq!(arena.table_index(), Some(table::ARENAS));
assert!(catalog.resolve_card(&CardRef::named("NotACard")).is_none());
}