[diffoscope] 01/01: json: detect order-only differences and print them nicely

Mattia Rizzolo mattia at debian.org
Wed Oct 26 22:13:45 CEST 2016


This is an automated email from the git hooks/post-receive script.

mattia pushed a commit to branch master
in repository diffoscope.

commit 8faf040767b892e1cf19d4ec2965a29301b9ae40
Author: Daniel Shahaf <danielsh at apache.org>
Date:   Wed Oct 26 20:09:12 2016 +0000

    json: detect order-only differences and print them nicely
    
    Closes: #839538
    Signed-off-by: Mattia Rizzolo <mattia at debian.org>
---
 diffoscope/comparators/json.py | 19 ++++++++++++++-----
 tests/comparators/test_json.py |  7 +++++++
 tests/data/order1.diff         |  7 +++++++
 tests/data/order1a.json        |  1 +
 tests/data/order1b.json        |  1 +
 5 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/diffoscope/comparators/json.py b/diffoscope/comparators/json.py
index d16a762..8d0c104 100644
--- a/diffoscope/comparators/json.py
+++ b/diffoscope/comparators/json.py
@@ -17,6 +17,7 @@
 # You should have received a copy of the GNU General Public License
 # along with diffoscope.  If not, see <http://www.gnu.org/licenses/>.
 
+from collections import OrderedDict
 import re
 import json
 
@@ -34,18 +35,26 @@ class JSONFile(File):
 
         with open(file.path) as f:
             try:
-                file.parsed = json.load(f)
+                file.parsed = json.load(f, object_pairs_hook=OrderedDict)
             except json.JSONDecodeError:
                 return False
 
         return True
 
     def compare_details(self, other, source=None):
-        return [Difference.from_text(self.dumps(self), self.dumps(other),
-            self.path, other.path)]
+        difference = Difference.from_text(self.dumps(self), self.dumps(other),
+            self.path, other.path)
+        if difference:
+            return [difference]
+
+        difference = Difference.from_text(self.dumps(self, sort_keys=False),
+                                          self.dumps(other, sort_keys=False),
+                                          self.path, other.path,
+                                          comment="ordering differences only")
+        return [difference]
 
     @staticmethod
-    def dumps(file):
+    def dumps(file, sort_keys=True):
         if not hasattr(file, 'parsed'):
             return ""
-        return json.dumps(file.parsed, indent=4, sort_keys=True)
+        return json.dumps(file.parsed, indent=4, sort_keys=sort_keys)
diff --git a/tests/comparators/test_json.py b/tests/comparators/test_json.py
index 26ea110..57c2006 100644
--- a/tests/comparators/test_json.py
+++ b/tests/comparators/test_json.py
@@ -25,6 +25,8 @@ from utils import data, load_fixture, assert_non_existing
 
 json1 = load_fixture(data('test1.json'))
 json2 = load_fixture(data('test2.json'))
+json3a = load_fixture(data('order1a.json'))
+json3b = load_fixture(data('order1b.json'))
 
 def test_identification(json1):
     assert isinstance(json1, JSONFile)
@@ -43,3 +45,8 @@ def test_diff(differences):
 
 def test_compare_non_existing(monkeypatch, json1):
     assert_non_existing(monkeypatch, json1)
+
+def test_ordering_differences(json3a, json3b):
+    diff = json3a.compare(json3b)
+    assert diff.details[0]._comments == ['ordering differences only']
+    assert diff.details[0].unified_diff == open(data('order1.diff')).read()
diff --git a/tests/data/order1.diff b/tests/data/order1.diff
new file mode 100644
index 0000000..92c7861
--- /dev/null
+++ b/tests/data/order1.diff
@@ -0,0 +1,7 @@
+@@ -1,4 +1,4 @@
+ {
+-    "hello": 42,
+-    "world": 43
++    "world": 43,
++    "hello": 42
+ }
diff --git a/tests/data/order1a.json b/tests/data/order1a.json
new file mode 100644
index 0000000..92ba8aa
--- /dev/null
+++ b/tests/data/order1a.json
@@ -0,0 +1 @@
+{ "hello": 42, "world": 43 }
diff --git a/tests/data/order1b.json b/tests/data/order1b.json
new file mode 100644
index 0000000..bb3a742
--- /dev/null
+++ b/tests/data/order1b.json
@@ -0,0 +1 @@
+{ "world": 43, "hello": 42 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/diffoscope.git


More information about the diffoscope mailing list