Skip to content

Commit 6f60dd3

Browse files
Merge pull request #78 from apdavison/improve-regression-tests
Run regression tests with both "v4" and "latest"
2 parents 2248509 + fca3443 commit 6f60dd3

File tree

4 files changed

+107
-50
lines changed

4 files changed

+107
-50
lines changed

pipeline/src/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def validate(self, ignore=None):
161161
162162
Returns a dict containing information about any validation failures.
163163
"""
164-
return self._validate(ignore=ignore)
164+
return dict(self._validate(ignore=ignore))
165165

166166
def _validate(self, ignore=None, seen=None):
167167
# this is implemented as an internal method so that the

pipeline/src/properties.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def validate(self, value, ignore=None, seen=None):
131131
if isinstance(item, Link):
132132
item_type = f"value contains a link to {item.allowed_types}"
133133
else:
134-
item_type = f"value contains {type(item)}"
134+
item_type = f"value contains {type(item).__name__}"
135135
failures["type"].append(
136136
f"{self.name}: Expected {', '.join(t.__name__ for t in self.types)}, " + item_type
137137
)
@@ -166,7 +166,7 @@ def validate(self, value, ignore=None, seen=None):
166166
if isinstance(value, Link):
167167
value_type = f"value contains a link to {value.allowed_types}"
168168
else:
169-
value_type = f"value contains {type(value)}"
169+
value_type = f"value contains {type(value).__name__}"
170170
failures["type"].append(
171171
f"{self.name}: Expected {', '.join(t.__name__ for t in self.types)}, " + value_type
172172
)

pipeline/tests/test_regressions.py

Lines changed: 77 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,45 @@
11
from datetime import date
22
import json
33
import os
4+
5+
import pytest
6+
47
from openminds import Collection, IRI
5-
from openminds.v4 import core as omcore
8+
import openminds.latest
9+
import openminds.v4
610
from utils import build_fake_node
711

812

9-
def test_issue_0002():
13+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
14+
def test_issue_0002(om):
1015
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/2
1116
# @type should not be given as a list but as a string
1217

13-
node = build_fake_node(omcore.Person)
18+
node = build_fake_node(om.core.Person)
1419
data = node.to_jsonld()
1520
assert data["@type"] == "https://openminds.om-i.org/types/Person"
1621

1722

18-
def test_issue_0003():
23+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
24+
def test_issue_0003(om):
1925
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/3
2026
# validate() does not complain about direct entries that should be lists
2127

2228
# we address this by always wrapping a single item in a list in such cases
2329

24-
some_file = omcore.File(
30+
some_file = om.core.File(
2531
iri=IRI("http://example.com/some_file.txt"),
2632
name="some_file.txt",
2733
)
2834

29-
node1 = omcore.FileArchive(
35+
node1 = om.core.FileArchive(
3036
iri=IRI("http://example.com/archive.zip"),
31-
format=omcore.ContentType(name="application/zip"),
37+
format=om.core.ContentType(name="application/zip"),
3238
source_data=[some_file], # multiple=True, min_items=1
3339
)
34-
node2 = omcore.FileArchive(
40+
node2 = om.core.FileArchive(
3541
iri=IRI("http://example.com/archive.zip"),
36-
format=omcore.ContentType(name="application/zip"),
42+
format=om.core.ContentType(name="application/zip"),
3743
source_data=some_file, # multiple=True, min_items=1
3844
)
3945
# on export, a single item should be wrapped in a list, where the property expects an array
@@ -59,14 +65,15 @@ def test_issue_0003():
5965
)
6066

6167

62-
def test_issue0005():
68+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
69+
def test_issue0005(om):
6370
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/5
6471
# validate() does not complain about list/tuple entries that should be a direct single entry
65-
uni1 = omcore.Organization(full_name="University of This Place")
66-
person = omcore.Person(
72+
uni1 = om.core.Organization(full_name="University of This Place")
73+
person = om.core.Person(
6774
given_name="A",
6875
family_name="Professor",
69-
affiliations=[omcore.Affiliation(member_of=uni1, end_date=(2023, 9, 30))],
76+
affiliations=[om.core.Affiliation(member_of=uni1, end_date=(2023, 9, 30))],
7077
)
7178
failures = person.validate()
7279
assert len(failures) == 1
@@ -76,16 +83,17 @@ def test_issue0005():
7683
assert len(failures) == 0
7784

7885

79-
def test_issue0007():
86+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
87+
def test_issue0007(om):
8088
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/7
8189
# Instances of embedded types with value type "array" are not correctly resolved for saving and causing an error.
8290

83-
person = omcore.Person(given_name="A", family_name="Professor", id="_:001")
84-
uni1 = omcore.Organization(full_name="University of This Place", id="_:002")
85-
uni2 = omcore.Organization(full_name="University of That Place", id="_:003")
91+
person = om.core.Person(given_name="A", family_name="Professor", id="_:001")
92+
uni1 = om.core.Organization(full_name="University of This Place", id="_:002")
93+
uni2 = om.core.Organization(full_name="University of That Place", id="_:003")
8694
person.affiliations = [
87-
omcore.Affiliation(member_of=uni1),
88-
omcore.Affiliation(member_of=uni2),
95+
om.core.Affiliation(member_of=uni1),
96+
om.core.Affiliation(member_of=uni2),
8997
]
9098

9199
actual = person.to_jsonld(include_empty_properties=False, embed_linked_nodes=False, with_context=True)
@@ -149,17 +157,18 @@ def test_issue0007():
149157
assert saved_data == expected_saved_data
150158

151159

152-
def test_issue0008():
160+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
161+
def test_issue0008(om):
153162
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/8
154163
# The instance of linked types in instances of embedded types are integrated as embedded not linked
155164
# (example: person -> affiliations (embedded) -> organization (linked))
156165

157-
uni1 = omcore.Organization(full_name="University of This Place", id="_:001")
158-
person = omcore.Person(
166+
uni1 = om.core.Organization(full_name="University of This Place", id="_:001")
167+
person = om.core.Person(
159168
id="_:002",
160169
given_name="A",
161170
family_name="Professor",
162-
affiliations=[omcore.Affiliation(member_of=uni1, end_date=date(2023, 9, 30))],
171+
affiliations=[om.core.Affiliation(member_of=uni1, end_date=date(2023, 9, 30))],
163172
)
164173
actual = person.to_jsonld(include_empty_properties=False, embed_linked_nodes=False, with_context=True)
165174
expected = {
@@ -179,14 +188,15 @@ def test_issue0008():
179188
assert actual == expected
180189

181190

182-
def test_issue0026():
191+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
192+
def test_issue0026(om):
183193
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/26
184194
# When reading a JSON-LD file, the attributes of LinkedMetadata nodes
185195
# inside EmbeddedMetadata nodes are not set properly
186196

187-
uni1 = omcore.Organization(full_name="University of This Place", id="_:uthisp")
188-
person = omcore.Person(
189-
given_name="A", family_name="Professor", affiliations=[omcore.Affiliation(member_of=uni1)], id="_:ap"
197+
uni1 = om.core.Organization(full_name="University of This Place", id="_:uthisp")
198+
person = om.core.Person(
199+
given_name="A", family_name="Professor", affiliations=[om.core.Affiliation(member_of=uni1)], id="_:ap"
190200
)
191201

192202
c = Collection(person)
@@ -196,57 +206,59 @@ def test_issue0026():
196206
output_paths = c.save("issue0026.jsonld", individual_files=False, include_empty_properties=False)
197207

198208
new_collection = Collection()
199-
new_collection.load(*output_paths)
209+
new_collection.load(*output_paths, version=om.__name__.split(".")[1])
200210
os.remove("issue0026.jsonld")
201211

202-
person_again = [item for item in new_collection if isinstance(item, omcore.Person)][0]
212+
person_again = [item for item in new_collection if isinstance(item, om.core.Person)][0]
203213
assert len(person_again.affiliations) == 1
204214
assert person_again.affiliations[0].member_of.full_name == "University of This Place"
205215

206216

207-
def test_issue0023():
217+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
218+
def test_issue0023(om):
208219
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/23
209220
# If a user adds an instance/node to a collection, and then later adds linked types to the instance,
210221
# currently that is not added to the collection
211222

212-
uni1 = omcore.Organization(full_name="University of This Place", id="_:uthisp")
213-
person = omcore.Person(
214-
given_name="A", family_name="Professor", affiliations=[omcore.Affiliation(member_of=uni1)], id="_:ap"
223+
uni1 = om.core.Organization(full_name="University of This Place", id="_:uthisp")
224+
person = om.core.Person(
225+
given_name="A", family_name="Professor", affiliations=[om.core.Affiliation(member_of=uni1)], id="_:ap"
215226
)
216-
dv = omcore.DatasetVersion(full_name="The name of the dataset version", custodians=[person], id="_:dv")
227+
dv = om.core.DatasetVersion(full_name="The name of the dataset version", custodians=[person], id="_:dv")
217228

218229
c = Collection(dv)
219230

220231
# even though we add uni2 and the repository after creating the collection,
221232
# they should be included when we save the collection.
222-
uni2 = omcore.Organization(full_name="University of That Place", id="_:uthatp")
223-
person.affiliations.append(omcore.Affiliation(member_of=uni2))
224-
dv.repository = omcore.FileRepository(iri="http://example.com", id="_:fr")
233+
uni2 = om.core.Organization(full_name="University of That Place", id="_:uthatp")
234+
person.affiliations.append(om.core.Affiliation(member_of=uni2))
235+
dv.repository = om.core.FileRepository(iri="http://example.com", id="_:fr")
225236

226237
output_paths = c.save("issue0023.jsonld", individual_files=False, include_empty_properties=False)
227238

228239
new_collection = Collection()
229-
new_collection.load(*output_paths)
240+
new_collection.load(*output_paths, version=om.__name__.split(".")[1])
230241
os.remove("issue0023.jsonld")
231242

232-
dv_again = [item for item in new_collection if isinstance(item, omcore.DatasetVersion)][0]
233-
assert isinstance(dv_again.repository, omcore.FileRepository)
243+
dv_again = [item for item in new_collection if isinstance(item, om.core.DatasetVersion)][0]
244+
assert isinstance(dv_again.repository, om.core.FileRepository)
234245
assert dv_again.repository.iri.value == "http://example.com"
235246
assert len(dv_again.custodians[0].affiliations) == 2
236247
assert dv_again.custodians[0].affiliations[0].member_of.full_name == "University of This Place"
237248
assert dv_again.custodians[0].affiliations[1].member_of.full_name == "University of That Place"
238249

239250

240-
def test_issue0056():
251+
@pytest.mark.parametrize("om", [openminds.latest, openminds.v4])
252+
def test_issue0056(om):
241253
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/56
242254
# Since we are permissive on object creation, serialization to JSON-LD should work
243255
# even if the object gives validation failures.
244256
# However, under some circumstances, to_jsonld() produces a data structure
245257
# that cannot be saved as a JSON string.
246-
dataset = omcore.Dataset(
258+
dataset = om.core.Dataset(
247259
digital_identifier=[
248-
omcore.DOI(identifier="abc"),
249-
omcore.DOI(identifier="def")
260+
om.core.DOI(identifier="abc"),
261+
om.core.DOI(identifier="def")
250262
]
251263
)
252264
failures = dataset.validate(ignore=["required"])
@@ -256,17 +268,35 @@ def test_issue0056():
256268
json.dumps(data) # this should not raise an Exception
257269

258270

259-
def test_issue0073():
271+
@pytest.mark.parametrize("om", [openminds.v4])
272+
def test_issue0073a(om):
260273
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/73
261274
# Infinite recursion in validate()
262-
ds1 = omcore.DatasetVersion(
275+
ds1 = om.core.DatasetVersion(
263276
short_name="ds1",
264277
is_alternative_version_of=None
265278
)
266-
ds2 = omcore.DatasetVersion(
279+
ds2 = om.core.DatasetVersion(
267280
short_name="ds2",
268281
is_alternative_version_of=ds1
269282
)
270283
ds1.is_alternative_version_of = ds2
271284

272285
failures = ds1.validate()
286+
287+
288+
@pytest.mark.parametrize("om", [openminds.latest])
289+
def test_issue0073b(om):
290+
# https://github.com/openMetadataInitiative/openMINDS_Python/issues/73
291+
# Infinite recursion in validate()
292+
ds1 = om.core.DatasetVersion(
293+
short_name="ds1",
294+
is_variant_of=None
295+
)
296+
ds2 = om.core.DatasetVersion(
297+
short_name="ds2",
298+
is_variant_of=ds1
299+
)
300+
ds1.is_variant_of = ds2
301+
302+
failures = ds1.validate()

pipeline/tests/test_validation.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import openminds.v4 as om
2+
3+
4+
def test_invalid_type():
5+
# invalid: type
6+
mouse = om.controlled_terms.Species.mus_musculus
7+
dsv = om.core.DatasetVersion(accessibility=mouse)
8+
assert dsv.validate(ignore=["required"]) == {
9+
"type": ["accessibility: Expected ProductAccessibility, value contains Species"]
10+
}
11+
12+
# valid
13+
dsv = om.core.DatasetVersion(study_targets=[mouse])
14+
assert dsv.validate(ignore=["required"]) == {}
15+
16+
# invalid: doubly-nested list
17+
dsv = om.core.DatasetVersion(study_targets=[[mouse]])
18+
assert "value contains list" in dsv.validate(ignore=["required"])["type"][0]
19+
20+
21+
def test_required():
22+
p = om.core.Person()
23+
assert p.validate() == {
24+
"required": [
25+
"given_name is required, but was not provided",
26+
]
27+
}

0 commit comments

Comments
 (0)