A 5e storytelling engine with an LLM DM
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 134 lines 3.6 kB view raw
1"""Tests for the gender morphology layer.""" 2 3import random 4 5import pytest 6 7from storied.names.forge import Morphology 8from storied.names.morphology import _join_with_suffix, apply_morphology 9 10 11@pytest.fixture 12def gendered() -> Morphology: 13 return Morphology( 14 applies=True, 15 female_suffixes=["a", "ina"], 16 male_suffixes=["us", "or"], 17 neutral_suffixes=["en"], 18 ) 19 20 21@pytest.fixture 22def unmarked() -> Morphology: 23 return Morphology( 24 applies=False, 25 female_suffixes=[], 26 male_suffixes=[], 27 neutral_suffixes=[], 28 ) 29 30 31class TestApplyMorphology: 32 def test_unmarked_returns_root_unchanged(self, unmarked: Morphology): 33 rng = random.Random(42) 34 result = apply_morphology("kara", unmarked, "female", rng) 35 assert result == "kara" 36 37 def test_bare_probability_can_skip_suffix(self, gendered: Morphology): 38 # bare_probability=1.0 → always skip 39 rng = random.Random(42) 40 result = apply_morphology( 41 "kara", 42 gendered, 43 "female", 44 rng, 45 bare_probability=1.0, 46 ) 47 assert result == "kara" 48 49 def test_female_suffix_applied(self, gendered: Morphology): 50 rng = random.Random(42) 51 result = apply_morphology( 52 "kar", 53 gendered, 54 "female", 55 rng, 56 bare_probability=0.0, 57 ) 58 assert result.startswith("kar") 59 assert any(result.endswith(s) for s in ["a", "ina"]) 60 61 def test_male_suffix_applied(self, gendered: Morphology): 62 rng = random.Random(42) 63 result = apply_morphology( 64 "kar", 65 gendered, 66 "male", 67 rng, 68 bare_probability=0.0, 69 ) 70 assert any(result.endswith(s) for s in ["us", "or"]) 71 72 def test_neutral_when_gender_is_none(self, gendered: Morphology): 73 rng = random.Random(42) 74 result = apply_morphology( 75 "kar", 76 gendered, 77 None, 78 rng, 79 bare_probability=0.0, 80 ) 81 assert result.endswith("en") 82 83 def test_returns_root_when_no_neutral_suffixes(self): 84 rng = random.Random(42) 85 morph = Morphology( 86 applies=True, 87 female_suffixes=["a"], 88 male_suffixes=["us"], 89 neutral_suffixes=[], 90 ) 91 result = apply_morphology( 92 "kar", 93 morph, 94 None, 95 rng, 96 bare_probability=0.0, 97 ) 98 assert result == "kar" 99 100 def test_empty_suffix_returns_root(self): 101 rng = random.Random(42) 102 morph = Morphology( 103 applies=True, 104 female_suffixes=[""], 105 male_suffixes=[""], 106 neutral_suffixes=[""], 107 ) 108 result = apply_morphology( 109 "kar", 110 morph, 111 "female", 112 rng, 113 bare_probability=0.0, 114 ) 115 assert result == "kar" 116 117 118class TestJoinWithSuffix: 119 def test_simple_concat(self): 120 assert _join_with_suffix("kar", "us") == "karus" 121 122 def test_drops_duplicate_at_boundary(self): 123 # root ends in 'a', suffix starts with 'a' → drop one 124 assert _join_with_suffix("mara", "a") == "mara" 125 assert _join_with_suffix("mara", "an") == "maran" 126 127 def test_empty_suffix(self): 128 assert _join_with_suffix("kar", "") == "kar" 129 130 def test_empty_root(self): 131 assert _join_with_suffix("", "us") == "us" 132 133 def test_case_insensitive_match(self): 134 assert _join_with_suffix("Mara", "An") == "Maran"