Skip to content

Commit 0461c15

Browse files
committed
Add run-tests.php --context [n] option.
Mentioned in #5965 (comment) This PR proposes 3 lines of context so the impact can be seen in tests. Other `diff` programs show around 3 lines of context. (This helps indicate exactly which position a test should be updated to add a new expected line at) Use the mapping for choosing order to display diffs Properly include context in cases where the expected output had more lines than the actual output, e.g. ``` --FILE-- A A1 A C NEARBY --EXPECTF-- A B A1 B A B A B NEARBY ``` Closes GH-5968
1 parent 517c993 commit 0461c15

File tree

1 file changed

+68
-7
lines changed

1 file changed

+68
-7
lines changed

run-tests.php

+68-7
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ function show_usage(): void
102102
seconds. The default value is 60 seconds, or 300 seconds when
103103
testing for memory leaks.
104104
105+
--context [n]
106+
Sets the number of lines of surrounding context to print for diffs.
107+
The default value is 3.
108+
105109
--show-[all|php|skip|clean|exp|diff|out|mem]
106110
Show 'all' files, 'php' test file, 'skip' or 'clean' file. You
107111
can also use this to show the output 'out', the expected result
@@ -146,6 +150,7 @@ function main(): void
146150
$user_tests, $valgrind, $sum_results, $shuffle, $file_cache;
147151
// Parallel testing
148152
global $workers, $workerID;
153+
global $context_line_count;
149154

150155
define('IS_WINDOWS', substr(PHP_OS, 0, 3) == "WIN");
151156

@@ -400,6 +405,7 @@ function main(): void
400405
$file_cache = null;
401406
$shuffle = false;
402407
$workers = null;
408+
$context_line_count = 3;
403409

