@@ -107,32 +107,76 @@ def test_same(self):
107107 def test_insert (self ):
108108 assert levenshtein ("abc" , "ab" ) == 1
109109
110+ def test_delete (self ):
111+ # s1이 더 짧으면 내부적으로 뒤집어서 처리됨
112+ assert levenshtein ("ab" , "abc" ) == 1
113+
114+ def test_substitute (self ):
115+ assert levenshtein ("abc" , "axc" ) == 1
116+
110117 def test_empty (self ):
111118 assert levenshtein ("abc" , "" ) == 3
119+ assert levenshtein ("" , "abc" ) == 3
120+
121+ def test_completely_different (self ):
122+ assert levenshtein ("abc" , "xyz" ) == 3
112123
113124 def test_custom_cost (self ):
114125 assert levenshtein ("a" , "b" , cost = {("a" , "b" ): 0.5 , ("b" , "a" ): 0.5 }) == 0.5
115126
127+ def test_symmetry (self ):
128+ assert levenshtein ("kitten" , "sitting" ) == levenshtein ("sitting" , "kitten" )
129+
116130
117131class TestJamoLevenshtein :
118132 def test_same (self ):
119133 assert jamo_levenshtein ("한글" , "한글" ) == 0
120134
121135 def test_similar (self ):
136+ # 한글 vs 한금: 받침만 다름 → 자모 거리 < 1
122137 dist = jamo_levenshtein ("한글" , "한금" )
123138 assert 0 < dist < 1
124139
125140 def test_empty (self ):
126141 assert jamo_levenshtein ("한" , "" ) == 1
142+ assert jamo_levenshtein ("" , "한" ) == 1
143+
144+ def test_non_korean_chars (self ):
145+ # 비한글 문자는 1 단위로 처리됨
146+ assert jamo_levenshtein ("abc" , "abc" ) == 0
147+ assert jamo_levenshtein ("abc" , "abx" ) == 1
148+
149+ def test_less_than_levenshtein (self ):
150+ # 자모 거리 < 일반 거리 (한글이 비슷한 경우)
151+ normal = levenshtein ("한글" , "한금" )
152+ jamo = jamo_levenshtein ("한글" , "한금" )
153+ assert jamo < normal
127154
128155
129156class TestCosineDistance :
130157 def test_same (self ):
131158 assert cosine_distance ("aaa" , "aaa" ) == pytest .approx (0.0 )
132159
133- def test_empty (self ):
160+ def test_empty_s1 (self ):
134161 assert cosine_distance ("" , "abc" ) == 2
135162
163+ def test_empty_s2 (self ):
164+ assert cosine_distance ("abc" , "" ) == 2
165+
166+ def test_orthogonal (self ):
167+ # "aaa" vs "bbb": 공통 문자 없음 → cosine=0, distance=1
168+ assert cosine_distance ("aaa" , "bbb" ) == pytest .approx (1.0 )
169+
170+ def test_partial_overlap (self ):
171+ d = cosine_distance ("abc" , "abx" )
172+ assert 0 < d < 1
173+
174+ def test_range (self ):
175+ # 거리는 항상 [0, 2] 범위
176+ for s1 , s2 in [("abc" , "abc" ), ("abc" , "def" ), ("abc" , "abx" )]:
177+ d = cosine_distance (s1 , s2 )
178+ assert 0.0 <= d <= 2.0
179+
136180
137181class TestJaccardDistance :
138182 def test_same (self ):
@@ -141,9 +185,23 @@ def test_same(self):
141185 def test_disjoint (self ):
142186 assert jaccard_distance ("abc" , "def" ) == pytest .approx (1.0 )
143187
144- def test_empty (self ):
188+ def test_empty_s1 (self ):
145189 assert jaccard_distance ("" , "abc" ) == 1
146190
191+ def test_empty_s2 (self ):
192+ assert jaccard_distance ("abc" , "" ) == 1
193+
194+ def test_partial_overlap (self ):
195+ # "ab" vs "bc": 교집합 {"b"}, 합집합 {"a","b","c"} → 1 - 1/3 = 2/3
196+ d = jaccard_distance ("ab" , "bc" )
197+ assert d == pytest .approx (2 / 3 )
198+
199+ def test_custom_unitfy (self ):
200+ # 단어 단위 분리
201+
202+ d = jaccard_distance ("hello world" , "hello earth" , unitfy = lambda s : set (s .split ()))
203+ assert 0 < d < 1
204+
147205
148206class TestTextToJamo :
149207 def test_with_jongsung (self ):
0 commit comments