From eda778b328aa3d0d84acd9c6d7e93e66e9ab08e7 Mon Sep 17 00:00:00 2001 From: Mansoor Date: Fri, 8 Mar 2024 19:25:58 +0500 Subject: [PATCH 1/2] Feat/Add getStatistics method to Diff class --- src/Diff.php | 34 ++++++++++++++++++++- tests/DiffTest.php | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) diff --git a/src/Diff.php b/src/Diff.php index 713e7d8..6874b94 100644 --- a/src/Diff.php +++ b/src/Diff.php @@ -3,6 +3,8 @@ namespace Overtrue\LaravelVersionable; use Illuminate\Support\Arr; +use Illuminate\Support\Collection; +use Jfcherng\Diff\Differ; use Jfcherng\Diff\DiffHelper; /** @@ -58,7 +60,7 @@ public function toSideBySideHtml(array $differOptions = [], array $renderOptions return $this->render('SideBySide', $differOptions, $renderOptions); } - public function render(?string $renderer = null, array $differOptions = [], array $renderOptions = []): array + public function render(string $renderer = null, array $differOptions = [], array $renderOptions = []): array { if (empty($differOptions)) { $differOptions = $this->differOptions; @@ -92,4 +94,34 @@ public function render(?string $renderer = null, array $differOptions = [], arra return $diff; } + + public function getStatistics(array $differOptions = []): array + { + if (empty($differOptions)) { + $differOptions = $this->differOptions; + } + + $oldContents = $this->fromVersion->contents; + $newContents = $this->toVersion->contents; + + $diffStats = new Collection; + + foreach ($oldContents as $key => $value) { + if ($newContents[$key] !== $oldContents[$key]) { + $diffStats->push( + (new Differ( + explode("\n", $newContents[$key]), + explode("\n", $oldContents[$key]), + ))->getStatistics() + ); + } + } + + return [ + 'inserted' => $diffStats->sum('inserted'), + 'deleted' => $diffStats->sum('deleted'), + 'unmodified' => $diffStats->sum('unmodified'), + 'changedRatio' => $diffStats->sum('changedRatio'), + ]; + } } diff --git a/tests/DiffTest.php b/tests/DiffTest.php index 7c0fe60..33ad189 100644 --- a/tests/DiffTest.php +++ b/tests/DiffTest.php @@ -140,6 +140,79 @@ public function test_diff_to_side_by_side_html() ); } + /** + * @test + */ + public function it_can_return_the_diff_statistics() + { + $old = new Version(['contents' => ['title' => 'example title', 'content' => 'example content']]); + + // we are modifying everything + $new = new Version(['contents' => ['title' => 'changing the title', 'content' => 'changing the content']]); + + $stats = (new Diff($new, $old))->getStatistics(); + + $this->assertIsArray($stats); + $this->assertArrayHasKey('inserted', $stats); + $this->assertArrayHasKey('deleted', $stats); + $this->assertArrayHasKey('unmodified', $stats); + + $this->assertEquals(2, $stats['inserted']); // two new lines inserted + $this->assertEquals(2, $stats['deleted']); // two lines deleted + $this->assertEquals(0, $stats['unmodified']); // modified everything + } + + /** + * @test + */ + public function it_can_return_correct_statistics_for_new_line_insertions() + { + $old = new Version(['contents' => ['title' => 'example title', 'content' => 'example content']]); + + // we are adding two new lines + $new = new Version(['contents' => ['content' => "example content\n adding new line \n another new line"]]); + + $stats = (new Diff($new, $old))->getStatistics(); + + $this->assertEquals(2, $stats['inserted']); // two new lines inserted + $this->assertEquals(0, $stats['deleted']); // no deletions + $this->assertEquals(1, $stats['unmodified']); // one line unmodified + } + + /** + * @test + */ + public function it_can_return_correct_statistics_for_deleted_lines() + { + $old = new Version(['contents' => ['title' => 'example title', 'content' => "example content\n adding new line \n another new line"]]); + + // we are removing last two lines + $new = new Version(['contents' => ['content' => 'example content']]); + + $stats = (new Diff($new, $old))->getStatistics(); + + $this->assertEquals(0, $stats['inserted']); // no insertions + $this->assertEquals(2, $stats['deleted']); // two lines deleted + $this->assertEquals(1, $stats['unmodified']); // one line unmodified + } + + /** + * @test + */ + public function it_can_return_correct_statistics_for_unmodified_lines() + { + $old = new Version(['contents' => ['title' => 'example title', 'content' => "example content\n adding new line \n another new line"]]); + + // we are just removing the last line + $new = new Version(['contents' => ['content' => "example content\n adding new line "]]); + + $stats = (new Diff($new, $old))->getStatistics(); + + $this->assertEquals(0, $stats['inserted']); // no insertions + $this->assertEquals(1, $stats['deleted']); // one line deleted + $this->assertEquals(2, $stats['unmodified']); // two lines unmodified + } + public function test_diff_nested_array_to_array() { $oldContent = [ From 9f99034777bc1e630f733a12e2dd0a954e1b3f63 Mon Sep 17 00:00:00 2001 From: Mansoor Date: Fri, 8 Mar 2024 19:32:22 +0500 Subject: [PATCH 2/2] fix code styling --- src/Diff.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Diff.php b/src/Diff.php index 6874b94..7c0e11c 100644 --- a/src/Diff.php +++ b/src/Diff.php @@ -60,7 +60,7 @@ public function toSideBySideHtml(array $differOptions = [], array $renderOptions return $this->render('SideBySide', $differOptions, $renderOptions); } - public function render(string $renderer = null, array $differOptions = [], array $renderOptions = []): array + public function render(?string $renderer = null, array $differOptions = [], array $renderOptions = []): array { if (empty($differOptions)) { $differOptions = $this->differOptions;