summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Waldon <bcwaldon@gmail.com>2012-11-26 11:41:14 -0500
committerBrian Waldon <bcwaldon@gmail.com>2012-11-26 12:23:12 -0500
commitc265073862706e48965b0e6312e281fcb726d8fa (patch)
treef4280416e7095e390d3dbf93d94b351f6c8167fc
parentec39437bfd7a710e5ac5d4e4ca3236391c90998a (diff)
downloadwarlock-c265073862706e48965b0e6312e281fcb726d8fa.tar.gz
Use jsonpatch to provide a JSON patch document
The attribute "patch" of a model now returns a string representing all of the operations that have occurred on the model since it was created in JSON patch form.
-rw-r--r--requirements.txt1
-rw-r--r--test/test_core.py44
-rw-r--r--warlock/core.py7
3 files changed, 52 insertions, 0 deletions
diff --git a/requirements.txt b/requirements.txt
index 35c7022..bd9b4f7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1 +1,2 @@
jsonschema>=0.7,<1
+jsonpatch==0.10
diff --git a/test/test_core.py b/test/test_core.py
index b4e1627..5226794 100644
--- a/test/test_core.py
+++ b/test/test_core.py
@@ -142,3 +142,47 @@ class TestCore(unittest.TestCase):
self.assertEqual(sweden.changes, {'name': 'Finland'})
sweden['name'] = 'Norway'
self.assertEqual(sweden.changes, {'name': 'Norway'})
+
+ def test_patch_no_changes(self):
+ Country = warlock.model_factory(fixture)
+ sweden = Country(name='Sweden', population=9379116)
+ self.assertEqual(sweden.patch, '[]')
+
+ def test_patch_alter_value(self):
+ Country = warlock.model_factory(fixture)
+ sweden = Country(name='Sweden', population=9379116)
+ sweden['name'] = 'Finland'
+ self.assertEqual(
+ sweden.patch,
+ '[{"path": "/name", "value": "Finland", "op": "replace"}]')
+
+ def test_patch_drop_attribute(self):
+ Country = warlock.model_factory(fixture)
+ sweden = Country(name='Sweden', population=9379116)
+ del sweden['name']
+ self.assertEqual(sweden.patch, '[{"path": "/name", "op": "remove"}]')
+
+ def test_patch_reduce_operations(self):
+ Country = warlock.model_factory(fixture)
+ sweden = Country(name='Sweden', population=9379116)
+
+ sweden['name'] = 'Finland'
+ self.assertEqual(
+ sweden.patch,
+ '[{"path": "/name", "value": "Finland", "op": "replace"}]')
+
+ sweden['name'] = 'Norway'
+ self.assertEqual(
+ sweden.patch,
+ '[{"path": "/name", "value": "Norway", "op": "replace"}]')
+
+ def test_patch_multiple_operations(self):
+ Country = warlock.model_factory(fixture)
+ sweden = Country(name='Sweden', population=9379116)
+
+ sweden['name'] = 'Finland'
+ sweden['population'] = 5387000
+ self.assertEqual(
+ sweden.patch,
+ '[{"path": "/name", "value": "Finland", "op": "replace"}, '
+ '{"path": "/population", "value": 5387000, "op": "replace"}]')
diff --git a/warlock/core.py b/warlock/core.py
index 38cb854..9c3cdf7 100644
--- a/warlock/core.py
+++ b/warlock/core.py
@@ -3,6 +3,7 @@
import copy
import jsonschema
+import jsonpatch
class InvalidOperation(RuntimeError):
@@ -43,6 +44,7 @@ def model_factory(schema):
dict.__init__(self, d)
self.__dict__['changes'] = {}
+ self.__dict__['__original__'] = copy.deepcopy(d)
def __getattr__(self, key):
try:
@@ -118,5 +120,10 @@ def model_factory(schema):
def changes(self):
return copy.deepcopy(self.__dict__['changes'])
+ @property
+ def patch(self):
+ original = self.__dict__['__original__']
+ return jsonpatch.make_patch(original, dict(self)).to_string()
+
Model.__name__ = str(schema['name'])
return Model