|
4 | 4 |
|
5 | 5 | import pytest |
6 | 6 |
|
7 | | -from rdflib import Literal, Namespace, Variable |
8 | | -from rdflib.graph import ConjunctiveGraph, Dataset, Graph |
| 7 | +from rdflib import Literal, Namespace, URIRef, Variable |
| 8 | +from rdflib.compare import isomorphic |
| 9 | +from rdflib.graph import DATASET_DEFAULT_GRAPH_ID, ConjunctiveGraph, Dataset, Graph |
9 | 10 | from test.data import TEST_DATA_DIR |
10 | 11 | from test.utils import GraphHelper |
11 | 12 | from test.utils.graph import GraphSource |
@@ -164,3 +165,88 @@ def test_reevaluation_between_updates_insert() -> None: |
164 | 165 | result = g.query("SELECT ?x WHERE { ex:bar ex:value ?x }") |
165 | 166 | values = {b.get(Variable("x")) for b in result} # type: ignore |
166 | 167 | assert values == {Literal(3), Literal(4), Literal(14)} |
| 168 | + |
| 169 | + |
| 170 | +def test_inserts_in_named_graph(): |
| 171 | + trig_data = """ |
| 172 | + @prefix ex: <http://example.org/> . |
| 173 | + @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . |
| 174 | +
|
| 175 | + # Named graph 1 |
| 176 | + ex:graph1 { |
| 177 | + ex:person1 ex:name "Alice" ; |
| 178 | + ex:age 30 . |
| 179 | + } |
| 180 | +
|
| 181 | + # Named graph 2 |
| 182 | + ex:graph2 { |
| 183 | + ex:person1 ex:worksFor ex:company1 . |
| 184 | + ex:company1 ex:industry "Technology" . |
| 185 | + } |
| 186 | + """ |
| 187 | + ds = Dataset().parse(data=trig_data, format="trig") |
| 188 | + ds.update( |
| 189 | + """ |
| 190 | + INSERT { |
| 191 | + GRAPH <urn:graph> { |
| 192 | + ?s ?p ?o |
| 193 | + } |
| 194 | +
|
| 195 | + ?s ?p ?o |
| 196 | + } |
| 197 | + WHERE { |
| 198 | + GRAPH ?g { |
| 199 | + ?s ?p ?o |
| 200 | + } |
| 201 | + } |
| 202 | + """ |
| 203 | + ) |
| 204 | + |
| 205 | + expected_trig = """ |
| 206 | + @prefix ex: <http://example.org/> . |
| 207 | + @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . |
| 208 | +
|
| 209 | + { |
| 210 | + ex:person1 ex:age 30 ; |
| 211 | + ex:name "Alice" ; |
| 212 | + ex:worksFor ex:company1 . |
| 213 | +
|
| 214 | + ex:company1 ex:industry "Technology" . |
| 215 | + } |
| 216 | +
|
| 217 | + <urn:graph> { |
| 218 | + ex:person1 ex:age 30 ; |
| 219 | + ex:name "Alice" ; |
| 220 | + ex:worksFor ex:company1 . |
| 221 | +
|
| 222 | + ex:company1 ex:industry "Technology" . |
| 223 | + } |
| 224 | +
|
| 225 | + ex:graph1 { |
| 226 | + ex:person1 ex:age 30 ; |
| 227 | + ex:name "Alice" . |
| 228 | + } |
| 229 | +
|
| 230 | + ex:graph2 { |
| 231 | + ex:person1 ex:worksFor ex:company1 . |
| 232 | +
|
| 233 | + ex:company1 ex:industry "Technology" . |
| 234 | + } |
| 235 | + """ |
| 236 | + expected_ds = Dataset().parse(data=expected_trig, format="trig") |
| 237 | + |
| 238 | + # There should be exactly 4 graphs, including the default graph. |
| 239 | + # SPARQL Update inserts into the default graph should go into the default graph, |
| 240 | + # not to a new graph with a blank node label. |
| 241 | + # See https://github.com/RDFLib/rdflib/issues/3080 |
| 242 | + expected_graph_names = [ |
| 243 | + DATASET_DEFAULT_GRAPH_ID, |
| 244 | + URIRef("urn:graph"), |
| 245 | + URIRef("http://example.org/graph1"), |
| 246 | + URIRef("http://example.org/graph2"), |
| 247 | + ] |
| 248 | + assert set(expected_graph_names) == set(graph.identifier for graph in ds.graphs()) |
| 249 | + |
| 250 | + for graph in ds.graphs(): |
| 251 | + expected_graph = expected_ds.graph(graph.identifier) |
| 252 | + assert isomorphic(graph, expected_graph) |
0 commit comments