true,
'verboseOutput' => true
]);
$tmpFiles = [];
$view = function(string $diff) use (&$tmpFiles): string {
$f = tempnam(sys_get_temp_dir(), 'lbdiff_');
file_put_contents($f, $diff);
$tmpFiles[] = $f;
return (new DiffViewer($f))->displaySideBySide();
};
//
の行を [クラス, 内容] の配列にする
$cells = function(string $html): array {
preg_match_all('# | (.*?) | #s', $html, $m, PREG_SET_ORDER);
return array_map(fn($x) => [$x[1], $x[2]], $m);
};
$test->describe('差分ビューア', function($test) use ($view, $cells): void {
$test->it('無いファイルは例外のはず', function($test): void {
$test->assertThrows(fn() => new DiffViewer('/no/such/file.diff'), \Exception::class);
});
$test->it('git形式の差分を左右に並べるはず', function($test) use ($view, $cells): void {
$html = $view("diff --git a/main.c b/main.c\nindex 1..2 100644\n--- a/main.c\n+++ b/main.c\n"
."@@ -1,3 +1,3 @@\n #include \n-int a;\n+int b;\n return 0;\n");
$test->assertStringContains('ファイル: a/main.c | b/main.c
', $html);
$test->assertStringContains('@@ -1,3 +1,3 @@ | ', $html);
$c = $cells($html);
$test->assertEquals(['line-number', '1'], $c[0]);
$test->assertEquals(['context', '#include <stdio.h>'], $c[1]);
$test->assertEquals(['removed', 'int a;'], $c[5]);
$test->assertEquals(['added', 'int b;'], $c[7]);
$test->assertEquals(['line-number', '2'], $c[6]);
});
$test->it('削除と追加の数が違う場合は空のセルで埋めるはず', function($test) use ($view): void {
$html = $view("--- a.txt\n+++ b.txt\n@@ -1,2 +1,1 @@\n-x\n-y\n+z\n");
$test->assertStringContains(' | ', $html);
$test->assertEquals(1, substr_count($html, 'class="empty"'));
});
$test->it('「---」で始まる削除行をファイルヘッダーと間違えないはず', function($test) use ($view): void {
$html = $view("--- a/x.md\n+++ b/x.md\n@@ -1,2 +1,1 @@\n---- 区切り\n keep\n");
$test->assertEquals(1, substr_count($html, ''));
$test->assertStringContains('| --- 区切り | ', $html);
});
$test->it('行数が省略されたハンクと新しいファイルを扱えるはず', function($test) use ($view, $cells): void {
$html = $view("diff --git a/new.txt b/new.txt\nnew file mode 100644\n--- /dev/null\n+++ b/new.txt\n@@ -0,0 +1 @@\n+hello\n\\ No newline at end of file\n");
$test->assertStringContains('ファイル: /dev/null | b/new.txt
', $html);
$c = $cells($html);
$test->assertEquals(['added', 'hello'], $c[3]);
$test->assertEquals(['line-number', '1'], $c[2]);
});
$test->it('複数のファイルと内容の無い変更を扱えるはず', function($test) use ($view): void {
$html = $view("diff --git a/a.png b/a.png\nBinary files a/a.png and b/a.png differ\n"
."diff --git a/old.sh b/new.sh\nsimilarity index 100%\nrename from old.sh\nrename to new.sh\n"
."diff --git a/c.txt b/c.txt\n--- a/c.txt\n+++ b/c.txt\n@@ -1 +1 @@\n-1\n+2\n");
$test->assertEquals(3, substr_count($html, ''));
$test->assertStringContains('
バイナリファイル
', $html);
$test->assertStringContains('ファイル: a/old.sh | b/new.sh
', $html);
$test->assertStringContains('類似度:100% / 名前の変更元:old.sh / 名前の変更先:new.sh', $html);
});
$test->it('HTMLをエスケープするはず', function($test) use ($view): void {
$html = $view("--- a/.html\n+++ b/.html\n@@ -1 +1 @@\n-\n+&\n");
$test->assertFalse(str_contains($html, '