skara-brae-common/docs/openup/test/test-cases.md
Jan-Peter von Hunnius 4798f55660 docs(openup): move WI-2 OpenUP work set verbatim from skara-brae-server
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).
2026-10-03 17:17:44 +02:00

6.6 KiB
Raw Blame History

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_status match (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)

  1. cargo fmt --check
  2. cargo clippy --all-targets -- -D warnings
  3. cargo 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 (3 level_up, 3 train_stat, 1 equip_item, 1 unequip_item, 1 pick_enemy_respects_weights — the last gains an Ok-path .unwrap() because pick_enemy becomes Result-returning) plus newly added tests.
  4. 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 without preserve_order), null-ness, number formatting.