diff --git a/CHANGELOG.md b/CHANGELOG.md index 892cf98..cba0efb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [3.7.3] - 2020-01-24 + +### Fixed +- Merge patch was not replacing partially different arrays. + ## [3.7.2] - 2019-10-23 ### Added @@ -30,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Compatibility option to `TOLERATE_ASSOCIATIVE_ARRAYS` that mimic JSON objects. +[3.7.3]: https://github.com/swaggest/json-diff/compare/v3.7.2...v3.7.3 [3.7.2]: https://github.com/swaggest/json-diff/compare/v3.7.1...v3.7.2 [3.7.1]: https://github.com/swaggest/json-diff/compare/v3.7.0...v3.7.1 [3.7.0]: https://github.com/swaggest/json-diff/compare/v3.6.0...v3.7.0 diff --git a/src/JsonDiff.php b/src/JsonDiff.php index 461a811..2302def 100644 --- a/src/JsonDiff.php +++ b/src/JsonDiff.php @@ -323,6 +323,7 @@ private function process($original, $new) } $isUriFragment = (bool)($this->options & self::JSON_URI_FRAGMENT_ID); + $diffCnt = $this->addedCnt + $this->modifiedCnt + $this->removedCnt; foreach ($originalKeys as $key => $originalValue) { if ($this->options & self::STOP_ON_DIFF) { if ($this->modifiedCnt || $this->addedCnt || $this->removedCnt) { @@ -366,6 +367,10 @@ private function process($original, $new) $this->pathItems = $pathItems; } + if ($merge && $isArray && $this->addedCnt + $this->modifiedCnt + $this->removedCnt > $diffCnt) { + JsonPointer::add($this->merge, $this->pathItems, $new); + } + // additions foreach ($newArray as $key => $value) { $this->addedCnt++; diff --git a/tests/assets/merge.json b/tests/assets/merge.json new file mode 100644 index 0000000..ed799f2 --- /dev/null +++ b/tests/assets/merge.json @@ -0,0 +1,30 @@ +{ + "key1": [ + 5, + 1, + 2, + 3 + ], + "key2": null, + "key3": { + "sub0": null, + "sub1": "c", + "sub2": false, + "sub3": 0 + }, + "key4": [ + { + "c": false, + "a": 2 + }, + { + "a": 1, + "b": true + }, + { + "c": 1, + "a": 3 + } + ], + "key5": "wat" +} \ No newline at end of file diff --git a/tests/src/MergePatchTest.php b/tests/src/MergePatchTest.php index eb02c21..def53f8 100644 --- a/tests/src/MergePatchTest.php +++ b/tests/src/MergePatchTest.php @@ -289,5 +289,20 @@ protected function doTest($case) } + public function testComplex() + { + $original = json_decode(file_get_contents(__DIR__ . '/../assets/original.json')); + $new = json_decode(file_get_contents(__DIR__ . '/../assets/new.json')); + + $diff = new JsonDiff($original, $new); + $mergePatch = $diff->getMergePatch(); + $mergePatchJson = json_encode($mergePatch, JSON_UNESCAPED_SLASHES + JSON_PRETTY_PRINT); + + $this->assertEquals(file_get_contents(__DIR__ . '/../assets/merge.json') , $mergePatchJson); + + JsonMergePatch::apply($original, $mergePatch); + $this->assertEquals($new, $original); + } + } \ No newline at end of file