Skip to content

Commit 57399a4

Browse files
committed
Add tests for relative URI handling
The PR has changes to the publicID that is used, which affects relative URI resolution, so that should also be tested.
1 parent bb2ff6b commit 57399a4

File tree

6 files changed

+94
-14
lines changed

6 files changed

+94
-14
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"public_id": "http://example.org/variants/relative_triples",
3+
"quad_count": 1,
4+
"exact_match" : true,
5+
"has_subject_iris": [
6+
"http://example.org/variants/path/subject"
7+
]
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<http://example.org/variants/path/subject> <http://example.org/variants/path/predicate> <http://example.org/variants/path/object> .
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@prefix anchor: <path/> .
2+
3+
anchor:subject anchor:predicate anchor:object .

test/test_sparql/test_update.py

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
import itertools
12
import logging
23
from test.data import TEST_DATA_DIR
34
from test.utils import GraphHelper
4-
from test.utils.graph import load_sources
5+
from test.utils.graph import GraphSource
56
from test.utils.namespace import EGDO
67
from typing import Callable
78

@@ -10,22 +11,33 @@
1011
from rdflib.graph import ConjunctiveGraph, Dataset, Graph
1112

1213

13-
@pytest.mark.parametrize("graph_factory", [Graph, ConjunctiveGraph, Dataset])
14-
def test_load_into_default(graph_factory: Callable[[], Graph]) -> None:
14+
@pytest.mark.parametrize(
15+
("graph_factory", "source"),
16+
itertools.product(
17+
[Graph, ConjunctiveGraph, Dataset],
18+
GraphSource.from_paths(
19+
TEST_DATA_DIR / "variants" / "simple_triple.ttl",
20+
TEST_DATA_DIR / "variants" / "relative_triple.ttl",
21+
),
22+
),
23+
ids=GraphSource.idfn,
24+
)
25+
def test_load_into_default(
26+
graph_factory: Callable[[], Graph], source: GraphSource
27+
) -> None:
1528
"""
1629
Evaluation of ``LOAD <source>`` into default graph works correctly.
1730
"""
18-
source_path = TEST_DATA_DIR / "variants" / "simple_triple.ttl"
1931

2032
expected_graph = graph_factory()
21-
load_sources(source_path, graph=expected_graph)
33+
source.load(graph=expected_graph)
2234

2335
actual_graph = graph_factory()
24-
actual_graph.update(f"LOAD <{source_path.as_uri()}>")
36+
actual_graph.update(f"LOAD <{source.public_id_or_path_uri()}>")
2537

2638
if logging.getLogger().isEnabledFor(logging.DEBUG):
2739
debug_format = (
28-
"trig" if isinstance(expected_graph, ConjunctiveGraph) else "turtle"
40+
"nquads" if isinstance(expected_graph, ConjunctiveGraph) else "ntriples"
2941
)
3042
logging.debug(
3143
"expected_graph = \n%s", expected_graph.serialize(format=debug_format)
@@ -41,22 +53,35 @@ def test_load_into_default(graph_factory: Callable[[], Graph]) -> None:
4153
GraphHelper.assert_triple_sets_equals(expected_graph, actual_graph)
4254

4355

44-
@pytest.mark.parametrize("graph_factory", [ConjunctiveGraph, Dataset])
45-
def test_load_into_named(graph_factory: Callable[[], ConjunctiveGraph]) -> None:
56+
@pytest.mark.parametrize(
57+
("graph_factory", "source"),
58+
itertools.product(
59+
[ConjunctiveGraph, Dataset],
60+
GraphSource.from_paths(
61+
TEST_DATA_DIR / "variants" / "simple_triple.ttl",
62+
TEST_DATA_DIR / "variants" / "relative_triple.ttl",
63+
),
64+
),
65+
ids=GraphSource.idfn,
66+
)
67+
def test_load_into_named(
68+
graph_factory: Callable[[], ConjunctiveGraph], source: GraphSource
69+
) -> None:
4670
"""
4771
Evaluation of ``LOAD <source> INTO GRAPH <name>`` works correctly.
4872
"""
49-
source_path = TEST_DATA_DIR / "variants" / "simple_triple.ttl"
5073

5174
expected_graph = graph_factory()
52-
load_sources(source_path, graph=expected_graph.get_context(EGDO.graph))
75+
source.load(graph=expected_graph.get_context(EGDO.graph))
5376

5477
actual_graph = graph_factory()
5578

56-
actual_graph.update(f"LOAD <{source_path.as_uri()}> INTO GRAPH <{EGDO.graph}>")
79+
actual_graph.update(
80+
f"LOAD <{source.public_id_or_path_uri()}> INTO GRAPH <{EGDO.graph}>"
81+
)
5782

5883
if logging.getLogger().isEnabledFor(logging.DEBUG):
59-
debug_format = "trig"
84+
debug_format = "nquads"
6085
logging.debug(
6186
"expected_graph = \n%s", expected_graph.serialize(format=debug_format)
6287
)

test/utils/__init__.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,24 @@ def ensure_suffix(value: str, suffix: str) -> str:
488488
return value
489489

490490

491+
def idfns(*idfns: Callable[[Any], Optional[str]]) -> Callable[[Any], Optional[str]]:
492+
"""
493+
Returns an ID function which will try each of the provided ID
494+
functions in order.
495+
496+
:param idfns: The ID functions to try.
497+
:return: An ID function which will try each of the provided ID
498+
functions.
499+
"""
500+
501+
def _idfns(value: Any) -> Optional[str]:
502+
for idfn in idfns:
503+
result = idfn(value)
504+
if result is not None:
505+
return result
506+
return None
507+
508+
return _idfns
509+
510+
491511
from test.utils.iri import file_uri_to_path # noqa: E402

test/utils/graph.py

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from __future__ import annotations
22

33
import logging
4+
import test.data
45
from dataclasses import dataclass
56
from functools import lru_cache
67
from pathlib import Path
78
from runpy import run_path
8-
from typing import Optional, Tuple, Type, Union
9+
from typing import Any, Optional, Tuple, Type, Union
910

1011
import rdflib.util
1112
from rdflib.graph import Graph, _GraphT
@@ -57,6 +58,11 @@ def from_source(
5758
source = GraphSource.from_path(source)
5859
return source
5960

61+
def public_id_or_path_uri(self) -> str:
62+
if self.public_id is not None:
63+
self.public_id
64+
return self.path.as_uri()
65+
6066
def load(
6167
self,
6268
graph: Optional[_GraphT] = None,
@@ -77,6 +83,23 @@ def load(
7783
)
7884
return graph
7985

86+
@classmethod
87+
def idfn(cls, val: Any) -> Optional[str]:
88+
"""
89+
ID function for GraphSource objects.
90+
91+
:param val: The value to try to generate and identifier for.
92+
:return: A string identifying the given value if the value is a
93+
`GraphSource`, otherwise return `None`.
94+
"""
95+
if isinstance(val, cls):
96+
try:
97+
path_string = f"{val.path.relative_to(test.data.TEST_DATA_DIR)}"
98+
except ValueError:
99+
path_string = f"{val.path}"
100+
return f"GS({path_string}, {val.format}, {val.public_id})"
101+
return None
102+
80103

81104
def load_sources(
82105
*sources: GraphSourceType,

0 commit comments

Comments
 (0)