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)}