404410
$cfgtypes = ['show', 'keep'];
405411
$cfgfiles = ['skip', 'php', 'clean', 'out', 'diff', 'exp', 'mem'];
@@ -568,6 +574,13 @@ function main(): void
568574
case '--set-timeout':
569575
$environment['TEST_TIMEOUT'] = $argv[++$i];
570576
break;
577+
case '--context':
578+
$context_line_count = $argv[++$i] ?? '';
579+
if (!preg_match('/^\d+$/', $context_line_count)) {
580+
error("'$context_line_count' is not a valid number of lines of context, try e.g. --context 3 for 3 lines");
581+
}
582+
$context_line_count = intval($context_line_count, 10);
583+
break;
571584
case '--show-all':
572585
foreach ($cfgfiles as $file) {
573586
$cfg['show'][$file] = true;
@@ -2890,15 +2903,22 @@ function count_array_diff(
28902903

28912904
function generate_array_diff(array $ar1, array $ar2, bool $is_reg, array $w): array
28922905
{
2906+
global $context_line_count;
28932907
$idx1 = 0;
28942908
$cnt1 = @count($ar1);
28952909
$idx2 = 0;
28962910
$cnt2 = @count($ar2);
28972911
$diff = [];
28982912
$old1 = [];
28992913
$old2 = [];
2914+
$number_len = max(3, strlen((string)max($cnt1 + 1, $cnt2 + 1)));
2915+
$line_number_spec = '%0' . $number_len . 'd';
2916+
2917+
/** Mapping from $idx2 to $idx1, including indexes of idx2 that are identical to idx1 as well as entries that don't have matches */
2918+
$mapping = [];
29002919

29012920
while ($idx1 < $cnt1 && $idx2 < $cnt2) {
2921+
$mapping[$idx2] = $idx1;
29022922
if (comp_line($ar1[$idx1], $ar2[$idx2], $is_reg)) {
29032923
$idx1++;
29042924
$idx2++;
@@ -2908,49 +2928,90 @@ function generate_array_diff(array $ar1, array $ar2, bool $is_reg, array $w): ar
29082928
$c2 = @count_array_diff($ar1, $ar2, $is_reg, $w, $idx1, $idx2 + 1, $cnt1, $cnt2, 10);
29092929

29102930
if ($c1 > $c2) {
2911-
$old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
2931+
$old1[$idx1] = sprintf("{$line_number_spec}- ", $idx1 + 1) . $w[$idx1++];
29122932
} elseif ($c2 > 0) {
2913-
$old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
2933+
$old2[$idx2] = sprintf("{$line_number_spec}+ ", $idx2 + 1) . $ar2[$idx2++];
29142934
} else {
2915-
$old1[$idx1] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
2916-
$old2[$idx2] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
2935+
$old1[$idx1] = sprintf("{$line_number_spec}- ", $idx1 + 1) . $w[$idx1++];
2936+
$old2[$idx2] = sprintf("{$line_number_spec}+ ", $idx2 + 1) . $ar2[$idx2++];
29172937
}
2938+
$last_printed_context_line = $idx1;
29182939
}
29192940
}
2941+
$mapping[$idx2] = $idx1;
29202942

29212943
reset($old1);
29222944
$k1 = key($old1);
29232945
$l1 = -2;
29242946
reset($old2);
29252947
$k2 = key($old2);
29262948
$l2 = -2;
2949+
$old_k1 = -1;
2950+
$add_context_lines = function (int $new_k1) use (&$old_k1, &$diff, $w, $context_line_count, $number_len) {
2951+
if ($old_k1 >= $new_k1 || !$context_line_count) {
2952+
return;
2953+
}
2954+
$end = $new_k1 - 1;
2955+
$range_end = min($end, $old_k1 + $context_line_count);
2956+
if ($old_k1 >= 0) {
2957+
while ($old_k1 < $range_end) {
2958+
$diff[] = str_repeat(' ', $number_len + 2) . $w[$old_k1++];
2959+
}
2960+
}
2961+
if ($end - $context_line_count > $old_k1) {
2962+
$old_k1 = $end - $context_line_count;
2963+
if ($old_k1 > 0) {
2964+
// Add a '--' to mark sections where the common areas were truncated
2965+
$diff[] = '--';
2966+
}
2967+
}
2968+
$old_k1 = max($old_k1, 0);
2969+
while ($old_k1 < $end) {
2970+
$diff[] = str_repeat(' ', $number_len + 2) . $w[$old_k1++];
2971+
}
2972+
$old_k1 = $new_k1;
2973+
};
29272974

29282975
while ($k1 !== null || $k2 !== null) {
29292976
if ($k1 == $l1 + 1 || $k2 === null) {
2977+
$add_context_lines($k1);
29302978
$l1 = $k1;
29312979
$diff[] = current($old1);
2980+
$old_k1 = $k1;
29322981
$k1 = next($old1) ? key($old1) : null;
29332982
} elseif ($k2 == $l2 + 1 || $k1 === null) {
2983+
$add_context_lines($mapping[$k2]);
29342984
$l2 = $k2;
29352985
$diff[] = current($old2);
29362986
$k2 = next($old2) ? key($old2) : null;
2937-
} elseif ($k1 < $k2) {
2987+
} elseif ($k1 < $mapping[$k2]) {
2988+
$add_context_lines($k1);
29382989
$l1 = $k1;
29392990
$diff[] = current($old1);
29402991
$k1 = next($old1) ? key($old1) : null;
29412992
} else {
2993+
$add_context_lines($mapping[$k2]);
29422994
$l2 = $k2;
29432995
$diff[] = current($old2);
29442996
$k2 = next($old2) ? key($old2) : null;
29452997
}
29462998
}
29472999

29483000
while ($idx1 < $cnt1) {
2949-
$diff[] = sprintf("%03d- ", $idx1 + 1) . $w[$idx1++];
3001+
$add_context_lines($idx1 + 1);
3002+
$diff[] = sprintf("{$line_number_spec}- ", $idx1 + 1) . $w[$idx1++];
29503003
}
29513004

29523005
while ($idx2 < $cnt2) {
2953-
$diff[] = sprintf("%03d+ ", $idx2 + 1) . $ar2[$idx2++];
3006+
if (isset($mapping[$idx2])) {
3007+
$add_context_lines($mapping[$idx2] + 1);
3008+
}
3009+
$diff[] = sprintf("{$line_number_spec}+ ", $idx2 + 1) . $ar2[$idx2++];
3010+
}
3011+
$add_context_lines(min($old_k1 + $context_line_count + 1, $cnt1 + 1));
3012+
if ($context_line_count && $old_k1 < $cnt1 + 1) {
3013+
// Add a '--' to mark sections where the common areas were truncated
3014+
$diff[] = '--';
29543015
}
29553016

29563017
return $diff;

0 commit comments

Comments
 (0)