| from sync.delta import compute_content_hash, compute_delta, build_state | |
| def _paper(id_, title="T", abstract="A"): | |
| return {"id": id_, "title": title, "abstract": abstract, "authors": "X", "venue": "ACL", "year": 2023, "url": "http://x"} | |
| def test_compute_content_hash_is_stable(): | |
| p = _paper("p1") | |
| assert compute_content_hash(p) == compute_content_hash(_paper("p1")) | |
| def test_compute_content_hash_changes_with_content(): | |
| assert compute_content_hash(_paper("p1", title="A")) != compute_content_hash(_paper("p1", title="B")) | |
| def test_compute_delta_detects_new_paper(): | |
| current = [_paper("p1")] | |
| result = compute_delta(current, last_state={}) | |
| assert [p["id"] for p in result.new_or_changed] == ["p1"] | |
| assert result.removed_ids == [] | |
| def test_compute_delta_detects_changed_paper(): | |
| old_hash = compute_content_hash(_paper("p1", title="Old")) | |
| current = [_paper("p1", title="New")] | |
| result = compute_delta(current, last_state={"p1": old_hash}) | |
| assert [p["id"] for p in result.new_or_changed] == ["p1"] | |
| def test_compute_delta_skips_unchanged_paper(): | |
| p = _paper("p1") | |
| current = [p] | |
| result = compute_delta(current, last_state={"p1": compute_content_hash(p)}) | |
| assert result.new_or_changed == [] | |
| def test_compute_delta_detects_removed_paper(): | |
| current = [] | |
| result = compute_delta(current, last_state={"p1": "somehash"}) | |
| assert result.removed_ids == ["p1"] | |
| def test_build_state_maps_id_to_hash(): | |
| p = _paper("p1") | |
| state = build_state([p]) | |
| assert state == {"p1": compute_content_hash(p)} | |