Skip to content

Commit 2a97977

Browse files
committed
Fix getGroupedOpcodes(0) should not have leading/trailing OP_EQ blocks
When "context" is set to 0, there should not be any OP_EQ blocks. Signed-off-by: Jack Cherng <jfcherng@gmail.com>
1 parent 6d35ebc commit 2a97977

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

src/SequenceMatcher.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ public function getGroupedOpcodes(int $context = 3): array
447447
}
448448

449449
if ($opcodes[0][0] === self::OP_EQ) {
450+
// fix the leading sequence which is out of context.
450451
$opcodes[0] = [
451452
$opcodes[0][0],
452453
\max($opcodes[0][1], $opcodes[0][2] - $context),
@@ -459,6 +460,7 @@ public function getGroupedOpcodes(int $context = 3): array
459460
$lastItem = \count($opcodes) - 1;
460461
if ($opcodes[$lastItem][0] === self::OP_EQ) {
461462
[$tag, $i1, $i2, $j1, $j2] = $opcodes[$lastItem];
463+
// fix the trailing sequence which is out of context.
462464
$opcodes[$lastItem] = [
463465
$tag,
464466
$i1,
@@ -498,6 +500,28 @@ public function getGroupedOpcodes(int $context = 3): array
498500
$groups[] = $group;
499501
}
500502

503+
// there will be at least leading/trailing OP_EQ blocks
504+
// if we want really zero-context, we keep only non-equal blocks
505+
if ($context <= 0) {
506+
$groupsNew = [];
507+
508+
foreach ($groups as $group) {
509+
$groupNew = [];
510+
511+
foreach ($group as $block) {
512+
if ($block[0] !== self::OP_EQ) {
513+
$groupNew[] = $block;
514+
}
515+
}
516+
517+
if (!empty($groupNew)) {
518+
$groupsNew[] = $groupNew;
519+
}
520+
}
521+
522+
return $groupsNew;
523+
}
524+
501525
return $groups;
502526
}
503527

tests/SequenceMatcherTest.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,23 @@ public function getGroupedOpcodesDataProvider(): array
3939
return [
4040
[
4141
<<<'EOT'
42+
A
43+
B
44+
C
45+
D
46+
EOT
47+
,
48+
<<<'EOT'
49+
A
50+
B
51+
C
52+
D
53+
EOT
54+
,
55+
[],
56+
],
57+
[
58+
<<<'EOT'
4259
apples
4360
oranges
4461
kiwis
@@ -84,6 +101,75 @@ public function testGetGroupedOpcodes(string $old, string $new, array $expected)
84101
static::assertSame($expected, $this->sm->getGroupedOpcodes());
85102
}
86103

104+
/**
105+
* Data provider for SequenceMatcher::getGroupedOpcodes.
106+
*
107+
* @return array the data provider
108+
*/
109+
public function getGroupedOpcodesWithZeroContextDataProvider(): array
110+
{
111+
return [
112+
[
113+
<<<'EOT'
114+
A
115+
B
116+
C
117+
D
118+
EOT
119+
,
120+
<<<'EOT'
121+
A
122+
B
123+
C
124+
D
125+
EOT
126+
,
127+
[],
128+
],
129+
[
130+
<<<'EOT'
131+
A
132+
B
133+
C
134+
D
135+
EOT
136+
,
137+
<<<'EOT'
138+
A
139+
B
140+
X
141+
D
142+
EOT
143+
,
144+
[
145+
[
146+
[SequenceMatcher::OP_REP, 2, 3, 2, 3],
147+
],
148+
],
149+
],
150+
];
151+
}
152+
153+
/**
154+
* Test the SequenceMatcher::getGroupedOpcodes.
155+
*
156+
* @covers \Jfcherng\Diff\SequenceMatcher::getGroupedOpcodes
157+
* @dataProvider getGroupedOpcodesWithZeroContextDataProvider
158+
*
159+
* @param string $old the old
160+
* @param string $new the new
161+
* @param array $expected the expected
162+
*/
163+
public function testGetGroupedOpcodesWithZeroContext(string $old, string $new, array $expected): void
164+
{
165+
$this->sm->setSequences(
166+
\explode("\n", $old),
167+
\explode("\n", $new)
168+
);
169+
170+
static::assertSame($expected, $this->sm->getGroupedOpcodes(0));
171+
}
172+
87173
/**
88174
* Data provider for SequenceMatcher::getOpcodes.
89175
*

0 commit comments

Comments
 (0)