All OpenUP artifacts are versioned in skara-brae-common under docs/openup/ per the 2026-10-03 decision reversal in design-wi-2-architecture-cleanup.md (supersedes the earlier in-server-docs decision). Verbatim move, no content changes: analysis-design/, requirements/, test/ (6 files).
6.6 KiB
Skara Brae — Test Cases (existing coverage mapped to use cases)
Version 1.0 (WI-2, 2026-10-03) · OpenUP artifact: test/test-cases.md
Baseline: 45 unit tests, all green on wi-2-architecture-cleanup @ 899fde8 (cargo test --workspace).
1. Existing tests → use-case mapping
| Test (file::name) | Verifies | UC |
|---|---|---|
character::stat_bonus_at_20_is_zero / _below_20_is_negative / _above_20_is_positive / _handles_large_values |
OB/DB stat-bonus curve incl. BIGINT headroom | UC-08, UC-05 |
character::xp_for_level_1_is_zero / _2_is_1800 / _scales_subexponentially / _does_not_overflow |
XP curve 18·100·(level−1)² | UC-12 |
character::level_up_fails_at_max_level / _succeeds_with_enough_xp_and_gold / _fails_without_enough_xp / _fails_without_enough_gold |
review-board rules | UC-12 |
character::level_up_cost_scales |
500·level cost | UC-12 |
character::calc_max_hp_depends_on_class_and_con / calc_max_energy_and_nerve_vary_by_class |
class tables | UC-03 |
character::training_cost_scales_with_stat |
5·1.3^(stat/10) cost curve | UC-05 |
character::apply_regen_restores_resources / _no_change_if_no_time_passed |
lazy regen (180 s / 300 s / 300 s) | shared sub-flow Regenerate Resources |
character::roll_stats_returns_all_five / race_modifiers_apply |
character creation rolls ± race mods | UC-03 |
character::create_character_is_deterministic_under_seeded_rng |
WI-1 injectable RNG at creation | UC-03, NFR-05 |
combat::open_ended_roll_stays_in_range |
d100 open-ended re-rolls (≥96 / ≤5) | UC-08 |
combat::offensive_bonus_includes_stat_and_base / defensive_bonus_includes_stat_and_base |
OB/DB composition | UC-08 |
combat::crit_damage_cap_equal_level_is_none / _higher_defender_reduces / _scaling |
level-gap crit caps (0.60/0.40/0.15/0.05) | UC-08 |
combat::resolve_attack_can_hit_or_miss |
round structure and HP clamping | UC-08 |
combat::resolve_combat_produces_winner |
fight termination, winner/loser | UC-08 |
combat::parse_attack_type_maps_known_types |
slash/crush/puncture + default crush | UC-08 |
services::pick_enemy_respects_weights |
weighted encounter draw | UC-08 |
services::train_stat_increases_stat / _fails_without_energy / _fails_without_gold / _fails_invalid_stat / train_constitution_recals_hp |
gym rules incl. max-HP recompute | UC-05 |
services::equip_item_moves_from_inventory_to_slot / _swaps_previous / _fails_if_not_in_inventory |
equip semantics | UC-06 |
services::unequip_item_moves_to_inventory / _fails_empty_slot |
unequip semantics | UC-06 |
services::equipped_damage_sums_weapon_slots / total_defense_sums_all_slots / equipped_attack_type_returns_weapon_type / _defaults_to_crush |
equipment → combat stats | UC-08 |
| (WI-1) seeded determinism pattern across the above | RNG injection | NFR-05 |
2. Coverage gaps the WI-2 refactor must not lose (and currently uncovered areas)
Covered code being moved — the run_adventure handler body (routes/mod.rs:409–567) is currently not directly tested; its ingredients (regen, pick_enemy, equipped stats, combat resolution) are covered per §1. WI-2 therefore adds direct service-level tests while moving the code:
| New test | Vector (design note §7) | UC |
|---|---|---|
adventure::run_adventure_win_applies_rewards_and_loot |
A1: seeded win → xp/gold/nerve/loot/inventory/exact outcome fields | UC-08 main |
adventure::run_adventure_defeat_sets_hp_to_zero |
A2: overwhelming enemy → no rewards | UC-08 alt |
adventure::run_adventure_rejects_incapacitated |
A3: hp = 0 → CharacterIncapacitated, nerve intact |
UC-08 exception |
adventure::run_adventure_rejects_insufficient_nerve |
A4 → NotEnoughNerve |
UC-08 exception |
adventure::run_adventure_applies_regen_before_guards |
A5: regen visible in combat HP | shared sub-flow |
adventure::run_adventure_charges_spell_upkeep_on_win_and_loss |
A6 both paths | UC-08 step 8 / UC-11 interplay |
adventure::run_adventure_filters_loot_to_catalog_items |
A7 drop for unknown item id skipped | UC-08 step 6 / NFR-07 |
adventure::run_adventure_is_deterministic_under_seeded_rng (+ optional golden CombatLog fixture) |
A8 two seeds-42 runs identical | NFR-05 |
routes::wire_identity_adventure_response … wire_identity_learn_response (W1–W6) |
byte-for-byte serde_json::to_string equality of each new DTO against golden strings recorded from the current json! expressions before the refactor; golden keys in lexicographic order at every nesting level (serde_json has no preserve_order — json! objects emit sorted keys; the adventure DTO's combat_log is the §4.3 Value bridge, defect #14) |
UC-08/09/11, NFR-19 |
New helper/constant pins (design note §4.4–4.5): as_str parity for ItemType/Quality (wire-format guarantee NFR-19), gym_display_order_covers_all_training_grounds (pins GymResponse.stats order to routes/mod.rs:588–594, which differs from TRAINING_GROUNDS order), race/class table exhaustiveness, embedded-JSON loader parses (5), caster_spell_level spot values, spell_learn_cost guard spot checks (0, −1, 8 → 999_999).
Known remaining gaps (documented, out of WI-2 scope — see design note Q3):
- Heal cost logic (UC-09) and spell learn/activate rules (UC-11) live in handlers and have no unit tests; WI-2 only types their responses.
- Shop buy/sell stock transitions (UC-07), auth flows (UC-01/02), and level-up handler status mapping (UC-12 → all 422) have no HTTP-level integration tests. The exhaustive
domain_statusmatch (compile-time totality) is the WI-2 mitigation for the mapping itself. - No test asserts JSON field order; the response structs declare fields in wire order and the golden CombatLog fixture pins the largest payload.
3. Regression protocol for WI-2 (coder must run per commit)
cargo fmt --checkcargo clippy --all-targets -- -D warningscargo test --workspace— 45 baseline tests green at every step; the only permitted test edits are the 9 mechanical assertion updates listed in design note §4.1 (3level_up, 3train_stat, 1equip_item, 1unequip_item, 1pick_enemy_respects_weights— the last gains an Ok-path.unwrap()becausepick_enemybecomesResult-returning) plus newly added tests.- Manual wire spot-check (recommended once, after commit 5): run the server, exercise
GET /api/characters/{id}/adventure,POST …/heal,GET …/spells,POST …/spells(both modes) and diff responses byte-for-byte against pre-refactor output — field names, key order (lexicographic, since serde_json runs withoutpreserve_order), null-ness, number formatting.