feat(combat): expose weapon reference in observation snapshot
This commit is contained in:
+67
-1
@@ -6,7 +6,7 @@ from collections import Counter
|
||||
|
||||
import pytest
|
||||
|
||||
from pf1e_simulator.dice import DiceExpr, DiceParseError, parse_dice
|
||||
from pf1e_simulator.dice import DiceExpr, DiceParseError, dice_to_str, parse_dice
|
||||
from pf1e_simulator.rng import ScriptedRng
|
||||
|
||||
# ── Parsing: accepted forms ──────────────────────────────────────────────────
|
||||
@@ -194,3 +194,69 @@ class TestDiceExprFlat:
|
||||
rng = ScriptedRng([])
|
||||
expr = DiceExpr.flat(5)
|
||||
assert expr.roll(rng) == 5
|
||||
|
||||
|
||||
# ── dice_to_str: canonical string representation ────────────────────────────
|
||||
|
||||
|
||||
class TestDiceToStr:
|
||||
"""Given: a DiceExpr
|
||||
When: dice_to_str is called
|
||||
Then: returns the canonical string inverse of parse_dice."""
|
||||
|
||||
def test_2d6_plus_3(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=2, sides=6, bonus=3)) == "2d6+3"
|
||||
|
||||
def test_1d4_no_bonus(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=1, sides=4, bonus=0)) == "1d4"
|
||||
|
||||
def test_flat_positive(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=0, sides=0, bonus=7)) == "7"
|
||||
|
||||
def test_flat_negative(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=0, sides=0, bonus=-5)) == "-5"
|
||||
|
||||
def test_flat_zero(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=0, sides=0, bonus=0)) == "0"
|
||||
|
||||
def test_negative_bonus(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=2, sides=6, bonus=-1)) == "2d6-1"
|
||||
|
||||
def test_d20_no_bonus(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=1, sides=20, bonus=0)) == "1d20"
|
||||
|
||||
def test_large_dice(self) -> None:
|
||||
assert dice_to_str(DiceExpr(count=10, sides=100, bonus=50)) == "10d100+50"
|
||||
|
||||
|
||||
class TestDiceToStrRoundTrip:
|
||||
"""Given: a valid dice string
|
||||
When: parse_dice → dice_to_str → parse_dice
|
||||
Then: the final DiceExpr equals the first."""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"text",
|
||||
[
|
||||
"2d6+3",
|
||||
"2d6-1",
|
||||
"1d4",
|
||||
"d20",
|
||||
"7",
|
||||
"-5",
|
||||
"0",
|
||||
"10d100+50",
|
||||
"1d6",
|
||||
"4d8-2",
|
||||
],
|
||||
)
|
||||
def test_round_trip_equivalence(self, text: str) -> None:
|
||||
first = parse_dice(text)
|
||||
serialized = dice_to_str(first)
|
||||
second = parse_dice(serialized)
|
||||
assert first == second
|
||||
|
||||
def test_round_trip_any_flat(self) -> None:
|
||||
for n in (-100, -1, 0, 1, 42, 999):
|
||||
expr = parse_dice(str(n))
|
||||
assert dice_to_str(expr) == str(n)
|
||||
assert parse_dice(dice_to_str(expr)) == expr
|
||||
|
||||
Reference in New Issue
Block a user