From d38254bd07df87feba1eaa92ece1674fe52f1fa9 Mon Sep 17 00:00:00 2001 From: florian <f.spreckelsen@inidscale.com> Date: Wed, 26 Oct 2022 13:26:40 +0200 Subject: [PATCH] TST: Add failing test for comparison of referenced entities --- unittests/test_apiutils.py | 109 ++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 7 deletions(-) diff --git a/unittests/test_apiutils.py b/unittests/test_apiutils.py index 2ebdf95a..d86b7523 100644 --- a/unittests/test_apiutils.py +++ b/unittests/test_apiutils.py @@ -30,7 +30,7 @@ import pytest import caosdb as db import caosdb.apiutils from caosdb.apiutils import (apply_to_ids, compare_entities, create_id_query, - resolve_reference, merge_entities) + empty_diff, resolve_reference, merge_entities) from caosdb.common.models import SPECIAL_ATTRIBUTES @@ -272,8 +272,10 @@ def test_copy_entities(): for i in [0, 1]: assert c.properties[i] is not r.properties[i] for special in SPECIAL_ATTRIBUTES: - assert getattr(c.properties[i], special) == getattr(r.properties[i], special) - assert c.get_importance(c.properties[i]) == r.get_importance(r.properties[i]) + assert getattr(c.properties[i], special) == getattr( + r.properties[i], special) + assert c.get_importance( + c.properties[i]) == r.get_importance(r.properties[i]) def test_merge_entities(): @@ -326,10 +328,12 @@ def test_merge_bug_109(): assert r_a.get_property("test_bug_property").value == [18, 19] assert "<Value>18</Value>\n <Value>19</Value>" in str(r_b) - assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str(r_b) + assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str( + r_b) assert "<Value>18</Value>\n <Value>19</Value>" in str(r_a) - assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str(r_a) + assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str( + r_a) @pytest.mark.xfail @@ -349,7 +353,98 @@ def test_bug_109(): assert r_a.get_property("test_bug_property").value == [18, 19] assert "<Value>18</Value>\n <Value>19</Value>" in str(r_b) - assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str(r_b) + assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str( + r_b) assert "<Value>18</Value>\n <Value>19</Value>" in str(r_a) - assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str(r_a) + assert "<Value>18</Value>\n <Value>19</Value>\n <Value>18</Value>\n <Value>19</Value>" not in str( + r_a) + + +def test_wrong_merge_conflict_reference(): + """Test a wrongly detected merge conflict in case of two records referencing + two different, but identical objects. + + """ + # Two identical license records will be referenced from both records to be + # merged + license_rt = db.RecordType(name="license") + license_rec_a = db.Record(name="CC-BY-3.0").add_parent(license_rt) + license_rec_b = db.Record(name="CC-BY-3.0").add_parent(license_rt) + + # two referencing records + dataset_rt = db.RecordType(name="Dataset") + title_prop = db.Property(name="title", datatype=db.TEXT) + doi_prop = db.Property(name="DOI", datatype=db.TEXT) + rec_a = db.Record().add_parent(dataset_rt) + rec_a.add_property(name=license_rt.name, + datatype=license_rt.name, value=license_rec_a) + rec_a.add_property(name=title_prop.name, value="Some dataset title") + + rec_b = db.Record().add_parent(dataset_rt) + rec_b.add_property(name=license_rt.name, + datatype=license_rt.name, value=license_rec_b) + rec_b.add_property(name=doi_prop.name, value="https://doi.org/12345.678") + + print(compare_entities(rec_a, rec_b)) + print(compare_entities(license_rec_a, license_rec_b)) + print(license_rec_b == license_rec_a) + merge_entities(rec_a, rec_b) + assert rec_a.get_property(license_rt.name) is not None + assert rec_a.get_property(license_rt.name).value is not None + assert isinstance(rec_a.get_property(license_rt.name).value, db.Record) + + +def test_empty_diff(): + + rec_a = db.Record(name="A") + rec_b = db.Record(name="B") + + assert empty_diff(rec_a, rec_a) + assert not empty_diff(rec_a, rec_b) + + rec_a.add_parent(name="RT") + rec_b.add_parent(name="RT") + assert empty_diff(rec_a, rec_a) + assert not empty_diff(rec_a, rec_b) + + rec_b.name = "A" + assert empty_diff(rec_a, rec_b) + + rec_a.add_property(name="some_prop", value=1) + assert not empty_diff(rec_a, rec_b) + + rec_b.add_property(name="some_prop", value=1) + assert empty_diff(rec_a, rec_b) + + rec_b.get_property("some_prop").value = 2 + assert not empty_diff(rec_a, rec_b) + + rec_b.get_property("some_prop").value = 1 + rec_b.add_property(name="some_other_prop", value="Test") + assert not empty_diff(rec_a, rec_b) + + rec_a.add_property(name="some_other_prop", value="Test") + assert empty_diff(rec_a, rec_b) + + # reference identical records, but different Python Record objects + ref_rec_a = db.Record(name="Ref").add_parent(name="RefType") + ref_rec_b = db.Record(name="Ref").add_parent(name="RefType") + rec_a.add_property(name="RefType", datatype="RefType", value=ref_rec_a) + rec_b.add_property(name="RefType", datatype="RefType", value=ref_rec_b) + # the default is `compare_referenced_records=False`, so the diff shouldn't + # be empty (different Python objects are referenced.) + assert not empty_diff(rec_a, rec_b) + # when looking into the referenced record, the diffs should be empty again + assert empty_diff(rec_a, rec_b, compare_referenced_records=True) + + # The same for lists of references + rec_a.remove_property("RefType") + rec_b.remove_property("RefType") + assert empty_diff(rec_a, rec_b) + rec_a.add_property(name="RefType", datatype=db.LIST( + "RefType"), value=[ref_rec_a, ref_rec_a]) + rec_b.add_property(name="RefType", datatype=db.LIST( + "RefType"), value=[ref_rec_b, ref_rec_b]) + assert not empty_diff(rec_a, rec_b) + assert empty_diff(rec_a, rec_b, compare_referenced_records=True) -- GitLab