From e8492489098ef5f8566214e083cd2c2d1d449f5a Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Thu, 8 Dec 2022 16:36:19 +0100 Subject: sparql triple store and graph (nodes, mostly) --- test/graph/test_graph.py | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 test/graph/test_graph.py (limited to 'test/graph/test_graph.py') diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py new file mode 100644 index 0000000..96046ef --- /dev/null +++ b/test/graph/test_graph.py @@ -0,0 +1,93 @@ +""" + +Part of the bsfs test suite. +A copy of the license is provided with the project. +Author: Matthias Baumgartner, 2022 +""" +# imports +import unittest + +# bsie imports +from bsfs import schema as _schema +from bsfs.namespace import ns +from bsfs.triple_store import SparqlStore +from bsfs.utils import URI +from bsfs.graph.nodes import Nodes + +# objects to test +from bsfs.graph.graph import Graph + + +## code ## + +class TestGraph(unittest.TestCase): + def setUp(self): + self.user = URI('http://example.com/me') + self.backend = SparqlStore.Open(None) + self.backend.schema = _schema.Schema.from_string(''' + prefix rdfs: + prefix bsfs: + bsfs:Entity rdfs:subClassOf bsfs:Node . + ''') + + def test_str(self): + self.assertEqual(str(Graph(self.backend, self.user)), + 'Graph(SparqlStore(uri=None), http://example.com/me)') + self.assertEqual(repr(Graph(self.backend, self.user)), + 'Graph(backend=SparqlStore(uri=None), user=http://example.com/me)') + # str respects backend + class Foo(SparqlStore): pass + self.assertEqual(str(Graph(Foo.Open(None), self.user)), + 'Graph(Foo(uri=None), http://example.com/me)') + self.assertEqual(repr(Graph(Foo.Open(None), self.user)), + 'Graph(backend=Foo(uri=None), user=http://example.com/me)') + # str respect user + self.assertEqual(str(Graph(self.backend, URI('http://example.com/you'))), + 'Graph(SparqlStore(uri=None), http://example.com/you)') + self.assertEqual(repr(Graph(self.backend, URI('http://example.com/you'))), + 'Graph(backend=SparqlStore(uri=None), user=http://example.com/you)') + # str respects type + class Bar(Graph): pass + self.assertEqual(str(Bar(self.backend, self.user)), + 'Bar(SparqlStore(uri=None), http://example.com/me)') + self.assertEqual(repr(Bar(self.backend, self.user)), + 'Bar(backend=SparqlStore(uri=None), user=http://example.com/me)') + + def test_equality(self): + graph = Graph(self.backend, self.user) + # instance is equal to itself + self.assertEqual(graph, graph) + self.assertEqual(hash(graph), hash(graph)) + # instance is equal to a clone + self.assertEqual(graph, Graph(self.backend, self.user)) + self.assertEqual(hash(graph), hash(Graph(self.backend, self.user))) + # equality respects backend + self.assertNotEqual(graph, Graph(SparqlStore.Open(None), self.user)) + self.assertNotEqual(hash(graph), hash(Graph(SparqlStore.Open(None), self.user))) + # equality respects user + self.assertNotEqual(graph, Graph(self.backend, URI('http://example.com/you'))) + self.assertNotEqual(hash(graph), hash(Graph(self.backend, URI('http://example.com/you')))) + + def test_essentials(self): + graph = Graph(self.backend, self.user) + # schema + self.assertEqual(graph.schema, self.backend.schema) + self.assertRaises(AttributeError, setattr, graph, 'schema', None) + + def test_nodes(self): + graph = Graph(self.backend, self.user) + guids = {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')} + # returns a Nodes instance + self.assertEqual( + graph.nodes(ns.bsfs.Entity, guids), + Nodes(self.backend, self.user, graph.schema.node(ns.bsfs.Entity), guids)) + # node_type must be in the schema + self.assertRaises(KeyError, graph.nodes, ns.bsfs.Invalid, guids) + + +## main ## + +if __name__ == '__main__': + unittest.main() + +## EOF ## -- cgit v1.2.3 From ebc3ccb5fdce950649bfcbf18f88ecb4a9dbcad0 Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 18 Dec 2022 13:53:34 +0100 Subject: import fixes --- test/graph/test_graph.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test/graph/test_graph.py') diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py index 96046ef..eaeee0c 100644 --- a/test/graph/test_graph.py +++ b/test/graph/test_graph.py @@ -8,10 +8,10 @@ Author: Matthias Baumgartner, 2022 import unittest # bsie imports -from bsfs import schema as _schema +from bsfs import schema from bsfs.namespace import ns from bsfs.triple_store import SparqlStore -from bsfs.utils import URI +from bsfs.utils import URI, errors from bsfs.graph.nodes import Nodes # objects to test @@ -24,7 +24,7 @@ class TestGraph(unittest.TestCase): def setUp(self): self.user = URI('http://example.com/me') self.backend = SparqlStore.Open(None) - self.backend.schema = _schema.Schema.from_string(''' + self.backend.schema = schema.Schema.from_string(''' prefix rdfs: prefix bsfs: bsfs:Entity rdfs:subClassOf bsfs:Node . -- cgit v1.2.3 From 3165c3609a5061135ff7393747f8dc3f7f7abe0c Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 18 Dec 2022 14:07:56 +0100 Subject: graph schema migration --- test/graph/test_graph.py | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'test/graph/test_graph.py') diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py index eaeee0c..0b16527 100644 --- a/test/graph/test_graph.py +++ b/test/graph/test_graph.py @@ -84,6 +84,104 @@ class TestGraph(unittest.TestCase): # node_type must be in the schema self.assertRaises(KeyError, graph.nodes, ns.bsfs.Invalid, guids) + def test_migrate(self): + # setup + graph = Graph(self.backend, self.user) + + # argument must be a schema + class Foo(): pass + self.assertRaises(TypeError, graph.migrate, 'hello world') + self.assertRaises(TypeError, graph.migrate, 1234) + self.assertRaises(TypeError, graph.migrate, Foo()) + + # cannot append inconsistent schema + self.assertRaises(errors.ConsistencyError, graph.migrate, schema.Schema({}, { + schema.Node(ns.bsfs.Entity, + schema.Node(ns.bsfs.Intermediate, + schema.Node(ns.bsfs.Node, None)))}), append=True) + + # cannot migrate to inconsistent schema + self.assertRaises(errors.ConsistencyError, graph.migrate, schema.Schema({}, { + schema.Node(ns.bsfs.Entity, + schema.Node(ns.bsfs.Intermediate, + schema.Node(ns.bsfs.Node, None)))}), append=False) + + # can migrate to compatible schema + target_1 = schema.Schema.from_string(''' + prefix rdfs: + prefix xsd: + prefix bsfs: + prefix bse: + bsfs:Entity rdfs:subClassOf bsfs:Node . + xsd:string rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsfs:Literal . + + bse:filename rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "false"^^xsd:boolean . + + bse:filesize rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:integer; + bsfs:unique "false"^^xsd:boolean . + + ''') + graph.migrate(target_1) + # new schema is applied + self.assertLess(target_1, graph.schema) + # graph appends its predicates + self.assertEqual(graph.schema, target_1 + schema.Schema.from_string(''' + prefix rdfs: + prefix xsd: + prefix bsfs: + prefix bsm: + xsd:integer rdfs:subClassOf bsfs:Literal . + bsm:t_created rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Node ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + ''')) + + # can overwrite the current schema + target_2 = schema.Schema.from_string(''' + prefix rdfs: + prefix xsd: + prefix bsfs: + prefix bse: + bsfs:Entity rdfs:subClassOf bsfs:Node . + xsd:string rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsfs:Literal . + + bse:filename rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "false"^^xsd:boolean . + + bse:author rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Entity ; + rdfs:range xsd:string ; + bsfs:unique "true"^^xsd:boolean . + + ''') + graph.migrate(target_2, append=False) + # append overwrites existing predicates + self.assertFalse(target_1 <= graph.schema) + # new schema is applied + self.assertLess(target_2, graph.schema) + # graph appends its predicates + self.assertEqual(graph.schema, target_2 + schema.Schema.from_string(''' + prefix rdfs: + prefix xsd: + prefix bsfs: + prefix bsm: + xsd:integer rdfs:subClassOf bsfs:Literal . + bsm:t_created rdfs:subClassOf bsfs:Predicate ; + rdfs:domain bsfs:Node ; + rdfs:range xsd:integer ; + bsfs:unique "true"^^xsd:boolean . + ''')) + ## main ## -- cgit v1.2.3 From 58496960926a56149c10d64e01b6df7d048eed0e Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 18 Dec 2022 14:11:27 +0100 Subject: triple store Open interface --- test/graph/test_graph.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'test/graph/test_graph.py') diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py index 0b16527..f8e107d 100644 --- a/test/graph/test_graph.py +++ b/test/graph/test_graph.py @@ -23,7 +23,7 @@ from bsfs.graph.graph import Graph class TestGraph(unittest.TestCase): def setUp(self): self.user = URI('http://example.com/me') - self.backend = SparqlStore.Open(None) + self.backend = SparqlStore.Open() self.backend.schema = schema.Schema.from_string(''' prefix rdfs: prefix bsfs: @@ -37,9 +37,9 @@ class TestGraph(unittest.TestCase): 'Graph(backend=SparqlStore(uri=None), user=http://example.com/me)') # str respects backend class Foo(SparqlStore): pass - self.assertEqual(str(Graph(Foo.Open(None), self.user)), + self.assertEqual(str(Graph(Foo.Open(), self.user)), 'Graph(Foo(uri=None), http://example.com/me)') - self.assertEqual(repr(Graph(Foo.Open(None), self.user)), + self.assertEqual(repr(Graph(Foo.Open(), self.user)), 'Graph(backend=Foo(uri=None), user=http://example.com/me)') # str respect user self.assertEqual(str(Graph(self.backend, URI('http://example.com/you'))), @@ -62,8 +62,8 @@ class TestGraph(unittest.TestCase): self.assertEqual(graph, Graph(self.backend, self.user)) self.assertEqual(hash(graph), hash(Graph(self.backend, self.user))) # equality respects backend - self.assertNotEqual(graph, Graph(SparqlStore.Open(None), self.user)) - self.assertNotEqual(hash(graph), hash(Graph(SparqlStore.Open(None), self.user))) + self.assertNotEqual(graph, Graph(SparqlStore.Open(), self.user)) + self.assertNotEqual(hash(graph), hash(Graph(SparqlStore.Open(), self.user))) # equality respects user self.assertNotEqual(graph, Graph(self.backend, URI('http://example.com/you'))) self.assertNotEqual(hash(graph), hash(Graph(self.backend, URI('http://example.com/you')))) -- cgit v1.2.3 From 8ed8dbb4010a9a75cf6e61d185327825fe783776 Mon Sep 17 00:00:00 2001 From: Matthias Baumgartner Date: Sun, 18 Dec 2022 14:16:40 +0100 Subject: Graph.node interface --- test/graph/test_graph.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'test/graph/test_graph.py') diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py index f8e107d..33cf6aa 100644 --- a/test/graph/test_graph.py +++ b/test/graph/test_graph.py @@ -74,6 +74,16 @@ class TestGraph(unittest.TestCase): self.assertEqual(graph.schema, self.backend.schema) self.assertRaises(AttributeError, setattr, graph, 'schema', None) + def test_node(self): + graph = Graph(self.backend, self.user) + guid = URI('http://example.com/me/entity#1234') + # returns a Nodes instance + self.assertEqual( + graph.node(ns.bsfs.Entity, guid), + Nodes(self.backend, self.user, graph.schema.node(ns.bsfs.Entity), {guid})) + # node_type must be in the schema + self.assertRaises(KeyError, graph.node, ns.bsfs.Invalid, guid) + def test_nodes(self): graph = Graph(self.backend, self.user) guids = {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')} -- cgit v1.2.3