Skip to content

Commit 2802d8f

Browse files
Merge pull request sebastianbergmann#14 from nafigator/chunk-fix
Multiple chunk parsing fix
2 parents 92d423d + dab373e commit 2802d8f

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

src/Parser.php

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ public function parse($string)
8080
$diff = new Diff($fromMatch['file'], $toMatch['file']);
8181
++$i;
8282
} else {
83+
if (preg_match('/^(?:diff --git |index [\da-f\.]+|[+-]{3} [ab])/', $lines[$i])) {
84+
continue;
85+
}
8386
$collected[] = $lines[$i];
8487
}
8588
}
@@ -100,45 +103,34 @@ private function parseFileDiff(Diff $diff, array $lines)
100103
{
101104
$chunks = array();
102105

103-
while (count($lines)) {
104-
while (!preg_match('(^@@\\s+-(?P<start>\\d+)(?:,\\s*(?P<startrange>\\d+))?\\s+\\+(?P<end>\\d+)(?:,\\s*(?P<endrange>\\d+))?\\s+@@)', $last = array_shift($lines), $match)) {
105-
if ($last === null) {
106-
break 2;
107-
}
106+
foreach ($lines as $line) {
107+
if (preg_match('/^@@\s+-(?P<start>\d+)(?:,\s*(?P<startrange>\d+))?\s+\+(?P<end>\d+)(?:,\s*(?P<endrange>\d+))?\s+@@/', $line, $match)) {
108+
$chunk = new Chunk(
109+
$match['start'],
110+
isset($match['startrange']) ? max(1, $match['startrange']) : 1,
111+
$match['end'],
112+
isset($match['endrange']) ? max(1, $match['endrange']) : 1
113+
);
114+
115+
$chunks[] = $chunk;
116+
$diffLines = array();
117+
continue;
108118
}
109119

110-
$chunk = new Chunk(
111-
$match['start'],
112-
isset($match['startrange']) ? max(1, $match['startrange']) : 1,
113-
$match['end'],
114-
isset($match['endrange']) ? max(1, $match['endrange']) : 1
115-
);
116-
117-
$diffLines = array();
118-
$last = null;
119-
120-
while (count($lines) &&
121-
(preg_match('(^(?P<type>[+ -])?(?P<line>.*))', $last = array_shift($lines), $match) ||
122-
(strpos($last, '\\ No newline at end of file') === 0))) {
123-
if (count($match)) {
124-
$type = Line::UNCHANGED;
120+
if (preg_match('/^(?P<type>[+ -])?(?P<line>.*)/', $line, $match)) {
121+
$type = Line::UNCHANGED;
125122

126-
if ($match['type'] == '+') {
127-
$type = Line::ADDED;
128-
} elseif ($match['type'] == '-') {
129-
$type = Line::REMOVED;
130-
}
131-
132-
$diffLines[] = new Line($type, $match['line']);
123+
if ($match['type'] == '+') {
124+
$type = Line::ADDED;
125+
} elseif ($match['type'] == '-') {
126+
$type = Line::REMOVED;
133127
}
134-
}
135128

136-
$chunk->setLines($diffLines);
129+
$diffLines[] = new Line($type, $match['line']);
137130

138-
$chunks[] = $chunk;
139-
140-
if ($last !== null) {
141-
array_unshift($lines, $last);
131+
if (isset($chunk)) {
132+
$chunk->setLines($diffLines);
133+
}
142134
}
143135
}
144136

tests/DifferTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,20 @@ public function testCustomHeaderCanBeUsed()
128128
);
129129
}
130130

131+
/**
132+
* @param string $diff
133+
* @param array $expected
134+
* @dataProvider diffProvider
135+
* @covers SebastianBergmann\Diff\Parser::parse
136+
*/
137+
public function testParser($diff, $expected)
138+
{
139+
$parser = new Parser;
140+
$result = $parser->parse($diff);
141+
142+
$this->assertEquals($expected, $result);
143+
}
144+
131145
public function arrayProvider()
132146
{
133147
return array(
@@ -243,4 +257,17 @@ public function textProvider()
243257
),
244258
);
245259
}
260+
261+
public function diffProvider()
262+
{
263+
$serialized_arr = <<<EOL
264+
a:1:{i:0;O:27:"SebastianBergmann\Diff\Diff":3:{s:33:"SebastianBergmann\Diff\Difffrom";s:7:"old.txt";s:31:"SebastianBergmann\Diff\Diffto";s:7:"new.txt";s:35:"SebastianBergmann\Diff\Diffchunks";a:3:{i:0;O:28:"SebastianBergmann\Diff\Chunk":5:{s:35:"SebastianBergmann\Diff\Chunkstart";i:1;s:40:"SebastianBergmann\Diff\ChunkstartRange";i:3;s:33:"SebastianBergmann\Diff\Chunkend";i:1;s:38:"SebastianBergmann\Diff\ChunkendRange";i:4;s:35:"SebastianBergmann\Diff\Chunklines";a:4:{i:0;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:1;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222111";}i:1;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:2;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:3;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}}}i:1;O:28:"SebastianBergmann\Diff\Chunk":5:{s:35:"SebastianBergmann\Diff\Chunkstart";i:5;s:40:"SebastianBergmann\Diff\ChunkstartRange";i:10;s:33:"SebastianBergmann\Diff\Chunkend";i:6;s:38:"SebastianBergmann\Diff\ChunkendRange";i:8;s:35:"SebastianBergmann\Diff\Chunklines";a:11:{i:0;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:1;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:2;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:3;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:8:"+1121211";}i:4;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"1111111";}i:5;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:8:"-1111111";}i:6;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:8:"-1111111";}i:7;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:8:"-2222222";}i:8;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:9;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:10;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}}}i:2;O:28:"SebastianBergmann\Diff\Chunk":5:{s:35:"SebastianBergmann\Diff\Chunkstart";i:17;s:40:"SebastianBergmann\Diff\ChunkstartRange";i:5;s:33:"SebastianBergmann\Diff\Chunkend";i:16;s:38:"SebastianBergmann\Diff\ChunkendRange";i:6;s:35:"SebastianBergmann\Diff\Chunklines";a:7:{i:0;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:1;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:2;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:3;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:8:"+2122212";}i:4;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:5;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:7:"2222222";}i:6;O:27:"SebastianBergmann\Diff\Line":2:{s:33:"SebastianBergmann\Diff\Linetype";i:3;s:36:"SebastianBergmann\Diff\Linecontent";s:0:"";}}}}}}
265+
EOL;
266+
return array(
267+
array(
268+
"--- old.txt 2014-11-04 08:51:02.661868729 +0300\n+++ new.txt 2014-11-04 08:51:02.665868730 +0300\n@@ -1,3 +1,4 @@\n+2222111\n 1111111\n 1111111\n 1111111\n@@ -5,10 +6,8 @@\n 1111111\n 1111111\n 1111111\n +1121211\n 1111111\n -1111111\n -1111111\n -2222222\n 2222222\n 2222222\n 2222222\n@@ -17,5 +16,6 @@\n 2222222\n 2222222\n 2222222\n +2122212\n 2222222\n 2222222\n",
269+
unserialize($serialized_arr)
270+
)
271+
);
272+
}
246273
}

0 commit comments

Comments
 (0)