Mattia Rizzolo wrote on Sun, Oct 23, 2016 at 23:21:53 +0000: > Though I'd really prefer to see some tests for this before applying it;
Attached. The code change is unchanged from the previous patch. Test test works; I'm not sure whether is idiomatic pytest, though. Cheers Daniel [[[ 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 index e69de29..92c7861 100644 --- a/tests/data/order1.diff +++ 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 index e69de29..92ba8aa 100644 --- a/tests/data/order1a.json +++ b/tests/data/order1a.json @@ -0,0 +1 @@ +{ "hello": 42, "world": 43 } diff --git a/tests/data/order1b.json b/tests/data/order1b.json index e69de29..bb3a742 100644 --- a/tests/data/order1b.json +++ b/tests/data/order1b.json @@ -0,0 +1 @@ +{ "world": 43, "hello": 42 } ]]]