aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xjson_diff.py52
-rw-r--r--test_json_diff.py17
-rw-r--r--test_strings.py19
3 files changed, 66 insertions, 22 deletions
diff --git a/json_diff.py b/json_diff.py
index d7d8aeb..4522ceb 100755
--- a/json_diff.py
+++ b/json_diff.py
@@ -132,7 +132,7 @@ class Comparator(object):
"""
Main workhorse, the object itself
"""
- def __init__(self, fn1=None, fn2=None, included_attrs=(), excluded_attrs=()):
+ def __init__(self, fn1=None, fn2=None, opts=None):
self.obj1 = None
self.obj2 = None
if fn1:
@@ -144,22 +144,37 @@ class Comparator(object):
try:
self.obj2 = json.load(fn2)
except (TypeError, OverflowError, ValueError), exc:
- raise BadJSONError("Cannot decode object from JSON\n%s" % unicode(exc))
- self.excluded_attributes = excluded_attrs
- self.included_attributes = included_attrs
+ raise BadJSONError("Cannot decode object from JSON\n%s" %
+ unicode(exc))
+
+ if opts and ("excluded_attrs" in opts):
+ self.excluded_attributes = opts['excluded_attrs']
+ else:
+ self.excluded_attributes = ()
+ if opts and ("included_attrs" in opts):
+ self.included_attributes = opts['included_attrs']
+ else:
+ self.included_attributes = ()
+
+ if opts and ('ignore_append' in opts):
+ self.ignore_appended = opts['ignore_append']
+ else:
+ self.ignore_appended = False
def _is_incex_key(self, key, value):
- """Is this key excluded or not among included ones? If yes, it should be ignored.
- """
- key_out = ((self.included_attributes and (key not in self.included_attributes)) or
- (key in self.excluded_attributes))
+ """Is this key excluded or not among included ones? If yes, it should
+ be ignored."""
+ key_out = ((self.included_attributes and
+ (key not in self.included_attributes)) or
+ (key in self.excluded_attributes))
value_out = True
if isinstance(value, dict):
for change_key in value:
if isinstance(value[change_key], dict):
for key in value[change_key]:
- if ((self.included_attributes and (key in self.included_attributes)) or
- (key not in self.excluded_attributes)):
+ if ((self.included_attributes and
+ (key in self.included_attributes)) or
+ (key not in self.excluded_attributes)):
value_out = False
return key_out and value_out
@@ -173,8 +188,12 @@ class Comparator(object):
for change_type in result:
temp_dict = {}
for key in result[change_type]:
- logging.debug("result[change_type] = %s, key = %s", unicode(result[change_type]), key)
- logging.debug("self._is_incex_key(key, result[change_type][key]) = %s",
+ logging.debug("change_type = %s", change_type)
+ if self.ignore_appended and (change_type == "_append"):
+ continue
+ logging.debug("result[change_type] = %s, key = %s",
+ unicode(result[change_type]), key)
+ logging.debug("self._is_incex_key = %s",
self._is_incex_key(key, result[change_type][key]))
if not self._is_incex_key(key, result[change_type][key]):
temp_dict[key] = result[change_type][key]
@@ -306,8 +325,11 @@ if __name__ == "__main__":
action="append", dest="exclude", metavar="ATTR", default=[],
help="attributes which should be ignored when comparing")
parser.add_option("-i", "--include",
- action="append", dest="include", metavar="ATTR", default=[],
- help="attributes which should be exclusively used when comparing")
+ action="append", dest="include", metavar="ATTR", default=[],
+ help="attributes which should be exclusively used when comparing")
+ parser.add_option("-a", "--ignore-append",
+ action="store_true", dest="ignore_append", metavar="BOOL", default=False,
+ help="ignore appended keys")
parser.add_option("-H", "--HTML",
action="store_true", dest="HTMLoutput", metavar="BOOL", default=False,
help="program should output to HTML report")
@@ -316,7 +338,7 @@ if __name__ == "__main__":
if len(args) != 2:
parser.error("Script requires two positional arguments, names for old and new JSON file.")
- diff = Comparator(open(args[0]), open(args[1]), options.include, options.exclude)
+ diff = Comparator(open(args[0]), open(args[1]), options)
if options.HTMLoutput:
diff_res = diff.compare_dicts()
# we want to hardcode UTF-8 here, because that's what's in <meta> element
diff --git a/test_json_diff.py b/test_json_diff.py
index 5b93044..21cd7af 100644
--- a/test_json_diff.py
+++ b/test_json_diff.py
@@ -14,11 +14,12 @@ import codecs
from test_strings import ARRAY_DIFF, ARRAY_NEW, ARRAY_OLD, \
NESTED_DIFF, NESTED_DIFF_EXCL, NESTED_DIFF_INCL, NESTED_NEW, NESTED_OLD, \
NO_JSON_NEW, NO_JSON_OLD, SIMPLE_ARRAY_DIFF, SIMPLE_ARRAY_NEW, \
+ NESTED_DIFF_IGNORING, \
SIMPLE_ARRAY_OLD, SIMPLE_DIFF, SIMPLE_DIFF_HTML, SIMPLE_NEW, SIMPLE_OLD
class OurTestCase(unittest.TestCase):
- def _run_test(self, oldf, newf, difff, msg="", inc=(), exc=()):
- diffator = json_diff.Comparator(oldf, newf, inc, exc)
+ def _run_test(self, oldf, newf, difff, msg="", opts=None):
+ diffator = json_diff.Comparator(oldf, newf, opts)
diff = diffator.compare_dicts()
expected = json.load(difff)
self.assertEqual(json.dumps(diff, sort_keys=True), json.dumps(expected, sort_keys=True),
@@ -26,11 +27,12 @@ class OurTestCase(unittest.TestCase):
(json.dumps(expected, sort_keys=True, indent=4, ensure_ascii=False),
json.dumps(diff, sort_keys=True, indent=4, ensure_ascii=False)))
- def _run_test_strings(self, olds, news, diffs, msg="", inc=(), exc=()):
- self._run_test(StringIO(olds), StringIO(news), StringIO(diffs), msg, inc, exc)
+ def _run_test_strings(self, olds, news, diffs, msg="", opts=None):
+ self._run_test(StringIO(olds), StringIO(news), StringIO(diffs),
+ msg, opts)
- def _run_test_formatted(self, oldf, newf, difff, msg=""):
- diffator = json_diff.Comparator(oldf, newf)
+ def _run_test_formatted(self, oldf, newf, difff, msg="", opts=None):
+ diffator = json_diff.Comparator(oldf, newf, opts)
diff = ("\n".join([line.strip() \
for line in unicode( \
json_diff.HTMLFormatter(diffator.compare_dicts())).split("\n")])).strip()
@@ -133,7 +135,8 @@ class TestPiglitData(OurTestCase):
def test_piglit_result_only(self):
self._run_test(open("test/old-testing-data.json"), open("test/new-testing-data.json"),
open("test/diff-result-only-testing-data.json"),
- "Large piglit reports diff (just resume field).", inc=('result',))
+ "Large piglit reports diff (just resume field).",
+ {'included_attrs': ("result",)})
if __name__ == "__main__":
unittest.main()
diff --git a/test_strings.py b/test_strings.py
index 1935912..31ab50f 100644
--- a/test_strings.py
+++ b/test_strings.py
@@ -173,6 +173,25 @@ NESTED_DIFF_INCL = u"""
}
"""
+NESTED_DIFF_IGNORING = u"""
+{
+ "_remove": {
+ "b": 2,
+ "ignore": {
+ "else": true
+ }
+ },
+ "_update": {
+ "a": 2,
+ "child": {
+ "_update": {
+ "nome": "Maruška"
+ }
+ }
+ }
+}
+"""
+
ARRAY_OLD = u"""
{
"a": 1,