Skip to content

Commit 75654cd

Browse files
committed
Converting the "issue" tests to pytest in preparation for rehoming the specific tests under the tests for the modules that they are testing. In some cases, the quality of the test was improved by adding in extra checks."
1 parent 7615438 commit 75654cd

21 files changed

+523
-655
lines changed

linkml_runtime/loaders/loader_root.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def load(self, *args, **kwargs) -> Union[BaseModel, YAMLRoot]:
7575
:return: instance of target_class
7676
"""
7777
results = self.load_any(*args, **kwargs)
78-
if isinstance(results, BaseModel) or isinstance(results, YAMLRoot):
78+
if isinstance(results, (BaseModel, YAMLRoot)):
7979
return results
8080
else:
8181
raise ValueError(f"Result is not an instance of BaseModel or YAMLRoot: {type(results)}")
@@ -145,9 +145,9 @@ def _construct_target_class(
145145
elif isinstance(data_as_dict, dict):
146146
if issubclass(target_class, BaseModel):
147147
return target_class.model_validate(data_as_dict)
148-
else:
149-
return target_class(**data_as_dict)
150-
elif isinstance(data_as_dict, JsonObj):
148+
return target_class(**data_as_dict)
149+
150+
if isinstance(data_as_dict, JsonObj):
151151
return [target_class(**as_dict(x)) for x in data_as_dict]
152152
else:
153153
raise ValueError(f"Unexpected type {data_as_dict}")
@@ -170,7 +170,7 @@ def _read_source(
170170
if not isinstance(source, dict):
171171
# Try to get local version of schema, if one is known to exist
172172
try:
173-
if str(source) in URI_TO_LOCAL.keys():
173+
if str(source) in URI_TO_LOCAL:
174174
source = str(URI_TO_LOCAL[str(source)])
175175
except (TypeError, KeyError) as e:
176176
# Fine, use original `source` value

tests/test_issues/input/linkml_issue_478.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ classes:
99
- id
1010
- preferred label
1111
- SOURCE
12-
biosample processing:
12+
biosample_processing:
1313
is_a: named thing
1414
attributes:
1515
processingMethod:
@@ -23,4 +23,4 @@ classes:
2323
slots:
2424
id:
2525
preferred label:
26-
SOURCE:
26+
SOURCE:

tests/test_issues/test_dataclass_extensions_376.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import sys
2-
import pytest
3-
import importlib.util
41
import dataclasses
2+
import importlib.util
3+
4+
import pytest
55

66

77
def import_patch_module():
8-
"""Fresh import to ensure warning is triggered"""
8+
"""Fresh import to ensure warning is triggered."""
99
spec = importlib.util.find_spec("linkml_runtime.utils.dataclass_extensions_376")
1010
mod = importlib.util.module_from_spec(spec)
1111
spec.loader.exec_module(mod)
1212
return mod
1313

1414

15-
def test_patch_module_emits_deprecation_warning():
16-
"""All Python versions: emits DeprecationWarning and defines compatibility symbols"""
15+
def test_patch_module_emits_deprecation_warning() -> None:
16+
"""All Python versions: emits DeprecationWarning and defines compatibility symbols."""
1717
with pytest.warns(DeprecationWarning):
1818
mod = import_patch_module()
1919

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,13 @@
1-
from unittest import TestCase
2-
1+
import pytest
32
import yaml.constructor
43

54
from linkml_runtime.linkml_model import SchemaDefinition
65
from linkml_runtime.loaders import yaml_loader
76
from tests.test_issues.environment import env
87

98

10-
class Issue1040TestCase(TestCase):
11-
"""
12-
https://github.com/linkml/linkml/issues/1040
13-
"""
14-
15-
env = env
16-
17-
def test_issue_1040_file_name(self):
18-
"""issue_1040.yaml has a parsing error is confusing as all getout when accompanied by a stack
19-
trace. We use this to make sure that the file name gets in correctly."""
20-
with self.assertRaises(yaml.constructor.ConstructorError) as e:
21-
yaml_loader.load(env.input_path("issue_1040.yaml"), SchemaDefinition)
22-
self.assertIn('"issue_1040.yaml"', str(e.exception))
9+
def test_issue_1040_file_name() -> None:
10+
"""issue_1040.yaml has a parsing error is confusing as all getout when accompanied by a stack
11+
trace. We use this to make sure that the file name gets in correctly."""
12+
with pytest.raises(yaml.constructor.ConstructorError, match='"issue_1040.yaml"'):
13+
yaml_loader.load(env.input_path("issue_1040.yaml"), SchemaDefinition)
Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
1-
"""
2-
Created on 2023-03-24
1+
import pytest
32

