Yes! You can use jycm
from jycm.helper import make_ignore_order_func
from jycm.jycm import YouchamaJsonDiffer
a = {
"errors": [
{"error": "invalid", "field": "email"},
{"error": "required", "field": "name"}
],
"success": False
}
b = {
"success": False,
"errors": [
{"error": "required", "field": "name"},
{"error": "invalid", "field": "email"}
]
}
ycm = YouchamaJsonDiffer(a, b, ignore_order_func=make_ignore_order_func([
"^errors",
]))
ycm.diff()
assert ycm.to_dict(no_pairs=True) == {} # aka no diff
for a more complex example(value changes in deep structure)
from jycm.helper import make_ignore_order_func
from jycm.jycm import YouchamaJsonDiffer
a = {
"errors": [
{"error": "invalid", "field": "email"},
{"error": "required", "field": "name"}
],
"success": True
}
b = {
"success": False,
"errors": [
{"error": "required", "field": "name-1"},
{"error": "invalid", "field": "email"}
]
}
ycm = YouchamaJsonDiffer(a, b, ignore_order_func=make_ignore_order_func([
"^errors",
]))
ycm.diff()
assert ycm.to_dict() == {
'just4vis:pairs': [
{'left': 'invalid', 'right': 'invalid', 'left_path': 'errors->[0]->error', 'right_path': 'errors->[1]->error'},
{'left': {'error': 'invalid', 'field': 'email'}, 'right': {'error': 'invalid', 'field': 'email'},
'left_path': 'errors->[0]', 'right_path': 'errors->[1]'},
{'left': 'email', 'right': 'email', 'left_path': 'errors->[0]->field', 'right_path': 'errors->[1]->field'},
{'left': {'error': 'invalid', 'field': 'email'}, 'right': {'error': 'invalid', 'field': 'email'},
'left_path': 'errors->[0]', 'right_path': 'errors->[1]'},
{'left': 'required', 'right': 'required', 'left_path': 'errors->[1]->error',
'right_path': 'errors->[0]->error'},
{'left': {'error': 'required', 'field': 'name'}, 'right': {'error': 'required', 'field': 'name-1'},
'left_path': 'errors->[1]', 'right_path': 'errors->[0]'},
{'left': 'name', 'right': 'name-1', 'left_path': 'errors->[1]->field', 'right_path': 'errors->[0]->field'},
{'left': {'error': 'required', 'field': 'name'}, 'right': {'error': 'required', 'field': 'name-1'},
'left_path': 'errors->[1]', 'right_path': 'errors->[0]'},
{'left': {'error': 'required', 'field': 'name'}, 'right': {'error': 'required', 'field': 'name-1'},
'left_path': 'errors->[1]', 'right_path': 'errors->[0]'}
],
'value_changes': [
{'left': 'name', 'right': 'name-1', 'left_path': 'errors->[1]->field', 'right_path': 'errors->[0]->field',
'old': 'name', 'new': 'name-1'},
{'left': True, 'right': False, 'left_path': 'success', 'right_path': 'success', 'old': True, 'new': False}
]
}
whose results can be rendered as
