diff --git a/jaydiff/__init__.py b/jaydiff/__init__.py index 865f0e4..e69de29 100644 --- a/jaydiff/__init__.py +++ b/jaydiff/__init__.py @@ -1,4 +0,0 @@ -from diff.diff import ( - jay_diff_add, jay_diff_del, jay_diff_upd, jay_diff_upd_add, - jay_diff_full, jay_merge_add, jay_merge_delete, jay_merge_update, jay_merge_full, -) diff --git a/tests/test_jay_diff.py b/tests/test_jay_diff.py index 050df9f..aba7ed2 100644 --- a/tests/test_jay_diff.py +++ b/tests/test_jay_diff.py @@ -2,305 +2,304 @@ import pytest from copy import deepcopy -from diff import ( - jay_diff_add, jay_diff_del, jay_diff_upd, jay_diff_upd_add, - jay_diff_full, jay_merge_add, jay_merge_delete, jay_merge_update, jay_merge_full, -) +from jaydiff.diff import diff_full, diff_add, diff_del, diff_upd, diff_upd_add +from jaydiff.merge import merge_add, merge_delete, merge_update, merge_full -# ── jay_diff_add ────────────────────────────────────────────────────────────── + +# ── diff_add ────────────────────────────────────────────────────────────── class TestJayDiffAdd: def test_add_to_empty(self): - assert jay_diff_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ + assert diff_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}} def test_no_new_keys(self): - assert jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}) == {} def test_old_has_extra_keys(self): - assert jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, + assert diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}) == {} def test_one_new_key(self): - assert jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}) == {'d': 'icecream'} def test_new_key_among_overlap(self): - assert jay_diff_add({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, + assert diff_add({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}) == {'b': 'fries'} def test_nested_new_key(self): - assert jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, + assert diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}}) == {'c': {'f': 'coffee'}} def test_nested_no_new_keys(self): - assert jay_diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}) == {} -# ── jay_diff_del ────────────────────────────────────────────────────────────── +# ── diff_del ────────────────────────────────────────────────────────────── class TestJayDiffDel: def test_one_deleted_key(self): - assert jay_diff_del({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, + assert diff_del({'a': 'hamburger', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}) == {'d': 'icecream'} def test_no_deleted_keys_same_values(self): - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}) == {} def test_no_deleted_keys_different_values(self): - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}) == {} def test_key_absent_from_new(self): - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries'}) == {'c': 'pepsi'} def test_nested_deleted_key(self): # 'c' is absent from _new → None signals "delete entire key" - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}) == {'c': None} def test_nested_partial_delete(self): - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}) == {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}} def test_nested_no_delete_different_value(self): - assert jay_diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_del({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}) == {} -# ── jay_diff_upd ────────────────────────────────────────────────────────────── +# ── diff_upd ────────────────────────────────────────────────────────────── class TestJayDiffUpd: def test_multiple_updates(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'potatoes'}) == {'a': 'hotdog', 'b': 'potatoes'} def test_nested_update(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi'}}) == {'c': {'e': 'pepsi'}} def test_one_update(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'fries'}) == {'a': 'hotdog'} def test_no_update_new_key_ignored(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}) == {'c': 'coke'} def test_nested_no_update_new_subkey_ignored(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}}, {'c': {'f': 'coffee'}}) == {} def test_nested_update_one_of_two(self): - assert jay_diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'pepsi', 'f': 'coffee'}}) \ == {'c': {'e': 'pepsi'}} -# ── jay_diff_upd_add ────────────────────────────────────────────────────────── +# ── diff_upd_add ────────────────────────────────────────────────────────── class TestJayDiffUpdAdd: def test_update_and_add(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}) \ == {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'} def test_nested_update_and_add(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b': 'potatoes'}) \ == {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}} def test_update_only(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'fries'}) == {'a': 'hotdog'} def test_nested_update_and_new_subkey(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}) \ == {'c': {'e': 'pepsi', 'h': 'cake'}} def test_add_new_top_and_update(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}) \ == {'c': 'coke', 'd': 'icecream'} def test_identical(self): - assert jay_diff_upd_add({'a': 'hamburger', 'b': 'fries'}, + assert diff_upd_add({'a': 'hamburger', 'b': 'fries'}, {'a': 'hamburger', 'b': 'fries'}) == {} -# ── jay_diff_full (combine_upd_add=False) ───────────────────────────────────── +# ── diff_full (combine_upd_add=False) ───────────────────────────────────── class TestJayDiffFullSeparate: F = False def test_add_all(self): - assert jay_diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, self.F) \ + assert diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, self.F) \ == {'add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}} def test_update_one(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, self.F) \ == {'update': {'c': 'coke'}} def test_delete_one(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, self.F) \ == {'delete': {'d': 'icecream'}} def test_add_delete_update(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}, self.F) \ == {'add': {'d': 'icecream'}, 'delete': {'b': 'fries'}, 'update': {'c': 'coke'}} def test_identical(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, self.F) == {} def test_delete_nested(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, self.F) \ == {'delete': {'c': None}} def test_nested_partial_delete(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, self.F) \ == {'delete': {'c': {'e': 'coke'}}} def test_update_and_delete(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'potatoes'}, self.F) \ == {'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}} def test_nested_add_delete_update(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'potatoes', 'd': 'icecream'}, self.F) \ == {'add': {'d': 'icecream'}, 'delete': {'c': None}, 'update': {'a': 'hotdog', 'b': 'potatoes'}} -# ── jay_diff_full (combine_upd_add=True) ────────────────────────────────────── +# ── diff_full (combine_upd_add=True) ────────────────────────────────────── class TestJayDiffFullCombined: T = True def test_add_all(self): - assert jay_diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, self.T) \ + assert diff_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, self.T) \ == {'update_add': {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}} def test_update_one(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, self.T) \ == {'update_add': {'c': 'coke'}} def test_delete_one(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, self.T) \ == {'delete': {'d': 'icecream'}} def test_delete_and_update_add(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'}, self.T) \ == {'delete': {'b': 'fries'}, 'update_add': {'c': 'coke', 'd': 'icecream'}} def test_identical(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, self.T) == {} def test_delete_nested(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries'}, self.T) \ == {'delete': {'c': None}} def test_update_and_delete_nested(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hotdog', 'b': 'potatoes'}, self.T) \ == {'delete': {'c': None}, 'update_add': {'a': 'hotdog', 'b': 'potatoes'}} def test_nested_update_add_and_delete(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}, 'b': 'potatoes'}, self.T) \ == {'delete': {'a': 'hamburger', 'c': {'f': 'coffee'}}, 'update_add': {'b': 'potatoes', 'c': {'e': 'pepsi', 'g': 'tea', 'h': 'cake'}}} def test_nested_add_subkey(self): - assert jay_diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert diff_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}}, self.T) \ == {'update_add': {'c': {'e': 'pepsi', 'h': 'cake'}}} -# ── jay_merge_* ─────────────────────────────────────────────────────────────── +# ── merge_* ─────────────────────────────────────────────────────────────── class TestJayMerge: def test_merge_add_to_empty(self): - assert jay_merge_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ + assert merge_add({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}} def test_merge_add_new_key(self): - assert jay_merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'d': 'icecream'}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd': 'icecream'} def test_merge_add_existing_unchanged(self): - assert jay_merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}, 'd': 'icecream'}, + assert merge_add({'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}, 'd': 'icecream'}, {'d': 'icecream'}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}, 'd': 'icecream'} def test_merge_delete_top_key(self): - assert jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd': 'icecream'}, + assert merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}, 'd': 'icecream'}, {'d': 'icecream'}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}} def test_merge_delete_nested_key(self): - assert jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'f': 'coffee'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke'}} def test_merge_delete_nested_leaves_sibling(self): - assert jay_merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert merge_delete({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'c': {'e': 'coke'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}} class TestJayMergeFull: def test_passthrough_when_old_empty(self): - assert jay_merge_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ + assert merge_full({}, {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}} def test_empty_diff_unchanged(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {}) \ + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {}) \ == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'} def test_update(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'update': {'c': 'pepsi'}}) \ + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'coke'}, {'update': {'c': 'pepsi'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'} def test_update_add(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update_add': {'c': 'coke'}}) \ + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'update_add': {'c': 'coke'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': 'coke'} def test_delete(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi', 'd': 'icecream'}, {'delete': {'d': 'icecream'}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'} def test_add_delete_update_combined(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': 'pepsi'}, {'add': {'d': 'icecream'}, 'delete': {'b': 'fries'}, 'update': {'c': 'coke'}}) \ == {'a': 'hamburger', 'd': 'icecream', 'c': 'coke'} def test_nested_update_and_delete(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'delete': {'a': 'hamburger', 'b': 'fries', 'c': {'f': 'coffee'}}, 'update': {'c': {'e': 'pepsi'}}}) \ == {'c': {'e': 'pepsi'}} def test_update_add_new_subkey(self): - assert jay_merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, + assert merge_full({'a': 'hamburger', 'b': 'fries', 'c': {'e': 'coke', 'f': 'coffee'}}, {'update_add': {'c': {'e': 'pepsi', 'h': 'cake'}}}) \ == {'a': 'hamburger', 'b': 'fries', 'c': {'e': 'pepsi', 'f': 'coffee', 'h': 'cake'}} @@ -319,7 +318,7 @@ class TestJayMergeFull: delete = {'charging': { 'chargingSettings': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:30Z'}}, 'plugStatus': {'value': {'carCapturedTimestamp': '2024-10-19T05:34:29Z'}}}} - result = jay_merge_full(old, {'update': update, 'add': add, 'delete': delete}) + result = merge_full(old, {'update': update, 'add': add, 'delete': delete}) assert result == old @@ -327,43 +326,43 @@ class TestJayMergeFull: class TestNumericAndScalarTypes: def test_diff_int_value_changed(self): - assert jay_diff_upd({'a': 1, 'b': 2}, {'a': 1, 'b': 3}) == {'b': 3} + assert diff_upd({'a': 1, 'b': 2}, {'a': 1, 'b': 3}) == {'b': 3} def test_diff_float_value_changed(self): - assert jay_diff_upd({'a': 1.0}, {'a': 1.1}) == {'a': 1.1} + assert diff_upd({'a': 1.0}, {'a': 1.1}) == {'a': 1.1} def test_diff_int_unchanged(self): - assert jay_diff_upd({'a': 42}, {'a': 42}) == {} + assert diff_upd({'a': 42}, {'a': 42}) == {} def test_diff_bool_changed(self): - assert jay_diff_upd({'a': True}, {'a': False}) == {'a': False} + assert diff_upd({'a': True}, {'a': False}) == {'a': False} def test_diff_bool_false_to_true(self): - assert jay_diff_upd({'online': False}, {'online': True}) == {'online': True} + assert diff_upd({'online': False}, {'online': True}) == {'online': True} def test_diff_none_value_changed(self): - assert jay_diff_upd({'a': None}, {'a': 'something'}) == {'a': 'something'} + assert diff_upd({'a': None}, {'a': 'something'}) == {'a': 'something'} def test_diff_value_to_none(self): - assert jay_diff_upd({'a': 'something'}, {'a': None}) == {'a': None} + assert diff_upd({'a': 'something'}, {'a': None}) == {'a': None} def test_diff_list_unchanged(self): - assert jay_diff_upd({'a': [1, 2, 3]}, {'a': [1, 2, 3]}) == {} + assert diff_upd({'a': [1, 2, 3]}, {'a': [1, 2, 3]}) == {} def test_diff_list_changed(self): - assert jay_diff_upd({'a': [1, 2]}, {'a': [1, 2, 3]}) == {'a': [1, 2, 3]} + assert diff_upd({'a': [1, 2]}, {'a': [1, 2, 3]}) == {'a': [1, 2, 3]} def test_add_numeric_key(self): - assert jay_diff_add({'a': 1}, {'a': 1, 'b': 2}) == {'b': 2} + assert diff_add({'a': 1}, {'a': 1, 'b': 2}) == {'b': 2} def test_full_combined_numeric(self): old = {'soc': 80, 'range': 300, 'temp': 22.5} new = {'soc': 75, 'range': 280, 'temp': 22.5} - diff = jay_diff_full(old, new) + diff = diff_full(old, new) assert diff == {'update_add': {'soc': 75, 'range': 280}} def test_merge_numeric_update(self): - assert jay_merge_full({'soc': 80, 'range': 300}, {'update_add': {'soc': 75}}) \ + assert merge_full({'soc': 80, 'range': 300}, {'update_add': {'soc': 75}}) \ == {'soc': 75, 'range': 300} @@ -374,27 +373,27 @@ class TestTypeChanges: # A key that was a dict becomes a scalar — upd treats the whole value as changed old = {'a': {'b': 'c'}} new = {'a': 'flat'} - diff = jay_diff_upd(old, new) + diff = diff_upd(old, new) assert diff == {'a': 'flat'} def test_merge_dict_to_scalar(self): old = {'a': {'b': 'c'}, 'x': 1} diff = {'update_add': {'a': 'flat'}} - result = jay_merge_full(old, diff) + result = merge_full(old, diff) assert result == {'a': 'flat', 'x': 1} def test_diff_full_dict_to_scalar_combined(self): old = {'status': {'value': 42}} new = {'status': 'unknown'} - diff = jay_diff_full(old, new) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(old, new) + result = merge_full(deepcopy(old), diff) assert result == new def test_diff_add_new_nested_structure(self): # Key absent in old, present as dict in new — treated as addition old = {'a': 1} new = {'a': 1, 'b': {'c': 2}} - diff = jay_diff_add(old, new) + diff = diff_add(old, new) assert diff == {'b': {'c': 2}} @@ -404,13 +403,13 @@ class TestCompletelyDifferentStructure: def test_all_keys_replaced(self): old = {'a': 1, 'b': 2} new = {'x': 10, 'y': 20} - diff = jay_diff_full(old, new) + diff = diff_full(old, new) assert diff == {'update_add': {'x': 10, 'y': 20}, 'delete': {'a': 1, 'b': 2}} def test_all_keys_replaced_deep(self): old = {'charging': {'state': 'charging', 'power': 11}} new = {'electric_drive': {'range': 300, 'soc': 80}} - diff = jay_diff_full(old, new) + diff = diff_full(old, new) assert diff == { 'update_add': {'electric_drive': {'range': 300, 'soc': 80}}, 'delete': {'charging': None}, @@ -419,51 +418,51 @@ class TestCompletelyDifferentStructure: def test_merge_round_trip_all_keys_replaced(self): old = {'a': 1, 'b': 2} new = {'x': 10, 'y': 20} - diff = jay_diff_full(old, new) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(old, new) + result = merge_full(deepcopy(old), diff) assert result == new def test_diff_disjoint_no_update(self): # No shared keys → no updates, only add/delete old = {'a': 1} new = {'b': 2} - diff = jay_diff_upd(old, new) + diff = diff_upd(old, new) assert diff == {} def test_diff_disjoint_add(self): - assert jay_diff_add({'a': 1}, {'b': 2}) == {'b': 2} + assert diff_add({'a': 1}, {'b': 2}) == {'b': 2} def test_diff_disjoint_del(self): - assert jay_diff_del({'a': 1}, {'b': 2}) == {'a': 1} + assert diff_del({'a': 1}, {'b': 2}) == {'a': 1} # ── Corner cases: empty containers ──────────────────────────────────────────── class TestEmptyContainers: def test_diff_both_empty(self): - assert jay_diff_full({}, {}) == {} + assert diff_full({}, {}) == {} def test_diff_old_empty_new_has_data(self): - diff = jay_diff_full({}, {'a': 1}) + diff = diff_full({}, {'a': 1}) assert diff == {'update_add': {'a': 1}} def test_diff_new_empty_old_has_data(self): - diff = jay_diff_full({'a': 1}, {}) + diff = diff_full({'a': 1}, {}) assert diff == {'delete': {'a': 1}} def test_merge_delete_all_keys(self): - result = jay_merge_full({'a': 1, 'b': 2}, {'delete': {'a': 1, 'b': 2}}) + result = merge_full({'a': 1, 'b': 2}, {'delete': {'a': 1, 'b': 2}}) assert result == {} def test_delete_empty_dict_value(self): # Deleting a key whose value is {} — should not recurse (fixed bug) - result = jay_merge_delete({'a': 'keep', 'b': {}}, {'b': {}}) + result = merge_delete({'a': 'keep', 'b': {}}, {'b': {}}) assert result == {'a': 'keep'} def test_diff_nested_empty_dict(self): old = {'a': {'b': 'c'}} new = {'a': {}} - diff = jay_diff_del(old, new) + diff = diff_del(old, new) assert diff == {'a': {'b': 'c'}} def test_empty_dict_preserved_after_delete_all_subkeys(self): @@ -471,8 +470,8 @@ class TestEmptyContainers: # (not be pruned away). This would break if merge incorrectly prunes empty dicts. old = {'x': {'p': 1, 'q': 2}} new = {'x': {}} - diff = jay_diff_full(old, new) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(old, new) + result = merge_full(deepcopy(old), diff) assert result == new # 'x' must remain as {} @@ -482,19 +481,19 @@ class TestDeepNesting: def test_diff_three_levels(self): old = {'l1': {'l2': {'l3': 'old'}}} new = {'l1': {'l2': {'l3': 'new'}}} - assert jay_diff_upd(old, new) == {'l1': {'l2': {'l3': 'new'}}} + assert diff_upd(old, new) == {'l1': {'l2': {'l3': 'new'}}} def test_merge_three_levels(self): old = {'l1': {'l2': {'l3': 'old', 'keep': 'yes'}}} diff = {'update_add': {'l1': {'l2': {'l3': 'new'}}}} - result = jay_merge_full(deepcopy(old), diff) + result = merge_full(deepcopy(old), diff) assert result == {'l1': {'l2': {'l3': 'new', 'keep': 'yes'}}} def test_diff_full_three_levels(self): old = {'a': {'b': {'c': {'d': 'deep'}}}} new = {'a': {'b': {'c': {'d': 'deeper'}}}} - diff = jay_diff_full(old, new) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(old, new) + result = merge_full(deepcopy(old), diff) assert result == new @@ -515,8 +514,8 @@ class TestRoundTrip: ({'a': 1}, {}), ]) def test_round_trip_combined(self, old, new): - diff = jay_diff_full(deepcopy(old), deepcopy(new), combine_upd_add=True) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(deepcopy(old), deepcopy(new), combine_upd_add=True) + result = merge_full(deepcopy(old), diff) assert result == new @pytest.mark.parametrize("old,new", [ @@ -527,6 +526,6 @@ class TestRoundTrip: ({'a': 1}, {}), ]) def test_round_trip_separate(self, old, new): - diff = jay_diff_full(deepcopy(old), deepcopy(new), combine_upd_add=False) - result = jay_merge_full(deepcopy(old), diff) + diff = diff_full(deepcopy(old), deepcopy(new), combine_upd_add=False) + result = merge_full(deepcopy(old), diff) assert result == new \ No newline at end of file diff --git a/tests/test_jay_diff_real_data.py b/tests/test_jay_diff_real_data.py index 2452484..f95e75a 100644 --- a/tests/test_jay_diff_real_data.py +++ b/tests/test_jay_diff_real_data.py @@ -14,7 +14,7 @@ import pathlib import pytest -from diff import jay_diff_full, jay_merge_full +from jaydiff import jay_diff_full, jay_merge_full DATA_DIR = pathlib.Path(__file__).parent / "data"