4-
@author: wf
5-
"""
6-
7-
from unittest import TestCase
83
from linkml_runtime.utils.metamodelcore import URI
94

105

11-
class Issue1355TestCase(TestCase):
12-
"""
13-
https://github.com/linkml/linkml/issues/1355
14-
improve invalid URL message
15-
"""
6+
def test_issue_1355_invalid_url_message() -> None:
7+
"""Check that quotes are used when referencing invalid urls to improve troubleshooting UX.
168
17-
def test_issue_1355_invalid_url_message(self):
18-
"""
19-
check that quotes are used when referencing invalid urls so that
20-
the visiblity of the problem gets better
21-
"""
22-
# note the trailing blank
23-
url = "https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf "
24-
try:
25-
_uri = URI(url)
26-
except ValueError as vex:
27-
msg = str(vex)
28-
# 'https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf ': is not a valid URI
29-
self.assertTrue(".pdf '" in msg)
9+
See https://github.com/linkml/linkml/issues/1355, improve invalid URL message
10+
"""
11+
# note the trailing blank
12+
url = "https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf "
13+
with pytest.raises(ValueError, match="'https://ceur-ws.org/Vol-2931/ICBO_2019_paper_20.pdf ': is not a valid URI"):
14+
URI(url)

tests/test_issues/test_issue_163.py

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 22 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,31 @@
1-
import unittest
2-
from typing import Callable
1+
from collections.abc import Callable
32

4-
from linkml_runtime.dumpers import json_dumper, yaml_dumper, rdf_dumper
5-
from tests.test_issues.environment import env
6-
from tests.test_loaders_dumpers.loaderdumpertestcase import LoaderDumperTestCase
3+
from linkml_runtime.dumpers import json_dumper, rdf_dumper, yaml_dumper
74
from linkml_runtime.utils.compile_python import compile_python
5+
from tests.test_issues.environment import env
86

97

10-
class Issue368TestCase(LoaderDumperTestCase):
11-
env = env
12-
13-
def header(self, txt: str) -> str:
14-
return "\n" + ("=" * 20) + f" {txt} " + ("=" * 20)
15-
16-
def test_issue_368_enums(self):
17-
"""Test Enum generation"""
18-
19-
module = compile_python(env.input_path("issue_368.py"))
8+
def header(txt: str) -> str:
9+
return "\n" + ("=" * 20) + f" {txt} " + ("=" * 20)
2010

21-
enum_inst = module.SampleEnum("pva") # EnumInstanceImpl
22-
example = module.SampleClass(slot_1="pva")
23-
assert hasattr(example, "slot_1")
24-
assert example.slot_1.code.text == enum_inst.code.text
25-
assert str(example.slot_1) == "pva"
2611

27-
def dump_and_load(dumper: Callable, sfx: str) -> None:
28-
fname = env.actual_path(f"issue_368_1.{sfx}")
29-
dumper(example, fname)
30-
with open(fname) as f:
31-
print(f"\n----- {sfx} -----")
32-
print(f.read())
12+
def test_issue_368_enums() -> None:
13+
"""Test Enum generation."""
14+
module = compile_python(env.input_path("issue_368.py"))
3315

34-
dump_and_load(json_dumper.dump, "json")
35-
dump_and_load(yaml_dumper.dump, "yaml")
36-
dump_and_load(lambda obj, fname: rdf_dumper.dump(obj, fname, env.input_path("issue_368.context.jsonld")), "ttl")
16+
enum_inst = module.SampleEnum("pva") # EnumInstanceImpl
17+
example = module.SampleClass(slot_1="pva")
18+
assert hasattr(example, "slot_1")
19+
assert example.slot_1.code.text == enum_inst.code.text
20+
assert str(example.slot_1) == "pva"
3721

22+
def dump_and_load(dumper: Callable, sfx: str) -> None:
23+
fname = env.actual_path(f"issue_368_1.{sfx}")
24+
dumper(example, fname)
25+
with open(fname) as f:
26+
print(f"\n----- {sfx} -----")
27+
print(f.read())
3828

39-
if __name__ == "__main__":
40-
unittest.main()
29+
dump_and_load(json_dumper.dump, "json")
30+
dump_and_load(yaml_dumper.dump, "yaml")
31+
dump_and_load(lambda obj, fname: rdf_dumper.dump(obj, fname, env.input_path("issue_368.context.jsonld")), "ttl")

tests/test_issues/test_issue_6.py

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import unittest
2-
31
import hbreader
2+
import pytest
43
import yaml
54

65
from linkml_runtime.utils.yamlutils import DupCheckYamlLoader, TypedNode
@@ -13,26 +12,29 @@
1312
"""
1413

1514

