From 769f03d7ff1709a43c0b82c131fae494f67cf08f Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sat, 13 Jan 2018 12:43:06 +0200 Subject: Add: show dict diffs in a way that's easier to understand --- yarns/900-implements.yarn | 7 ++++- yarns/lib.py | 65 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) (limited to 'yarns') diff --git a/yarns/900-implements.yarn b/yarns/900-implements.yarn index 1a42198..59da6c7 100644 --- a/yarns/900-implements.yarn +++ b/yarns/900-implements.yarn @@ -108,7 +108,12 @@ along with this program. If not, see . expected_text = get_next_match() expected = json.loads(expected_text) actual = json.loads(vars['body']) - assertEqual(expected, actual) + print('expected', json.dumps(expected, indent=4)) + print('actual', json.dumps(actual, indent=4)) + diff = dict_diff(expected, actual) + if diff is not None: + print(diff) + assert 0 IMPLEMENTS THEN body text is "(.*)" expected = unescape(get_next_match()) diff --git a/yarns/lib.py b/yarns/lib.py index b19ccf3..b4929fd 100644 --- a/yarns/lib.py +++ b/yarns/lib.py @@ -153,3 +153,68 @@ def delete(url, token): } r = requests.delete(url, headers=headers, verify=False) return r.status_code, r.headers['Content-Type'], dict(r.headers), r.text + + +def dict_diff(a, b): + if not isinstance(a, dict): + return 'first value is not a dict' + if not isinstance(b, dict): + return 'second value is not a dict' + + delta = [] + + for key in a: + if key not in b: + delta.append('second does not have key {}'.format(key)) + elif isinstance(a[key], dict): + delta2 = dict_diff(a[key], b[key]) + if delta2 is not None: + delta.append('key {}: dict values differ:'.format(key)) + delta.append(delta2) + elif isinstance(a[key], list): + delta2 = list_diff(a[key], b[key]) + if delta2 is not None: + delta.append('key {}: list values differ:'.format(key)) + delta.append(delta2) + elif a[key] != b[key]: + delta.append('key {}: values differ'.format(key)) + delta.append(' first value : {!r}'.format(a[key])) + delta.append(' second value: {!r}'.format(b[key])) + + for key in b: + if key not in a: + delta.append('first does not have key {}'.format(key)) + + if delta: + return '\n'.join(delta) + return None + + +def list_diff(a, b): + if not isinstance(a, list): + return 'first value is not a list' + if not isinstance(b, list): + return 'second value is not a list' + + delta = [] + + for i in range(len(a)): + if i >= len(b): + delta.append('second list is shorter than first') + break + elif isinstance(a[i], dict): + delta2 = dict_diff(a[i], b[i]) + if delta2 is not None: + delta.append('item {}: items are different dicts'.format(i)) + delta.append(delta2) + elif a[i] != b[i]: + delta.append('item %d: values differ'.format(i)) + delta.append(' first value : {!r}'.format(a[i])) + delta.append(' second value: {!r}'.format(b[i])) + + if len(a) < len(b): + delta.append('first list is shorter than second') + + if delta: + return '\n'.join(delta) + return None -- cgit v1.2.1