@@ -12,6 +12,7 @@ A PHP implementation for finding unordered diff between two `JSON` documents.
1212 * To simplify changes review between two ` JSON ` files you can use a standard ` diff ` tool on rearranged pretty-printed ` JSON ` .
1313 * To detect breaking changes by analyzing removals and changes from original ` JSON ` .
1414 * To keep original order of object sets (for example ` swagger.json ` [ parameters] ( https://swagger.io/docs/specification/describing-parameters/ ) list).
15+ * To make and apply JSON Patches, specified in [ RFC 6902] ( http://tools.ietf.org/html/rfc6902 ) from the IETF.
1516
1617## Installation
1718
@@ -52,6 +53,9 @@ $r = new JsonDiff(
5253
5354On created object you have several handy methods.
5455
56+ ### ` getPatch `
57+ Returns JsonPatch of difference
58+
5559### ` getRearranged `
5660Returns new value, rearranged with original order.
5761
@@ -98,7 +102,7 @@ $originalJson = <<<'JSON'
98102 "sub2": "b"
99103 },
100104 "key4": [
101- {"a":1, "b":true}, {"a":2, "b":false}, {"a":3}
105+ {"a":1, "b":true, "subs": [{"s":1}, {"s":2}, {"s":3}] }, {"a":2, "b":false}, {"a":3}
102106 ]
103107}
104108JSON;
@@ -108,7 +112,7 @@ $newJson = <<<'JSON'
108112 "key5": "wat",
109113 "key1": [5, 1, 2, 3],
110114 "key4": [
111- {"c":false, "a":2}, {"a":1, "b":true}, {"c":1, "a":3}
115+ {"c":false, "a":2}, {"a":1, "b":true, "subs": [{"s":3, "add": true}, {"s":2}, {"s":1}] }, {"c":1, "a":3}
112116 ],
113117 "key3": {
114118 "sub3": 0,
@@ -118,85 +122,125 @@ $newJson = <<<'JSON'
118122}
119123JSON;
120124
121- $expected = <<<'JSON'
122- {
123- "key1": [5, 1, 2, 3],
124- "key3": {
125- "sub1": "c",
126- "sub2": false,
127- "sub3": 0
128- },
129- "key4": [
130- {"a":1, "b":true}, {"a":2, "c":false}, {"a":3, "c":1}
131- ],
132- "key5": "wat"
133- }
125+ $patchJson = <<<'JSON'
126+ [
127+ {"value":4,"op":"test","path":"/key1/0"},
128+ {"value":5,"op":"replace","path":"/key1/0"},
129+
130+ {"op":"remove","path":"/key2"},
131+
132+ {"op":"remove","path":"/key3/sub0"},
133+
134+ {"value":"a","op":"test","path":"/key3/sub1"},
135+ {"value":"c","op":"replace","path":"/key3/sub1"},
136+
137+ {"value":"b","op":"test","path":"/key3/sub2"},
138+ {"value":false,"op":"replace","path":"/key3/sub2"},
139+
140+ {"value":0,"op":"add","path":"/key3/sub3"},
141+
142+ {"value":true,"op":"add","path":"/key4/0/subs/2/add"},
143+
144+ {"op":"remove","path":"/key4/1/b"},
145+
146+ {"value":false,"op":"add","path":"/key4/1/c"},
147+
148+ {"value":1,"op":"add","path":"/key4/2/c"},
149+
150+ {"value":"wat","op":"add","path":"/key5"}
151+ ]
134152JSON;
135153
136- $r = new JsonDiff(json_decode($originalJson), json_decode($newJson));
137- $this->assertSame(
138- json_encode(json_decode($expected), JSON_PRETTY_PRINT),
139- json_encode($r->getRearranged(), JSON_PRETTY_PRINT)
140- );
141- $this->assertSame('{"key3":{"sub3":0},"key4":{"1":{"c":false},"2":{"c":1}},"key5":"wat"}',
142- json_encode($r->getAdded()));
143- $this->assertSame(array(
144- '#/key3/sub3',
145- '#/key4/1/c',
146- '#/key4/2/c',
147- '#/key5',
148- ), $r->getAddedPaths());
149- $this->assertSame('{"key2":2,"key3":{"sub0":0},"key4":{"1":{"b":false}}}',
150- json_encode($r->getRemoved()));
151- $this->assertSame(array(
152- '#/key2',
153- '#/key3/sub0',
154- '#/key4/1/b',
155- ), $r->getRemovedPaths());
156-
157- $this->assertSame(array(
158- '#/key1/0',
159- '#/key3/sub1',
160- '#/key3/sub2',
161- ), $r->getModifiedPaths());
162-
163- $this->assertSame('{"key1":[4],"key3":{"sub1":"a","sub2":"b"}}', json_encode($r->getModifiedOriginal()));
164- $this->assertSame('{"key1":[5],"key3":{"sub1":"c","sub2":false}}', json_encode($r->getModifiedNew()));
154+ $diff = new JsonDiff(json_decode($originalJson), json_decode($newJson), JsonDiff::REARRANGE_ARRAYS);
155+ $this->assertEquals(json_decode($patchJson), $diff->getPatch()->jsonSerialize());
156+
157+ $original = json_decode($originalJson);
158+ $patch = JsonPatch::import(json_decode($patchJson));
159+ $patch->apply($original);
160+ $this->assertEquals($diff->getRearranged(), $original);
165161```
166162
167163## CLI tool
168164
169165### Usage
170166
171167```
172- json-diff --help
173- v1.0.0 json-diff
174- JSON diff and rearrange tool for PHP, https://github.com/swaggest/json-diff
168+ bin/json-diff --help
169+ JSON diff and apply tool for PHP, https://github.com/swaggest/json-diff
170+ Usage:
171+ json-diff <action>
172+ action Action name
173+ Allowed values: diff, apply, rearrange, info
174+ ```
175+
176+ ```
177+ bin/json-diff diff --help
178+ v2.0.0 json-diff diff
179+ JSON diff and apply tool for PHP, https://github.com/swaggest/json-diff
180+ Make patch from two json documents, output to STDOUT
175181Usage:
176- json-diff <action> <originalPath> <newPath>
177- action Action to perform
178- Allowed values: rearrange, changes, removals, additions, modifications
179- originalPath Path to old (original) json file
180- newPath Path to new json file
182+ json-diff diff <originalPath> <newPath>
183+ originalPath Path to old (original) json file
184+ newPath Path to new json file
181185
182186Options:
183- --out <out> Path to output result json file, STDOUT if not specified
184- --show-paths Show JSON paths
185- --show-json Show JSON result
187+ --pretty Pretty-print result JSON
188+ --rearrange-arrays Rearrange arrays to match original
189+ ```
190+
191+ ```
192+ bin/json-diff apply --help
193+ v2.0.0 json-diff apply
194+ JSON diff and apply tool for PHP, https://github.com/swaggest/json-diff
195+ Apply patch to base json document, output to STDOUT
196+ Usage:
197+ json-diff apply [patchPath] [basePath]
198+ patchPath Path to JSON patch file
199+ basePath Path to JSON base file
186200
187- Misc:
188- --help Show usage information
189- --version Show version
190- --bash-completion Generate bash completion
191- --install Install to /usr/local/bin/
201+ Options:
202+ --pretty Pretty-print result JSON
203+ --rearrange-arrays Rearrange arrays to match original
204+ ```
205+
206+ ```
207+ bin/json-diff rearrange --help
208+ v2.0.0 json-diff rearrange
209+ JSON diff and apply tool for PHP, https://github.com/swaggest/json-diff
210+ Rearrange json document in the order of another (original) json document
211+ Usage:
212+ json-diff rearrange <originalPath> <newPath>
213+ originalPath Path to old (original) json file
214+ newPath Path to new json file
215+
216+ Options:
217+ --pretty Pretty-print result JSON
218+ --rearrange-arrays Rearrange arrays to match original
219+ ```
220+
221+ ```
222+ bin/json-diff info --help
223+ v2.0.0 json-diff info
224+ JSON diff and apply tool for PHP, https://github.com/swaggest/json-diff
225+ Show diff info for two JSON documents
226+ Usage:
227+ json-diff info <originalPath> <newPath>
228+ originalPath Path to old (original) json file
229+ newPath Path to new json file
230+
231+ Options:
232+ --pretty Pretty-print result JSON
233+ --rearrange-arrays Rearrange arrays to match original
234+ --with-contents Add content to output
235+ --with-paths Add paths to output
192236```
193237
194238### Examples
195239
196240Using with standard ` diff `
197241
198242```
199- json-diff rearrange ./composer.json ./composer2.json --show-json | diff ./composer.json -
243+ json-diff rearrange ./composer.json ./composer2.json | diff ./composer.json -
2002443c3
201245< "description": "JSON diff and merge tool for PHP",
202246---
@@ -221,30 +265,29 @@ json-diff rearrange ./composer.json ./composer2.json --show-json | diff ./compos
221265Showing differences in ` JSON ` mode
222266
223267```
224- bin/json-diff changes ./composer.json ./composer2.json --show-json --show-paths
225- #/license
226- #/authors
227- #/bin
228- #/description
268+ bin/json-diff info tests/assets/original.json tests/assets/new.json --with-paths --pretty
229269{
230- "removals": {
231- "license": "MIT",
232- "authors": [
233- {
234- "name": "Viacheslav Poturaev",
235- 236- }
237- ],
238- "bin": [
239- "bin/json-diff"
240- ]
241- },
242- "additions": null,
243- "modifiedOriginal": {
244- "description": "JSON diff and merge tool for PHP"
245- },
246- "modifiedNew": {
247- "description": "JSON diff and merge tool for PHPH"
248- }
270+ "addedCnt": 4,
271+ "modifiedCnt": 4,
272+ "removedCnt": 3,
273+ "addedPaths": [
274+ "/key3/sub3",
275+ "/key4/0/c",
276+ "/key4/2/c",
277+ "/key5"
278+ ],
279+ "modifiedPaths": [
280+ "/key1/0",
281+ "/key3/sub1",
282+ "/key3/sub2",
283+ "/key4/0/a",
284+ "/key4/1/a",
285+ "/key4/1/b"
286+ ],
287+ "removedPaths": [
288+ "/key2",
289+ "/key3/sub0",
290+ "/key4/0/b"
291+ ]
249292}
250293```
0 commit comments