16-
class Issue6TestCase(unittest.TestCase):
17-
def test_loc_function(self):
18-
inp = yaml.load(hbreader.hbread(inp_yaml), DupCheckYamlLoader)
19-
self.assertEqual('File "<unicode string>", line 3, col 8: ', TypedNode.yaml_loc(inp["foo"]["x"]))
20-
self.assertEqual('File "<unicode string>", line 3, col 8', TypedNode.yaml_loc(inp["foo"]["x"], suffix=""))
21-
self.assertEqual('File "<unicode string>", line 4, col 8: ', TypedNode.yaml_loc(inp["foo"]["y"]))
22-
self.assertEqual(
23-
'File "<unicode string>", line 4, col 8I yam that I yam',
24-
TypedNode.yaml_loc(inp["foo"]["y"], suffix=inp["foo"]["y"]),
25-
)
26-
self.assertEqual('File "<unicode string>", line 5, col 8: ', TypedNode.yaml_loc(inp["foo"]["z"]))
27-
28-
with self.assertWarns(DeprecationWarning) as cm:
29-
self.assertEqual('File "<unicode string>", line 3, col 8', TypedNode.loc(inp["foo"]["x"]))
30-
self.assertEqual("Call to deprecated method loc. (Use yaml_loc instead)", cm.warning.args[0])
31-
32-
self.assertEqual("", TypedNode.yaml_loc(None))
33-
self.assertEqual("", TypedNode.yaml_loc("abc"))
34-
self.assertEqual("", TypedNode.yaml_loc(["a", "b"]))
35-
36-
37-
if __name__ == "__main__":
38-
unittest.main()
15+
def test_loc_function() -> None:
16+
"""Test the TypedNode.yaml_loc function."""
17+
inp = yaml.load(hbreader.hbread(inp_yaml), DupCheckYamlLoader)
18+
assert TypedNode.yaml_loc(inp["foo"]["x"]) == 'File "<unicode string>", line 3, col 8: '
19+
assert TypedNode.yaml_loc(inp["foo"]["x"], suffix="") == 'File "<unicode string>", line 3, col 8'
20+
assert TypedNode.yaml_loc(inp["foo"]["y"]) == 'File "<unicode string>", line 4, col 8: '
21+
assert (
22+
TypedNode.yaml_loc(inp["foo"]["y"], suffix=inp["foo"]["y"])
23+
== 'File "<unicode string>", line 4, col 8I yam that I yam'
24+
)
25+
assert TypedNode.yaml_loc(inp["foo"]["z"]) == 'File "<unicode string>", line 5, col 8: '
26+
27+
28+
def test_yaml_loc_warning() -> None:
29+
"""Test that a warning is emitted when using the `loc` method."""
30+
inp = yaml.load(hbreader.hbread(inp_yaml), DupCheckYamlLoader)
31+
with pytest.warns(DeprecationWarning) as warning_list:
32+
assert TypedNode.loc(inp["foo"]["x"]) == 'File "<unicode string>", line 3, col 8'
33+
assert len(warning_list) == 1
34+
assert str(warning_list[0].message) == "Call to deprecated method loc. (Use yaml_loc instead)"
35+
36+
37+
@pytest.mark.parametrize("loc", [None, "abc", ["a", "b"]])
38+
def test_yaml_loc_empty_str(loc) -> None:
39+
"""Test yaml_loc values that translate to an empty string."""
40+
assert TypedNode.yaml_loc(loc) == ""
Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import unittest
2-
31
from linkml_runtime.linkml_model import SchemaDefinition
42
from linkml_runtime.utils.yamlutils import from_yaml
53

@@ -12,22 +10,17 @@
1210
string:
1311
base: str
1412
uri: xsd:string
15-
13+
1614
slots:
1715
name:
1816
"""
1917

2018

21-
class IsolatedNameTestCase(unittest.TestCase):
22-
def test_it(self):
23-
"""Dangling name should not throw a type error"""
24-
error_thrown = False
25-
try:
26-
from_yaml(model_txt, SchemaDefinition)
27-
except TypeError as e:
28-
error_thrown = True
29-
self.assertFalse(error_thrown, msg="Type error should not be thrown")
30-
31-
32-
if __name__ == "__main__":
33-
unittest.main()
19+
def test_read_dangling_name() -> None:
20+
"""Dangling name should not throw a type error."""
21+
error_thrown = False
22+
try:
23+
from_yaml(model_txt, SchemaDefinition)
24+
except TypeError:
25+
error_thrown = True
26+
assert error_thrown is False

tests/test_issues/test_issue_718.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
1-
import pytest
1+
from __future__ import annotations
2+
23
from dataclasses import dataclass
3-
from typing import Optional, ClassVar
4+
from typing import ClassVar
45

6+
import pytest
57
import yaml
68

7-
from linkml_runtime.utils.yamlutils import YAMLRoot, DupCheckYamlLoader
9+
from linkml_runtime.utils.yamlutils import DupCheckYamlLoader, YAMLRoot
810

911

1012
@pytest.mark.xfail(reason="Reporting line numbers should happen at load time not when instantiating dataclasses")
11-
def test_issue_38():
13+
def test_issue_38() -> None:
1214
# The goal is to provide line numbers on error messages. We've tweaked the parser so that it returns augmented
1315
# str's and int's with the line numbers on them. The problem we are trying to address now is that the dataclass
1416
# constructor doesn't support **argv out of the box. We can certainly tweak the generator to emit the __init__
@@ -18,8 +20,8 @@ def test_issue_38():
1820
class FesterBesterTester(YAMLRoot):
1921
cv: ClassVar[int] = 42
2022

21-
a: Optional[int] = 0
22-
b: Optional[str] = None
23+
a: int | None = 0
24+
b: str | None = None
2325

2426
with pytest.raises(TypeError, match="unexpected keyword argument 'c'"):
2527
FesterBesterTester(a=12, b="Sell", c="buy")

0 commit comments

Comments
 (0)