-
Notifications
You must be signed in to change notification settings - Fork 95
Add option to generate test
operations in diff
#154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
2cb66b9
597b76e
13e9ab0
35734fb
e1de7e4
821ed0a
ee5040f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -157,7 +157,7 @@ def apply_patch(doc, patch, in_place=False, pointer_cls=JsonPointer): | |||||
return patch.apply(doc, in_place) | ||||||
|
||||||
|
||||||
def make_patch(src, dst, pointer_cls=JsonPointer): | ||||||
def make_patch(src, dst, generate_test_ops=False, pointer_cls=JsonPointer): | ||||||
"""Generates patch by comparing two document objects. Actually is | ||||||
a proxy to :meth:`JsonPatch.from_diff` method. | ||||||
|
||||||
|
@@ -170,6 +170,12 @@ def make_patch(src, dst, pointer_cls=JsonPointer): | |||||
:param pointer_cls: JSON pointer class to use. | ||||||
:type pointer_cls: Type[JsonPointer] | ||||||
|
||||||
:param generate_test_ops: While :const:`True` generate test operations | ||||||
capturing previous values of `replace`/`remove` | ||||||
operations. By default do not generate these | ||||||
operations. | ||||||
:type generate_test_ops: bool | ||||||
|
||||||
>>> src = {'foo': 'bar', 'numbers': [1, 3, 4, 8]} | ||||||
>>> dst = {'baz': 'qux', 'numbers': [1, 4, 7]} | ||||||
>>> patch = make_patch(src, dst) | ||||||
|
@@ -178,7 +184,7 @@ def make_patch(src, dst, pointer_cls=JsonPointer): | |||||
True | ||||||
""" | ||||||
|
||||||
return JsonPatch.from_diff(src, dst, pointer_cls=pointer_cls) | ||||||
return JsonPatch.from_diff(src, dst, generate_test_ops=generate_test_ops, pointer_cls=pointer_cls) | ||||||
|
||||||
|
||||||
class PatchOperation(object): | ||||||
|
@@ -475,6 +481,11 @@ def apply(self, obj): | |||||
|
||||||
return obj | ||||||
|
||||||
def _on_undo_add(self, path, key): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These empty methods Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
return key | ||||||
|
||||||
def _on_undo_remove(self, path, key): | ||||||
return key | ||||||
|
||||||
class CopyOperation(PatchOperation): | ||||||
""" Copies an object property or an array element to a new location """ | ||||||
|
@@ -628,7 +639,7 @@ def from_string(cls, patch_str, loads=None, pointer_cls=JsonPointer): | |||||
|
||||||
@classmethod | ||||||
def from_diff( | ||||||
cls, src, dst, optimization=True, dumps=None, | ||||||
cls, src, dst, generate_test_ops=False, dumps=None, | ||||||
pointer_cls=JsonPointer, | ||||||
): | ||||||
"""Creates JsonPatch instance based on comparison of two document | ||||||
|
@@ -641,6 +652,12 @@ def from_diff( | |||||
:param dst: Data source document object. | ||||||
:type dst: dict | ||||||
|
||||||
:param generate_test_ops: While :const:`True` generate test operations | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same grammatical error as in the
Suggested change
Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
capturing previous values of `replace`/`remove` | ||||||
operations. By default do not generate these | ||||||
operations. | ||||||
:type generate_test_ops: bool | ||||||
|
||||||
:param dumps: A function of one argument that produces a serialized | ||||||
JSON string. | ||||||
:type dumps: function | ||||||
|
@@ -658,7 +675,7 @@ def from_diff( | |||||
True | ||||||
""" | ||||||
json_dumper = dumps or cls.json_dumper | ||||||
builder = DiffBuilder(src, dst, json_dumper, pointer_cls=pointer_cls) | ||||||
builder = DiffBuilder(src, dst, json_dumper, generate_test_ops=generate_test_ops, pointer_cls=pointer_cls) | ||||||
builder._compare_values('', None, src, dst) | ||||||
ops = list(builder.execute()) | ||||||
return cls(ops, pointer_cls=pointer_cls) | ||||||
|
@@ -711,9 +728,10 @@ def _get_operation(self, operation): | |||||
|
||||||
class DiffBuilder(object): | ||||||
|
||||||
def __init__(self, src_doc, dst_doc, dumps=json.dumps, pointer_cls=JsonPointer): | ||||||
def __init__(self, src_doc, dst_doc, dumps=json.dumps, generate_test_ops=False, pointer_cls=JsonPointer): | ||||||
self.dumps = dumps | ||||||
self.pointer_cls = pointer_cls | ||||||
self.generate_test_ops = generate_test_ops | ||||||
self.index_storage = [{}, {}] | ||||||
self.index_storage2 = [[], []] | ||||||
self.__root = root = [] | ||||||
|
@@ -801,6 +819,11 @@ def _item_added(self, path, key, item): | |||||
for v in self.iter_from(index): | ||||||
op.key = v._on_undo_remove(op.path, op.key) | ||||||
|
||||||
if self.generate_test_ops: | ||||||
prev_op_index = index[0] | ||||||
if isinstance(prev_op_index[2], TestOperation): | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [nitpick] The code accesses Copilot uses AI. Check for mistakes. Positive FeedbackNegative Feedback |
||||||
self.remove(prev_op_index) | ||||||
|
||||||
self.remove(index) | ||||||
if op.location != _path_join(path, key): | ||||||
new_op = MoveOperation({ | ||||||
|
@@ -819,6 +842,13 @@ def _item_added(self, path, key, item): | |||||
self.store_index(item, new_index, _ST_ADD) | ||||||
|
||||||
def _item_removed(self, path, key, item): | ||||||
if self.generate_test_ops: | ||||||
test_index = self.insert(TestOperation({ | ||||||
'op': 'test', | ||||||
'path': _path_join(path, key), | ||||||
'value': item, | ||||||
}, pointer_cls=self.pointer_cls)) | ||||||
|
||||||
new_op = RemoveOperation({ | ||||||
'op': 'remove', | ||||||
'path': _path_join(path, key), | ||||||
|
@@ -844,14 +874,25 @@ def _item_removed(self, path, key, item): | |||||
'path': op.location, | ||||||
}, pointer_cls=self.pointer_cls) | ||||||
new_index[2] = new_op | ||||||
if self.generate_test_ops: | ||||||
self.remove(test_index) | ||||||
|
||||||
else: | ||||||
self.remove(new_index) | ||||||
if self.generate_test_ops: | ||||||
self.remove(test_index) | ||||||
|
||||||
else: | ||||||
self.store_index(item, new_index, _ST_REMOVE) | ||||||
|
||||||
def _item_replaced(self, path, key, item): | ||||||
def _item_replaced(self, path, key, item, old_item): | ||||||
if self.generate_test_ops: | ||||||
self.insert(TestOperation({ | ||||||
'op': 'test', | ||||||
'path': _path_join(path, key), | ||||||
'value': old_item, | ||||||
}, pointer_cls=self.pointer_cls)) | ||||||
|
||||||
self.insert(ReplaceOperation({ | ||||||
'op': 'replace', | ||||||
'path': _path_join(path, key), | ||||||
|
@@ -921,7 +962,7 @@ def _compare_values(self, path, key, src, dst): | |||||
return | ||||||
|
||||||
else: | ||||||
self._item_replaced(path, key, dst) | ||||||
self._item_replaced(path, key, dst, src) | ||||||
|
||||||
|
||||||
def _path_join(path, key): | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring uses 'While :const:
True
' which is grammatically incorrect. It should be 'When :const:True
' or 'If :const:True
'.Copilot uses AI. Check for mistakes.