fix(loaders): coerce combatant level with Pydantic-consistent rules
Feat resolution read level with an isinstance(int) check and fell back to 1, while Pydantic accepts numeric strings and lossless floats: a level-4 sheet authored as "4" got Toughness for level 1. _parse_level now runs the value through TypeAdapter(int) (same lax coercion as the model) and raises CombatantLoadError for values the model would reject.
This commit is contained in:
@@ -146,6 +146,28 @@ class TestFeatures:
|
||||
c = load_combatant(_write(tmp_path, data))
|
||||
assert c.features[0].effects == toughness(7).effects
|
||||
|
||||
def test_toughness_numeric_string_level(self, tmp_path: Path) -> None:
|
||||
data = _minimal_payload(level="4", features=["Toughness"])
|
||||
c = load_combatant(_write(tmp_path, data))
|
||||
assert c.level == 4
|
||||
assert c.features[0].effects == toughness(4).effects
|
||||
|
||||
def test_toughness_lossless_float_level(self, tmp_path: Path) -> None:
|
||||
data = _minimal_payload(level=4.0, features=["Toughness"])
|
||||
c = load_combatant(_write(tmp_path, data))
|
||||
assert c.level == 4
|
||||
assert c.features[0].effects == toughness(4).effects
|
||||
|
||||
def test_non_numeric_level_raises(self, tmp_path: Path) -> None:
|
||||
data = _minimal_payload(level="abc", features=["Toughness"])
|
||||
with pytest.raises(CombatantLoadError, match="level must be an integer"):
|
||||
load_combatant(_write(tmp_path, data))
|
||||
|
||||
def test_fractional_level_raises(self, tmp_path: Path) -> None:
|
||||
data = _minimal_payload(level=4.5, features=["Toughness"])
|
||||
with pytest.raises(CombatantLoadError, match="level must be an integer"):
|
||||
load_combatant(_write(tmp_path, data))
|
||||
|
||||
def test_level_default_one(self, tmp_path: Path) -> None:
|
||||
data = _minimal_payload(level=1, features=["Toughness"])
|
||||
c = load_combatant(_write(tmp_path, data))
|
||||
|
||||
Reference in New Issue
Block a user