Skip to content

Commit a55151f

Browse files
committed
test: expand preg_replace_count_changes test coverage
Add comprehensive test cases for PREG_REPLACE_COUNT_CHANGES flag covering: - Limit parameter behavior with cancel-out patterns - Zero-length matches (lookahead assertions) - Empty matches at every position - Subject arrays (per-element counting) - UTF-8 byte comparison correctness Also improve comment clarity by removing "Edge case" prefix.
1 parent d76e08c commit a55151f

File tree

1 file changed

+61
-1
lines changed

1 file changed

+61
-1
lines changed

ext/pcre/tests/preg_replace_count_changes.phpt

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ $after = preg_replace_callback('/a/', fn($m) => 'x', $before, -1, $count, PREG_R
4242
show("callback_change", $before, $after, $count);
4343
echo "callback_change: " . $after . "\n";
4444

45-
/* Edge case: replacements change locally but cancel out globally */
45+
/* Replacements change locally but cancel out globally */
4646
function cancel_out_callback($arr) {
4747
return match ($arr[0]) {
4848
'a' => 'ab',
@@ -53,6 +53,43 @@ $before3 = "abba";
5353
$after = preg_replace_callback('/^a|bba/', 'cancel_out_callback', $before3, -1, $count, PREG_REPLACE_COUNT_CHANGES);
5454
show("callback_cancel_out", $before3, $after, $count);
5555

56+
/* Cancel out would happen, but limit prevents it */
57+
$after = preg_replace_callback('/^a|bba/', 'cancel_out_callback', $before3, 1, $count, PREG_REPLACE_COUNT_CHANGES);
58+
show("callback_cancel_out_limit_1", $before3, $after, $count);
59+
echo "callback_cancel_out_limit_1: " . $after . "\n";
60+
61+
/* Zero length match inside the string */
62+
$before4 = "ab";
63+
$after = preg_replace('/(?=b)/', '', $before4, -1, $count, PREG_REPLACE_COUNT_CHANGES);
64+
show("empty_lookahead_identity", $before4, $after, $count);
65+
66+
$after = preg_replace('/(?=b)/', 'X', $before4, -1, $count, PREG_REPLACE_COUNT_CHANGES);
67+
show("empty_lookahead_change", $before4, $after, $count);
68+
echo "empty_lookahead_change: " . $after . "\n";
69+
70+
/* Zero length match at every position */
71+
$after = preg_replace('/(?=)/', '', $before4, -1, $count, PREG_REPLACE_COUNT_CHANGES);
72+
show("empty_everywhere_identity", $before4, $after, $count);
73+
74+
$after = preg_replace('/(?=)/', '-', $before4, -1, $count, PREG_REPLACE_COUNT_CHANGES);
75+
show("empty_everywhere_change", $before4, $after, $count);
76+
echo "empty_everywhere_change: " . $after . "\n";
77+
78+
/* Subject array should count per element */
79+
$subjects = ["abba", "abca"];
80+
$after = preg_replace_callback('/^a|bba/', 'cancel_out_callback', $subjects, -1, $count, PREG_REPLACE_COUNT_CHANGES);
81+
echo "array_subject_after: " . var_export($after, true) . "\n";
82+
echo "array_subject_count: " . $count . "\n";
83+
84+
/* UTF 8, ensure byte comparison is correct */
85+
$before5 = "éaé";
86+
$after = preg_replace('/é/u', 'é', $before5, -1, $count, PREG_REPLACE_COUNT_CHANGES);
87+
show("utf8_identity", $before5, $after, $count);
88+
89+
$after = preg_replace('/é/u', 'e', $before5, -1, $count, PREG_REPLACE_COUNT_CHANGES);
90+
show("utf8_change", $before5, $after, $count);
91+
echo "utf8_change: " . $after . "\n";
92+
5693
/* Empty string match behavior */
5794
$before2 = "abc";
5895
$after = preg_replace('/^/', '', $before2, -1, $count, PREG_REPLACE_COUNT_CHANGES);
@@ -80,6 +117,29 @@ callback_change: 2 REPLACEMENTS
80117
callback_change: xbcx
81118
callback_cancel_out: NO REPLACEMENTS
82119
callback_cancel_out: 0 REPLACEMENTS
120+
callback_cancel_out_limit_1: CHANGED
121+
callback_cancel_out_limit_1: 1 REPLACEMENTS
122+
callback_cancel_out_limit_1: abbba
123+
empty_lookahead_identity: NO REPLACEMENTS
124+
empty_lookahead_identity: 0 REPLACEMENTS
125+
empty_lookahead_change: CHANGED
126+
empty_lookahead_change: 1 REPLACEMENTS
127+
empty_lookahead_change: aXb
128+
empty_everywhere_identity: NO REPLACEMENTS
129+
empty_everywhere_identity: 0 REPLACEMENTS
130+
empty_everywhere_change: CHANGED
131+
empty_everywhere_change: 3 REPLACEMENTS
132+
empty_everywhere_change: -a-b-
133+
array_subject_after: array (
134+
0 => 'abba',
135+
1 => 'abbca',
136+
)
137+
array_subject_count: 1
138+
utf8_identity: NO REPLACEMENTS
139+
utf8_identity: 0 REPLACEMENTS
140+
utf8_change: CHANGED
141+
utf8_change: 2 REPLACEMENTS
142+
utf8_change: eae
83143
empty_match_identity: NO REPLACEMENTS
84144
empty_match_identity: 0 REPLACEMENTS
85145
empty_match_change: CHANGED

0 commit comments

Comments
 (0)