summaryrefslogtreecommitdiff
path: root/yarns
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2018-01-13 12:43:06 +0200
committerLars Wirzenius <liw@liw.fi>2018-01-14 22:23:43 +0200
commit769f03d7ff1709a43c0b82c131fae494f67cf08f (patch)
tree6ca9d6fa1116c16d1bf71ebe0839e867f73066ac /yarns
parent4c6243ba5daaaab525e6c8ca866d5ebcb9f81dcf (diff)
downloadick2-769f03d7ff1709a43c0b82c131fae494f67cf08f.tar.gz
Add: show dict diffs in a way that's easier to understand
Diffstat (limited to 'yarns')
-rw-r--r--yarns/900-implements.yarn7
-rw-r--r--yarns/lib.py65
2 files changed, 71 insertions, 1 deletions
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 <http://www.gnu.org/licenses/>.
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