@@ -14,6 +14,24 @@ def entities():
1414 return ["IP_ADDRESS" ]
1515
1616
17+ def assert_results_match (
18+ results ,
19+ expected_positions ,
20+ expected_score_ranges ,
21+ entities ,
22+ max_score ,
23+ ):
24+ ordered_results = sorted (results , key = lambda result : (result .start , result .end ))
25+ for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
26+ ordered_results , expected_positions , expected_score_ranges
27+ ):
28+ if fn_score == "max" :
29+ fn_score = max_score
30+ assert_result_within_score_range (
31+ res , entities [0 ], st_pos , fn_pos , st_score , fn_score
32+ )
33+
34+
1735@pytest .mark .parametrize (
1836 "text, expected_len, expected_positions, expected_score_ranges" ,
1937 [
@@ -29,6 +47,11 @@ def entities():
2947 ("2345:0425:2CA1::0567:5673:23b5" , 1 , (), (),),
3048 ("2400:c401::5054:ff:fe1b:b031" , 1 , (), (),),
3149 ("Use local ipv6 ::" , 1 , ((15 , 17 ),), ((0.05 , 0.15 ),),),
50+ # IPv6 loopback (::1) should match at high confidence
51+ ("my ip: ::1" , 1 , ((7 , 10 ),), ((0.6 , 0.81 ),),),
52+ ("connecting from ::1" , 1 , ((16 , 19 ),), ((0.6 , 0.81 ),),),
53+ # bare :: and ::1 in same string should each match once
54+ ("src=:: dst=::1" , 2 , ((4 , 6 ), (11 , 14 )), ((0.05 , 0.15 ), (0.6 , 0.81 )),),
3255 # fmt: on
3356 ],
3457)
@@ -43,14 +66,9 @@ def test_when_all_ips_then_succeed(
4366):
4467 results = recognizer .analyze (text , entities )
4568 assert len (results ) == expected_len
46- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
47- results , expected_positions , expected_score_ranges
48- ):
49- if fn_score == "max" :
50- fn_score = max_score
51- assert_result_within_score_range (
52- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
53- )
69+ assert_results_match (
70+ results , expected_positions , expected_score_ranges , entities , max_score
71+ )
5472
5573
5674@pytest .mark .parametrize (
@@ -77,14 +95,9 @@ def test_when_ipv6_compression_then_succeed(
7795):
7896 results = recognizer .analyze (text , entities )
7997 assert len (results ) == expected_len
80- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
81- results , expected_positions , expected_score_ranges
82- ):
83- if fn_score == "max" :
84- fn_score = max_score
85- assert_result_within_score_range (
86- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
87- )
98+ assert_results_match (
99+ results , expected_positions , expected_score_ranges , entities , max_score
100+ )
88101
89102
90103@pytest .mark .parametrize (
@@ -112,14 +125,9 @@ def test_when_ipv6_in_context_then_succeed(
112125):
113126 results = recognizer .analyze (text , entities )
114127 assert len (results ) == expected_len
115- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
116- results , expected_positions , expected_score_ranges
117- ):
118- if fn_score == "max" :
119- fn_score = max_score
120- assert_result_within_score_range (
121- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
122- )
128+ assert_results_match (
129+ results , expected_positions , expected_score_ranges , entities , max_score
130+ )
123131
124132
125133@pytest .mark .parametrize (
@@ -162,14 +170,9 @@ def test_when_ipv4_mapped_then_full_span_redacted(
162170):
163171 results = recognizer .analyze (text , entities )
164172 assert len (results ) == expected_len
165- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
166- results , expected_positions , expected_score_ranges
167- ):
168- if fn_score == "max" :
169- fn_score = max_score
170- assert_result_within_score_range (
171- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
172- )
173+ assert_results_match (
174+ results , expected_positions , expected_score_ranges , entities , max_score
175+ )
173176
174177
175178@pytest .mark .parametrize (
@@ -205,14 +208,9 @@ def test_when_ipv4_embedded_then_full_span_redacted(
205208):
206209 results = recognizer .analyze (text , entities )
207210 assert len (results ) == expected_len
208- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
209- results , expected_positions , expected_score_ranges
210- ):
211- if fn_score == "max" :
212- fn_score = max_score
213- assert_result_within_score_range (
214- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
215- )
211+ assert_results_match (
212+ results , expected_positions , expected_score_ranges , entities , max_score
213+ )
216214
217215
218216@pytest .mark .parametrize (
@@ -237,14 +235,9 @@ def test_when_multiple_ips_then_all_found(
237235):
238236 results = recognizer .analyze (text , entities )
239237 assert len (results ) == expected_len
240- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
241- results , expected_positions , expected_score_ranges
242- ):
243- if fn_score == "max" :
244- fn_score = max_score
245- assert_result_within_score_range (
246- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
247- )
238+ assert_results_match (
239+ results , expected_positions , expected_score_ranges , entities , max_score
240+ )
248241
249242
250243@pytest .mark .parametrize (
@@ -278,14 +271,9 @@ def test_when_non_ip_pattern_then_no_match(
278271):
279272 results = recognizer .analyze (text , entities )
280273 assert len (results ) == expected_len
281- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
282- results , expected_positions , expected_score_ranges
283- ):
284- if fn_score == "max" :
285- fn_score = max_score
286- assert_result_within_score_range (
287- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
288- )
274+ assert_results_match (
275+ results , expected_positions , expected_score_ranges , entities , max_score
276+ )
289277
290278
291279@pytest .mark .parametrize (
@@ -321,14 +309,9 @@ def test_when_ip_at_boundary_then_correct_span(
321309):
322310 results = recognizer .analyze (text , entities )
323311 assert len (results ) == expected_len
324- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
325- results , expected_positions , expected_score_ranges
326- ):
327- if fn_score == "max" :
328- fn_score = max_score
329- assert_result_within_score_range (
330- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
331- )
312+ assert_results_match (
313+ results , expected_positions , expected_score_ranges , entities , max_score
314+ )
332315
333316
334317@pytest .mark .parametrize (
@@ -364,14 +347,9 @@ def test_when_invalid_ip_then_no_match(
364347):
365348 results = recognizer .analyze (text , entities )
366349 assert len (results ) == expected_len
367- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
368- results , expected_positions , expected_score_ranges
369- ):
370- if fn_score == "max" :
371- fn_score = max_score
372- assert_result_within_score_range (
373- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
374- )
350+ assert_results_match (
351+ results , expected_positions , expected_score_ranges , entities , max_score
352+ )
375353
376354
377355@pytest .mark .parametrize (
@@ -403,14 +381,9 @@ def test_when_special_ip_variants_then_succeed(
403381):
404382 results = recognizer .analyze (text , entities )
405383 assert len (results ) == expected_len
406- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
407- results , expected_positions , expected_score_ranges
408- ):
409- if fn_score == "max" :
410- fn_score = max_score
411- assert_result_within_score_range (
412- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
413- )
384+ assert_results_match (
385+ results , expected_positions , expected_score_ranges , entities , max_score
386+ )
414387
415388
416389@pytest .mark .parametrize (
@@ -457,11 +430,6 @@ def test_when_cidr_notation_then_largest_span_redacted(
457430):
458431 results = recognizer .analyze (text , entities )
459432 assert len (results ) == expected_len
460- for res , (st_pos , fn_pos ), (st_score , fn_score ) in zip (
461- results , expected_positions , expected_score_ranges
462- ):
463- if fn_score == "max" :
464- fn_score = max_score
465- assert_result_within_score_range (
466- res , entities [0 ], st_pos , fn_pos , st_score , fn_score
467- )
433+ assert_results_match (
434+ results , expected_positions , expected_score_ranges , entities , max_score
435+ )
0 commit comments