Skip to content

Commit

Permalink
Add collection_diff util
Browse files Browse the repository at this point in the history
  • Loading branch information
leplatrem committed Nov 19, 2024
1 parent 4d20df4 commit 654ca6d
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/kinto_http/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,21 @@ def records_equal(a, b):
ac = {k: v for k, v in a.items() if k not in ignore_fields}
bc = {k: v for k, v in b.items() if k not in ignore_fields}
return ac == bc


def collection_diff(src, dest):
"""
Compare two lists of records.
"""
dest_by_id = {r["id"]: r for r in dest}
to_create = []
to_update = []
for r in src:
record = dest_by_id.pop(r["id"], None)
if record is None:
to_create.append(r)
elif not records_equal(r, record):
r.pop("last_modified", None)
to_update.append((record, r))
to_delete = list(dest_by_id.values())
return to_create, to_update, to_delete
58 changes: 58 additions & 0 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,61 @@ def test_records_equal_only_ignored_fields():
a = {"last_modified": 123, "schema": "v1"}
b = {"last_modified": 456, "schema": "v2"}
assert utils.records_equal(a, b)


def test_collection_diff_create():
src = [{"id": 1, "name": "Alice"}]
dest = []
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == [{"id": 1, "name": "Alice"}]
assert to_update == []
assert to_delete == []


def test_collection_diff_update():
src = [{"id": 1, "name": "Alice"}]
dest = [{"id": 1, "name": "Bob"}]
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == []
assert to_update == [({"id": 1, "name": "Bob"}, {"id": 1, "name": "Alice"})]
assert to_delete == []


def test_collection_diff_delete():
src = []
dest = [{"id": 1, "name": "Alice"}]
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == []
assert to_update == []
assert to_delete == [{"id": 1, "name": "Alice"}]


def test_collection_diff_mixed():
src = [{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}, {"id": 3, "name": "Charlie"}]
dest = [
{"id": 2, "name": "Bob"},
{"id": 3, "name": "CharlieUpdated"},
{"id": 4, "name": "Dave"},
]
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == [{"id": 1, "name": "Alice"}]
assert to_update == [({"id": 3, "name": "CharlieUpdated"}, {"id": 3, "name": "Charlie"})]
assert to_delete == [{"id": 4, "name": "Dave"}]


def test_collection_diff_no_changes():
src = [{"id": 1, "name": "Alice"}]
dest = [{"id": 1, "name": "Alice"}]
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == []
assert to_update == []
assert to_delete == []


def test_collection_diff_empty_collections():
src = []
dest = []
to_create, to_update, to_delete = utils.collection_diff(src, dest)
assert to_create == []
assert to_update == []
assert to_delete == []

0 comments on commit 654ca6d

Please sign in to comment.