From 4dc82340e04f1f445e072952ec03a3e9f544bc66 Mon Sep 17 00:00:00 2001 From: kafkaf- Date: Wed, 5 Nov 2014 23:06:31 +0200 Subject: Catching a broad exception to ensure the return of the default, added tests, fixed a bug where obj.contains(obj) returned false, added test case --- jsonpointer.py | 7 ++++--- tests.py | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/jsonpointer.py b/jsonpointer.py index ee7f266..02aa594 100644 --- a/jsonpointer.py +++ b/jsonpointer.py @@ -166,7 +166,8 @@ class JsonPointer(object): try: doc = self.walk(doc, part) - except JsonPointerException: + # Catching a broad exception to ensure the return of the default + except: if default is _nothing: raise else: @@ -215,7 +216,7 @@ class JsonPointer(object): else: raise JsonPointerException("Document '%s' does not support indexing, " - "must be dict/list or support __getitem__" % type(doc)) + "must be mapping/sequence or support __getitem__" % type(doc)) def walk(self, doc, part): @@ -249,7 +250,7 @@ class JsonPointer(object): def contains(self, ptr): """ Returns True if self contains the given ptr """ - return len(self.parts) > len(ptr.parts) and \ + return len(self.parts) >= len(ptr.parts) and \ self.parts[:len(ptr.parts)] == ptr.parts @property diff --git a/tests.py b/tests.py index 2b5608e..db9c1c7 100755 --- a/tests.py +++ b/tests.py @@ -8,6 +8,7 @@ import copy from jsonpointer import resolve_pointer, EndOfList, JsonPointerException, \ JsonPointer, set_pointer + class SpecificationTests(unittest.TestCase): """ Tests all examples from the JSON Pointer specification """ @@ -70,6 +71,7 @@ class SpecificationTests(unittest.TestCase): new_ptr = JsonPointer.from_parts(parts) self.assertEqual(ptr, new_ptr) + class ComparisonTests(unittest.TestCase): def test_eq_hash(self): @@ -94,10 +96,10 @@ class ComparisonTests(unittest.TestCase): p3 = JsonPointer("/b/c") self.assertTrue(p1.contains(p2)) + self.assertTrue(p1.contains(p1)) self.assertFalse(p1.contains(p3)) - class WrongInputTests(unittest.TestCase): def test_no_start_slash(self): @@ -181,11 +183,11 @@ class SetTests(unittest.TestCase): self.assertRaises(JsonPointerException, set_pointer, doc, "", 9) -class AltTypesTests(unittest.TestCase): - def test_alttypes(self): - JsonPointer.alttypes = True +class AltTypesTests(unittest.TestCase): + @classmethod + def setUpClass(cls): class Node(object): def __init__(self, name, parent=None): self.name = name @@ -217,6 +219,18 @@ class AltTypesTests(unittest.TestCase): raise KeyError("Only left and right supported: %s" % key) + class mdict(object): + def __init__(self, d): + self._d = d + def __getitem__(self, item): + return self._d[item] + + cls.mdict = mdict({'root': {'1': {'2': '3'}}}) + cls.Node = Node + + + def test_alttypes(self): + Node = self.Node root = Node('root') root.set_left(Node('a')) @@ -238,6 +252,38 @@ class AltTypesTests(unittest.TestCase): set_pointer(root, '/left/right', Node('AB')) self.assertEqual(resolve_pointer(root, '/left/right').name, 'AB') + def test_mock_dict_sanity(self): + doc = self.mdict + default = None + + # TODO: Generate this automatically for any given object + path_to_expected_value = { + '/root/1': {'2': '3'}, + '/root': {'1': {'2': '3'}}, + '/root/1/2': '3', + } + + for path, expected_value in iter(path_to_expected_value.items()): + self.assertEqual(resolve_pointer(doc, path, default), expected_value) + + def test_mock_dict_returns_default(self): + doc = self.mdict + default = None + + path_to_expected_value = { + '/foo': default, + '/x/y/z/d': default + } + + for path, expected_value in iter(path_to_expected_value.items()): + self.assertEqual(resolve_pointer(doc, path, default), expected_value) + + def test_mock_dict_raises_key_error(self): + doc = self.mdict + self.assertRaises(KeyError, resolve_pointer, doc, '/foo') + + + suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(SpecificationTests)) suite.addTest(unittest.makeSuite(ComparisonTests)) -- cgit v1.2.1 From ec26151db15c241e29c7730dc12657434370ff67 Mon Sep 17 00:00:00 2001 From: kafkaf- Date: Fri, 14 Nov 2014 16:05:00 +0200 Subject: Removed unrelated changes to the contains method, reverted the exception handle --- jsonpointer.py | 5 ++--- tests.py | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/jsonpointer.py b/jsonpointer.py index 02aa594..b3f0362 100644 --- a/jsonpointer.py +++ b/jsonpointer.py @@ -166,8 +166,7 @@ class JsonPointer(object): try: doc = self.walk(doc, part) - # Catching a broad exception to ensure the return of the default - except: + except JsonPointerException: if default is _nothing: raise else: @@ -250,7 +249,7 @@ class JsonPointer(object): def contains(self, ptr): """ Returns True if self contains the given ptr """ - return len(self.parts) >= len(ptr.parts) and \ + return len(self.parts) > len(ptr.parts) and \ self.parts[:len(ptr.parts)] == ptr.parts @property diff --git a/tests.py b/tests.py index db9c1c7..cc81dc6 100755 --- a/tests.py +++ b/tests.py @@ -96,7 +96,6 @@ class ComparisonTests(unittest.TestCase): p3 = JsonPointer("/b/c") self.assertTrue(p1.contains(p2)) - self.assertTrue(p1.contains(p1)) self.assertFalse(p1.contains(p3)) -- cgit v1.2.1 From 8a371c786fc77139be2a325c05e0a5c95ea83246 Mon Sep 17 00:00:00 2001 From: kafkaf- Date: Fri, 14 Nov 2014 16:06:20 +0200 Subject: Removed the setUpClass method to support py26 --- tests.py | 80 +++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 39 insertions(+), 41 deletions(-) diff --git a/tests.py b/tests.py index cc81dc6..3bec626 100755 --- a/tests.py +++ b/tests.py @@ -185,47 +185,45 @@ class SetTests(unittest.TestCase): class AltTypesTests(unittest.TestCase): - @classmethod - def setUpClass(cls): - class Node(object): - def __init__(self, name, parent=None): - self.name = name - self.parent = parent - self.left = None - self.right = None - - def set_left(self, node): - node.parent = self - self.left = node - - def set_right(self, node): - node.parent = self - self.right = node - - def __getitem__(self, key): - if key == 'left': - return self.left - if key == 'right': - return self.right - - raise KeyError("Only left and right supported") - - def __setitem__(self, key, val): - if key == 'left': - return self.set_left(val) - if key == 'right': - return self.set_right(val) - - raise KeyError("Only left and right supported: %s" % key) - - class mdict(object): - def __init__(self, d): - self._d = d - def __getitem__(self, item): - return self._d[item] - - cls.mdict = mdict({'root': {'1': {'2': '3'}}}) - cls.Node = Node + class Node(object): + def __init__(self, name, parent=None): + self.name = name + self.parent = parent + self.left = None + self.right = None + + def set_left(self, node): + node.parent = self + self.left = node + + def set_right(self, node): + node.parent = self + self.right = node + + def __getitem__(self, key): + if key == 'left': + return self.left + if key == 'right': + return self.right + + raise KeyError("Only left and right supported") + + def __setitem__(self, key, val): + if key == 'left': + return self.set_left(val) + if key == 'right': + return self.set_right(val) + + raise KeyError("Only left and right supported: %s" % key) + + class mdict(object): + def __init__(self, d): + self._d = d + def __getitem__(self, item): + return self._d[item] + + mdict = mdict({'root': {'1': {'2': '3'}}}) + Node = Node def test_alttypes(self): -- cgit v1.2.1 From 4c5cb493f2a8e41fd05b9b25df419701e215812a Mon Sep 17 00:00:00 2001 From: kafkaf- Date: Fri, 14 Nov 2014 16:18:39 +0200 Subject: Using the same handling for the case in which the doc is a mapping or an object that support __getitem__(but not a sequence), Updated the tests --- jsonpointer.py | 18 +++++++----------- tests.py | 3 ++- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/jsonpointer.py b/jsonpointer.py index b3f0362..06d2cb7 100644 --- a/jsonpointer.py +++ b/jsonpointer.py @@ -225,15 +225,7 @@ class JsonPointer(object): assert (type(doc) in (dict, list) or hasattr(doc, '__getitem__')), "invalid document type %s" % (type(doc),) - if isinstance(doc, Mapping): - try: - return doc[part] - - except KeyError: - raise JsonPointerException("member '%s' not found in %s" % (part, doc)) - - elif isinstance(doc, Sequence): - + if isinstance(doc, Sequence): if part == '-': return EndOfList(doc) @@ -243,10 +235,14 @@ class JsonPointer(object): except IndexError: raise JsonPointerException("index '%s' is out of bounds" % (part, )) - else: - # Object supports __getitem__, assume custom indexing + # Else the object is a mapping or supports __getitem__(so assume custom indexing) + try: return doc[part] + except KeyError: + raise JsonPointerException("member '%s' not found in %s" % (part, doc)) + + def contains(self, ptr): """ Returns True if self contains the given ptr """ return len(self.parts) > len(ptr.parts) and \ diff --git a/tests.py b/tests.py index 3bec626..246b507 100755 --- a/tests.py +++ b/tests.py @@ -277,7 +277,8 @@ class AltTypesTests(unittest.TestCase): def test_mock_dict_raises_key_error(self): doc = self.mdict - self.assertRaises(KeyError, resolve_pointer, doc, '/foo') + self.assertRaises(JsonPointerException, resolve_pointer, doc, '/foo') + self.assertRaises(JsonPointerException, resolve_pointer, doc, '/root/1/2/3/4') -- cgit v1.2.1 From 2ca270f01e7667366800e5648c2561d7072dd0e9 Mon Sep 17 00:00:00 2001 From: kafkaf- Date: Fri, 14 Nov 2014 16:19:32 +0200 Subject: Removed redundent assertion(part of it) --- jsonpointer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jsonpointer.py b/jsonpointer.py index 06d2cb7..e4c407d 100644 --- a/jsonpointer.py +++ b/jsonpointer.py @@ -223,7 +223,7 @@ class JsonPointer(object): part = self.get_part(doc, part) - assert (type(doc) in (dict, list) or hasattr(doc, '__getitem__')), "invalid document type %s" % (type(doc),) + assert hasattr(doc, '__getitem__'), "invalid document type %s" % (type(doc),) if isinstance(doc, Sequence): if part == '-': -- cgit v1.2.1