aboutsummaryrefslogtreecommitdiffstats
path: root/test/graph
diff options
context:
space:
mode:
Diffstat (limited to 'test/graph')
-rw-r--r--test/graph/test_graph.py13
-rw-r--r--test/graph/test_nodes.py224
-rw-r--r--test/graph/test_result.py432
-rw-r--r--test/graph/test_walk.py173
4 files changed, 835 insertions, 7 deletions
diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py
index f97783b..5db1fd2 100644
--- a/test/graph/test_graph.py
+++ b/test/graph/test_graph.py
@@ -95,6 +95,19 @@ class TestGraph(unittest.TestCase):
# node_type must be in the schema
self.assertRaises(KeyError, graph.nodes, ns.bsfs.Invalid, guids)
+ def test_all(self):
+ graph = Graph(self.backend, self.user)
+ # resulting nodes can be empty
+ self.assertEqual(graph.all(ns.bsfs.Entity),
+ Nodes(self.backend, self.user, graph.schema.node(ns.bsfs.Entity), set()))
+ # resulting nodes contains all nodes of the respective type
+ guids = {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}
+ self.backend.create(graph.schema.node(ns.bsfs.Entity), guids)
+ self.assertEqual(graph.all(ns.bsfs.Entity),
+ Nodes(self.backend, self.user, graph.schema.node(ns.bsfs.Entity), guids))
+ # node_type must be in the schema
+ self.assertRaises(KeyError, graph.all, ns.bsfs.Invalid)
+
def test_migrate(self):
# setup
graph = Graph(self.backend, self.user)
diff --git a/test/graph/test_nodes.py b/test/graph/test_nodes.py
index 2870f35..6bb3ef3 100644
--- a/test/graph/test_nodes.py
+++ b/test/graph/test_nodes.py
@@ -4,13 +4,18 @@ Part of the bsfs test suite.
A copy of the license is provided with the project.
Author: Matthias Baumgartner, 2022
"""
-# imports
-import rdflib
+# standard imports
+from functools import partial
+import operator
import unittest
+# external imports
+import rdflib
+
# bsie imports
-from bsfs import schema as _schema
-from bsfs.namespace import ns
+from bsfs import schema as bsc
+from bsfs.graph.walk import Walk
+from bsfs.namespace import Namespace, ns
from bsfs.triple_store.sparql import SparqlStore
from bsfs.utils import errors, URI
@@ -20,11 +25,13 @@ from bsfs.graph.nodes import Nodes
## code ##
+bst = Namespace('http://bsfs.ai/schema/Tag')
+
class TestNodes(unittest.TestCase):
def setUp(self):
# initialize backend
self.backend = SparqlStore()
- self.backend.schema = _schema.from_string('''
+ self.backend.schema = bsc.from_string('''
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
@@ -67,6 +74,11 @@ class TestNodes(unittest.TestCase):
rdfs:range bsfs:User ;
bsfs:unique "true"^^xsd:boolean .
+ bst:label rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Tag ;
+ rdfs:range xsd:string ;
+ bsfs:unique "true"^^xsd:boolean .
+
bst:representative rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Tag ;
rdfs:range bsfs:Entity ;
@@ -80,6 +92,7 @@ class TestNodes(unittest.TestCase):
(rdflib.URIRef(ns.bsfs.User), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)),
(rdflib.URIRef(ns.xsd.string), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
(rdflib.URIRef(ns.bsfs.Array), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
+ (rdflib.URIRef(ns.bsfs.BinaryBlob), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
(rdflib.URIRef(ns.bsfs.Feature), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Array)),
(rdflib.URIRef(ns.bsfs.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
(rdflib.URIRef(ns.bsfs.Time), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)),
@@ -89,7 +102,8 @@ class TestNodes(unittest.TestCase):
(rdflib.URIRef(ns.bse.filesize), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
(rdflib.URIRef(ns.bse.author), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
- (rdflib.URIRef('http://bsfs.ai/schema/Tag#representative'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
+ (rdflib.URIRef(bst.representative), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
+ (rdflib.URIRef(bst.label), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)),
}
# Nodes constructor args
self.user = URI('http://example.com/me')
@@ -100,7 +114,8 @@ class TestNodes(unittest.TestCase):
self.p_filesize = self.backend.schema.predicate(ns.bse.filesize)
self.p_author = self.backend.schema.predicate(ns.bse.author)
self.p_tag = self.backend.schema.predicate(ns.bse.tag)
- self.p_representative = self.backend.schema.predicate(URI('http://bsfs.ai/schema/Tag#representative'))
+ self.p_representative = self.backend.schema.predicate(bst.representative)
+ self.p_label = self.backend.schema.predicate(bst.label)
self.t_created = self.backend.schema.predicate(ns.bsm.t_created)
self.ent_ids = {
URI('http://example.com/me/entity#1234'),
@@ -371,6 +386,201 @@ class TestNodes(unittest.TestCase):
(self.p_author.uri, Nodes(self.backend, self.user, self.user_type, {URI('http://example.com/me/user#1234'), URI('http://example.com/me/user#4321')}))))
self.assertSetEqual(curr, set(self.backend._graph))
+ def test_get(self):
+ # setup: add some instances
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}) \
+ .set(ns.bse.comment, 'hello world') \
+ .set(ns.bse.filesize, 1234) \
+ .set(ns.bse.tag, Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#1234'}))
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}) \
+ .set(ns.bse.filesize, 4321) \
+ .set(ns.bse.tag, Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#4321'}))
+ Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#1234'}) \
+ .set(bst.label, 'tag_label_1234')
+ Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#4321'}) \
+ .set(bst.label, 'tag_label_4321')
+ # setup: get nodes instance
+ nodes = Nodes(self.backend, self.user, self.ent_type, self.ent_ids)
+ # must pass at least one path
+ self.assertRaises(AttributeError, nodes.get)
+ # view must be list or dict
+ self.assertRaises(ValueError, nodes.get, ns.bse.filesize, view='hello')
+ self.assertRaises(ValueError, nodes.get, ns.bse.filesize, view=1234)
+ self.assertRaises(ValueError, nodes.get, ns.bse.filesize, view=tuple)
+ # can pass path as URI
+ self.assertDictEqual(nodes.get(ns.bse.filesize), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}): 1234,
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}): 4321,
+ })
+ # can pass path as sequence of URI
+ self.assertDictEqual(nodes.get((ns.bse.tag, bst.label)), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}): {'tag_label_1234'},
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}): {'tag_label_4321'},
+ })
+ # get returns the same path that was passed
+ self.assertCountEqual(list(nodes.get((ns.bse.tag, bst.label), path=True, view=list)), [
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}), (ns.bse.tag, bst.label), 'tag_label_1234'),
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}), (ns.bse.tag, bst.label), 'tag_label_4321'),
+ ])
+ self.assertCountEqual(list(nodes.get([ns.bse.tag, bst.label], path=True, view=list)), [
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}), [ns.bse.tag, bst.label], 'tag_label_1234'),
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}), [ns.bse.tag, bst.label], 'tag_label_4321'),
+ ])
+ # paths must be URI or sequence thereof
+ self.assertRaises(TypeError, nodes.get, 1234)
+ self.assertRaises(TypeError, nodes.get, (ns.bse.tag, 1234))
+ self.assertRaises(TypeError, nodes.get, (1234, ns.bse.tag))
+ self.assertRaises(errors.ConsistencyError, nodes.get, 'hello world')
+ self.assertRaises(errors.ConsistencyError, nodes.get, ns.bse.invalid)
+ self.assertRaises(errors.ConsistencyError, nodes.get, (ns.bse.tag, bst.invalid))
+ # can pass multiple paths
+ self.assertDictEqual(nodes.get(ns.bse.filesize, (ns.bse.tag, bst.label)), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}): {
+ ns.bse.filesize: 1234,
+ (ns.bse.tag, bst.label): {'tag_label_1234'},
+ },
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}): {
+ ns.bse.filesize: 4321,
+ (ns.bse.tag, bst.label): {'tag_label_4321'},
+ },
+ })
+ # get respects view
+ self.assertDictEqual(nodes.get(ns.bse.filesize, view=dict), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}): 1234,
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}): 4321,
+ })
+ self.assertSetEqual(set(nodes.get(ns.bse.filesize, view=list)), {
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}), 1234),
+ (Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}), 4321),
+ })
+ # get returns Nodes instance when fetching a node
+ self.assertDictEqual(nodes.get(ns.bse.tag), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}):
+ {Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#1234'})},
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#4321'}):
+ {Nodes(self.backend, self.user, self.tag_type, {'http://example.com/me/tag#4321'})},
+ })
+ # get returns a value when fetching a value and omits missing values
+ self.assertDictEqual(nodes.get(ns.bse.comment), {
+ Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'}): {'hello world'},
+ })
+
+ # FIXME: What if I call `get` with a single predicate and a single node, but
+ # that node has no value for that predicate?
+ # so, essentially, what if triples is empty? -> Also check in test_result!
+ raise NotImplementedError()
+
+ def test_getattr(self):
+ nodes = Nodes(self.backend, self.user, self.ent_type, {'http://example.com/me/entity#1234'})
+ # can get walks to values
+ self.assertEqual(nodes.filesize, Walk(nodes, (self.p_filesize, )))
+ # can get walks to nodes
+ self.assertEqual(nodes.tag, Walk(nodes, (self.p_tag, )))
+ # can do multiple hops
+ self.assertEqual(nodes.tag.label, Walk(nodes, (self.p_tag, self.p_label)))
+ # invalid step raises an error
+ self.assertRaises(ValueError, getattr, nodes, 'foobar')
+
+ def test_schema(self):
+ self.assertEqual(Nodes(self.backend, self.user, self.ent_type,
+ {URI('http://example.com/me/entity#1234')}).schema, self.backend.schema)
+
+ def test_operators(self): # __add__, __or__, __sub__, __and__
+ gen = partial(Nodes, self.backend, self.user, self.ent_type)
+ nodes = gen({URI('http://example.com/me/entity#1234')})
+ # add/or concatenates guids
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234')}) +
+ gen({URI('http://example.com/me/entity#4321')}),
+ # target
+ gen({
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321')}))
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234')}) |
+ gen({URI('http://example.com/me/entity#4321')}),
+ # target
+ gen({
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321')}))
+ # repeated guids are ignored
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234')}) +
+ gen({URI('http://example.com/me/entity#1234')}),
+ # target
+ gen({URI('http://example.com/me/entity#1234')}))
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234')}) |
+ gen({URI('http://example.com/me/entity#1234')}),
+ # target
+ gen({URI('http://example.com/me/entity#1234')}))
+
+ # sub substracts guids
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321')}) -
+ gen({URI('http://example.com/me/entity#4321')}),
+ # target
+ gen({URI('http://example.com/me/entity#1234')}))
+ # missing guids are ignored
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234')}) -
+ gen({URI('http://example.com/me/entity#4321')}),
+ # target
+ gen({URI('http://example.com/me/entity#1234')}))
+
+ # and intersects guids
+ self.assertEqual(
+ gen({URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321')}) &
+ gen({URI('http://example.com/me/entity#4321'),
+ URI('http://example.com/me/entity#5678')}),
+ # target
+ gen({URI('http://example.com/me/entity#4321')}))
+
+ for op in (operator.add, operator.or_, operator.sub, operator.and_):
+ # type must match
+ self.assertRaises(TypeError, op, nodes, 1234)
+ self.assertRaises(TypeError, op, nodes, 'hello world')
+ # backend must match
+ self.assertRaises(ValueError, op, nodes,
+ Nodes(None, self.user, self.ent_type, {URI('http://example.com/me/entity#1234')}))
+ # user must match
+ self.assertRaises(ValueError, op, nodes,
+ Nodes(self.backend, '', self.ent_type, {URI('http://example.com/me/entity#1234')}))
+ # node type must match
+ self.assertRaises(ValueError, op, nodes,
+ Nodes(self.backend, self.user, self.tag_type, {URI('http://example.com/me/entity#1234')}))
+
+ def test_len(self):
+ self.assertEqual(1, len(Nodes(self.backend, self.user, self.ent_type, {
+ URI('http://example.com/me/entity#1234'),
+ })))
+ self.assertEqual(2, len(Nodes(self.backend, self.user, self.ent_type, {
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321'),
+ })))
+ self.assertEqual(4, len(Nodes(self.backend, self.user, self.ent_type, {
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321'),
+ URI('http://example.com/me/entity#5678'),
+ URI('http://example.com/me/entity#8765'),
+ })))
+
+ def test_iter(self): # __iter__
+ gen = partial(Nodes, self.backend, self.user, self.ent_type)
+ self.assertSetEqual(set(Nodes(self.backend, self.user, self.ent_type, {
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321'),
+ URI('http://example.com/me/entity#5678'),
+ URI('http://example.com/me/entity#8765'),
+ })), {
+ gen({URI('http://example.com/me/entity#1234')}),
+ gen({URI('http://example.com/me/entity#4321')}),
+ gen({URI('http://example.com/me/entity#5678')}),
+ gen({URI('http://example.com/me/entity#8765')}),
+ })
+
## main ##
diff --git a/test/graph/test_result.py b/test/graph/test_result.py
new file mode 100644
index 0000000..749b8ad
--- /dev/null
+++ b/test/graph/test_result.py
@@ -0,0 +1,432 @@
+"""
+
+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 bsc
+from bsfs.namespace import ns
+from bsfs.utils import URI
+
+# objects to test
+from bsfs.graph.result import to_list_view, to_dict_view
+
+
+## code ##
+
+class TestListView(unittest.TestCase):
+ def setUp(self):
+ self.triples_111 = [('ent#1234', ns.bse.iso, 123)]
+ self.triples_11U = [('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678')]
+ self.triples_1M1 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.t_created, '2010-01-02')]
+ self.triples_1MU = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678')]
+ self.triples_N11 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#4321', ns.bse.iso, 321)]
+ self.triples_N1U = [('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678'),
+ ('ent#4321', ns.bse.tag, 'tag#4321')]
+ self.triples_NM1 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.t_created, '2010-01-02'),
+ ('ent#4321', ns.bse.iso, 321),
+ ('ent#4321', ns.bse.t_created, '2022-02-22')]
+ self.triples_NMU = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678'),
+ ('ent#4321', ns.bse.iso, 321),
+ ('ent#4321', ns.bse.t_created, '2022-02-22')]
+
+ def test_copy(self):
+ # iterator yields tuples
+ self.assertIsInstance(list(to_list_view([('subject', 'predicate', 'object')], node=True, path=True, value=True))[0], tuple)
+ # components are not changed
+ class Foo(): pass
+ foo = Foo()
+ self.assertListEqual(list(to_list_view([('subject', 'predicate', 'object')], node=True, path=True, value=True)),
+ [('subject', 'predicate', 'object')])
+ self.assertListEqual(list(to_list_view([(foo, 'predicate', 'object')], node=True, path=True, value=True)),
+ [(foo, 'predicate', 'object')])
+ self.assertListEqual(list(to_list_view([('subject', foo, 'object')], node=True, path=True, value=True)),
+ [('subject', foo, 'object')])
+ self.assertListEqual(list(to_list_view([('subject', 'predicate', foo)], node=True, path=True, value=True)),
+ [('subject', 'predicate', foo)])
+
+ def test_agg_none(self):
+ self.assertListEqual(list(to_list_view(self.triples_111, node=True, path=True, value=True)), self.triples_111)
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=True, path=True, value=True)), self.triples_11U)
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=True, path=True, value=True)), self.triples_1M1)
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=True, path=True, value=True)), self.triples_1MU)
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=True, path=True, value=True)), self.triples_N11)
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=True, path=True, value=True)), self.triples_N1U)
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=True, path=True, value=True)), self.triples_NM1)
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=True, path=True, value=True)), self.triples_NMU)
+
+ def test_agg_node(self):
+ self.assertListEqual(list(to_list_view(self.triples_111, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123)])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=False, path=True, value=True)),
+ [(ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123), (ns.bse.t_created, '2010-01-02')])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123), (ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123), (ns.bse.iso, 321)])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=False, path=True, value=True)),
+ [(ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678'), (ns.bse.tag, 'tag#4321')])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123), (ns.bse.t_created, '2010-01-02'), (ns.bse.iso, 321), (ns.bse.t_created, '2022-02-22')])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=False, path=True, value=True)),
+ [(ns.bse.iso, 123), (ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678'), (ns.bse.iso, 321), (ns.bse.t_created, '2022-02-22')])
+
+ def test_agg_path(self):
+ self.assertListEqual(list(to_list_view(self.triples_111, node=True, path=False, value=True)),
+ [('ent#1234', 123)])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=True, path=False, value=True)),
+ [('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=True, path=False, value=True)),
+ [('ent#1234', 123), ('ent#1234', '2010-01-02')])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=True, path=False, value=True)),
+ [('ent#1234', 123), ('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=True, path=False, value=True)),
+ [('ent#1234', 123), ('ent#4321', 321)])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=True, path=False, value=True)),
+ [('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678'), ('ent#4321', 'tag#4321')])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=True, path=False, value=True)),
+ [('ent#1234', 123), ('ent#1234', '2010-01-02'), ('ent#4321', 321), ('ent#4321', '2022-02-22')])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=True, path=False, value=True)),
+ [('ent#1234', 123), ('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678'), ('ent#4321', 321), ('ent#4321', '2022-02-22')])
+
+ def test_agg_node_path(self):
+ self.assertListEqual(list(to_list_view(self.triples_111, node=False, path=False, value=True)),
+ [123])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=False, path=False, value=True)),
+ ['tag#1234', 'tag#5678'])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=False, path=False, value=True)),
+ [123, '2010-01-02'])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=False, path=False, value=True)),
+ [123, 'tag#1234', 'tag#5678'])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=False, path=False, value=True)),
+ [123, 321])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=False, path=False, value=True)),
+ ['tag#1234', 'tag#5678', 'tag#4321'])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=False, path=False, value=True)),
+ [123, '2010-01-02', 321, '2022-02-22'])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=False, path=False, value=True)),
+ [123, 'tag#1234', 'tag#5678', 321, '2022-02-22'])
+
+ def test_agg_value(self):
+ # value flag has no effect
+ self.assertListEqual(list(to_list_view(self.triples_111, node=True, path=True, value=True)), self.triples_111)
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=True, path=True, value=True)), self.triples_11U)
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=True, path=True, value=True)), self.triples_1M1)
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=True, path=True, value=True)), self.triples_1MU)
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=True, path=True, value=True)), self.triples_N11)
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=True, path=True, value=True)), self.triples_N1U)
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=True, path=True, value=True)), self.triples_NM1)
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=True, path=True, value=True)), self.triples_NMU)
+
+ def test_agg_node_value(self):
+ # value flag has no effect -> same test as test_agg_node
+ self.assertListEqual(list(to_list_view(self.triples_111, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123)])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=False, path=True, value=False)),
+ [(ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123), (ns.bse.t_created, '2010-01-02')])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123), (ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123), (ns.bse.iso, 321)])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=False, path=True, value=False)),
+ [(ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678'), (ns.bse.tag, 'tag#4321')])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123), (ns.bse.t_created, '2010-01-02'), (ns.bse.iso, 321), (ns.bse.t_created, '2022-02-22')])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=False, path=True, value=False)),
+ [(ns.bse.iso, 123), (ns.bse.tag, 'tag#1234'), (ns.bse.tag, 'tag#5678'), (ns.bse.iso, 321), (ns.bse.t_created, '2022-02-22')])
+
+ def test_agg_path_value(self):
+ # value flag has no effect -> same test as test_agg_path
+ self.assertListEqual(list(to_list_view(self.triples_111, node=True, path=False, value=False)),
+ [('ent#1234', 123)])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=True, path=False, value=False)),
+ [('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=True, path=False, value=False)),
+ [('ent#1234', 123), ('ent#1234', '2010-01-02')])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=True, path=False, value=False)),
+ [('ent#1234', 123), ('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678')])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=True, path=False, value=False)),
+ [('ent#1234', 123), ('ent#4321', 321)])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=True, path=False, value=False)),
+ [('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678'), ('ent#4321', 'tag#4321')])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=True, path=False, value=False)),
+ [('ent#1234', 123), ('ent#1234', '2010-01-02'), ('ent#4321', 321), ('ent#4321', '2022-02-22')])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=True, path=False, value=False)),
+ [('ent#1234', 123), ('ent#1234', 'tag#1234'), ('ent#1234', 'tag#5678'), ('ent#4321', 321), ('ent#4321', '2022-02-22')])
+
+ def test_agg_all(self):
+ # value flag has no effect -> same test as test_agg_node_path
+ self.assertListEqual(list(to_list_view(self.triples_111, node=False, path=False, value=False)),
+ [123])
+ self.assertListEqual(list(to_list_view(self.triples_11U, node=False, path=False, value=False)),
+ ['tag#1234', 'tag#5678'])
+ self.assertListEqual(list(to_list_view(self.triples_1M1, node=False, path=False, value=False)),
+ [123, '2010-01-02'])
+ self.assertListEqual(list(to_list_view(self.triples_1MU, node=False, path=False, value=False)),
+ [123, 'tag#1234', 'tag#5678'])
+ self.assertListEqual(list(to_list_view(self.triples_N11, node=False, path=False, value=False)),
+ [123, 321])
+ self.assertListEqual(list(to_list_view(self.triples_N1U, node=False, path=False, value=False)),
+ ['tag#1234', 'tag#5678', 'tag#4321'])
+ self.assertListEqual(list(to_list_view(self.triples_NM1, node=False, path=False, value=False)),
+ [123, '2010-01-02', 321, '2022-02-22'])
+ self.assertListEqual(list(to_list_view(self.triples_NMU, node=False, path=False, value=False)),
+ [123, 'tag#1234', 'tag#5678', 321, '2022-02-22'])
+
+
+class TestDictView(unittest.TestCase):
+ def setUp(self):
+ self.unique_paths = {ns.bse.iso, ns.bse.t_created}
+ self.triples_111 = [('ent#1234', ns.bse.iso, 123)]
+ self.triples_11U = [('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678')]
+ self.triples_1M1 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.t_created, '2010-01-02')]
+ self.triples_1MU = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678')]
+ self.triples_N11 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#4321', ns.bse.iso, 321)]
+ self.triples_N1U = [('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678'),
+ ('ent#4321', ns.bse.tag, 'tag#4321')]
+ self.triples_NM1 = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.t_created, '2010-01-02'),
+ ('ent#4321', ns.bse.iso, 321),
+ ('ent#4321', ns.bse.t_created, '2022-02-22')]
+ self.triples_NMU = [('ent#1234', ns.bse.iso, 123),
+ ('ent#1234', ns.bse.tag, 'tag#1234'),
+ ('ent#1234', ns.bse.tag, 'tag#5678'),
+ ('ent#4321', ns.bse.iso, 321),
+ ('ent#4321', ns.bse.t_created, '2022-02-22')]
+
+ def test_errounous_call(self):
+ # return set instead of value
+ self.assertSetEqual(to_dict_view(self.triples_111, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123})
+ self.assertSetEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123})
+ # one_node mismatch: return set of values instead of value
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: {123}})
+ # one_path mismatch: return set of values instead of value
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {123}})
+ # unique_paths mismatch: return set of values instead of value
+ self.assertSetEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths={}, node=False, path=False, value=False),
+ {123})
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths={}, node=False, path=True, value=False),
+ {ns.bse.iso: {123}})
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths={}, node=True, path=False, value=False),
+ {'ent#1234': {123}})
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=False, unique_paths={}, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: {123}}})
+
+ def test_agg_none(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}}})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.tag: {'tag#1234', 'tag#5678'}}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}, ns.bse.t_created: {'2010-01-02'}}})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}, ns.bse.tag: {'tag#1234', 'tag#5678'}}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}}, 'ent#4321': {ns.bse.iso: {321}}})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.tag: {'tag#1234', 'tag#5678'}}, 'ent#4321': {ns.bse.tag: {'tag#4321'}}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}, ns.bse.t_created: {'2010-01-02'}}, 'ent#4321': {ns.bse.iso: {321}, ns.bse.t_created: {'2022-02-22'}}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True),
+ {'ent#1234': {ns.bse.iso: {123}, ns.bse.tag: {'tag#1234', 'tag#5678'}}, 'ent#4321': {ns.bse.iso: {321}, ns.bse.t_created: {'2022-02-22'}}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=True), {})
+
+ def test_agg_node(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123}})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.tag: {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123}, ns.bse.t_created: {'2010-01-02'}})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123}, ns.bse.tag: {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123, 321}})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.tag: {'tag#1234', 'tag#5678', 'tag#4321'}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123, 321}, ns.bse.t_created: {'2010-01-02', '2022-02-22'}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True),
+ {ns.bse.iso: {123, 321}, ns.bse.tag: {'tag#1234', 'tag#5678'}, ns.bse.t_created: {'2022-02-22'}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=True), {})
+
+ def test_agg_path(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123}})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123, '2010-01-02'}})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123, 'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123}, 'ent#4321': {321}})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {'tag#1234', 'tag#5678'}, 'ent#4321': {'tag#4321'}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123, '2010-01-02'}, 'ent#4321': {321, '2022-02-22'}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True),
+ {'ent#1234': {123, 'tag#1234', 'tag#5678'}, 'ent#4321': {321, '2022-02-22'}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=True), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=True), {})
+
+ def test_agg_node_path(self):
+ self.assertSetEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123})
+ self.assertSetEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {'tag#1234', 'tag#5678'})
+ self.assertSetEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123, '2010-01-02'})
+ self.assertSetEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123, 'tag#1234', 'tag#5678'})
+ self.assertSetEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123, 321})
+ self.assertSetEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {'tag#1234', 'tag#5678', 'tag#4321'})
+ self.assertSetEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123, '2010-01-02', 321, '2022-02-22'})
+ self.assertSetEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True),
+ {123, 'tag#1234', 'tag#5678', 321, '2022-02-22'})
+ # empty
+ self.assertSetEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True), set())
+ self.assertSetEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True), set())
+ self.assertSetEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=True), set())
+ self.assertSetEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=True), set())
+
+ def test_agg_value(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123}})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.tag: {'tag#1234', 'tag#5678'}}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123, ns.bse.t_created: '2010-01-02'}})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123, ns.bse.tag: {'tag#1234', 'tag#5678'}}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123}, 'ent#4321': {ns.bse.iso: 321}})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.tag: {'tag#1234', 'tag#5678'}}, 'ent#4321': {ns.bse.tag: {'tag#4321'}}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123, ns.bse.t_created: '2010-01-02'}, 'ent#4321': {ns.bse.iso: 321, ns.bse.t_created: '2022-02-22'}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False),
+ {'ent#1234': {ns.bse.iso: 123, ns.bse.tag: {'tag#1234', 'tag#5678'}}, 'ent#4321': {ns.bse.iso: 321, ns.bse.t_created: '2022-02-22'}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=True, value=False), {})
+
+ def test_agg_node_value(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: 123})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.tag: {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: 123, ns.bse.t_created: '2010-01-02'})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: 123, ns.bse.tag: {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: {123, 321}})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.tag: {'tag#1234', 'tag#5678', 'tag#4321'}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: {123, 321}, ns.bse.t_created: {'2010-01-02', '2022-02-22'}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False),
+ {ns.bse.iso: {123, 321}, ns.bse.tag: {'tag#1234', 'tag#5678'}, ns.bse.t_created: {'2022-02-22'}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=True, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=True, value=False), {})
+
+ def test_agg_path_value(self):
+ self.assertDictEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': 123})
+ self.assertDictEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {123, '2010-01-02'}})
+ self.assertDictEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {123, 'tag#1234', 'tag#5678'}})
+ self.assertDictEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': 123, 'ent#4321': 321})
+ self.assertDictEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {'tag#1234', 'tag#5678'}, 'ent#4321': {'tag#4321'}})
+ self.assertDictEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {123, '2010-01-02'}, 'ent#4321': {321, '2022-02-22'}})
+ self.assertDictEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False),
+ {'ent#1234': {123, 'tag#1234', 'tag#5678'}, 'ent#4321': {321, '2022-02-22'}})
+ # empty
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=True, path=False, value=False), {})
+ self.assertDictEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=True, path=False, value=False), {})
+
+ def test_agg_all(self):
+ self.assertEqual(to_dict_view(self.triples_111, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ 123)
+ self.assertSetEqual(to_dict_view(self.triples_11U, one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {'tag#1234', 'tag#5678'})
+ self.assertSetEqual(to_dict_view(self.triples_1M1, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123, '2010-01-02'})
+ self.assertSetEqual(to_dict_view(self.triples_1MU, one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123, 'tag#1234', 'tag#5678'})
+ self.assertSetEqual(to_dict_view(self.triples_N11, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123, 321})
+ self.assertSetEqual(to_dict_view(self.triples_N1U, one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {'tag#1234', 'tag#5678', 'tag#4321'})
+ self.assertSetEqual(to_dict_view(self.triples_NM1, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123, '2010-01-02', 321, '2022-02-22'})
+ self.assertSetEqual(to_dict_view(self.triples_NMU, one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False),
+ {123, 'tag#1234', 'tag#5678', 321, '2022-02-22'})
+ # empty
+ self.assertEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False), None)
+ self.assertSetEqual(to_dict_view([], one_node=True, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False), set())
+ self.assertSetEqual(to_dict_view([], one_node=False, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False), set())
+ self.assertSetEqual(to_dict_view([], one_node=False, one_path=False, unique_paths=self.unique_paths, node=False, path=False, value=False), set())
+ self.assertEqual(to_dict_view([], one_node=True, one_path=True, unique_paths=self.unique_paths, node=False, path=False, value=False, default=123), 123)
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##
diff --git a/test/graph/test_walk.py b/test/graph/test_walk.py
new file mode 100644
index 0000000..f9dbc7a
--- /dev/null
+++ b/test/graph/test_walk.py
@@ -0,0 +1,173 @@
+"""
+
+Part of the bsfs test suite.
+A copy of the license is provided with the project.
+Author: Matthias Baumgartner, 2022
+"""
+# imports
+import unittest
+
+# bsfs imports
+from bsfs import schema as bsc
+from bsfs.graph import Graph
+from bsfs.namespace import Namespace, ns
+from bsfs.triple_store.sparql import SparqlStore
+from bsfs.utils import URI
+
+# symbol to test
+from bsfs.graph.walk import Walk
+
+## code ##
+
+bse = ns.bse
+bst = Namespace('http://bsfs.ai/schema/Tag')
+
+class TestWalk(unittest.TestCase):
+ def setUp(self):
+ # backend setup
+ self.schema = bsc.from_string('''
+ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
+ prefix xsd: <http://www.w3.org/2001/XMLSchema#>
+ prefix bsfs: <http://bsfs.ai/schema/>
+ prefix bse: <http://bsfs.ai/schema/Entity#>
+ prefix bst: <http://bsfs.ai/schema/Tag#>
+
+ bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Tag rdfs:subClassOf bsfs:Node .
+ bsfs:User rdfs:subClassOf bsfs:Node .
+ xsd:string rdfs:subClassOf bsfs:Literal .
+
+ bse:author rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Node ;
+ rdfs:range bsfs:User .
+
+ bse:tag rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Entity ;
+ rdfs:range bsfs:Tag .
+
+ bst:label rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Tag ;
+ rdfs:range xsd:string ;
+ bsfs:unique "true"^^xsd:boolean .
+
+ bst:subTagOf rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Tag ;
+ rdfs:range bsfs:Tag .
+
+ bst:main rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Tag ;
+ rdfs:range bsfs:Entity .
+
+ bst:author rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Tag ;
+ rdfs:range xsd:string .
+
+ ''')
+ self.backend = SparqlStore.Open()
+ self.user = URI('http://example.com/me')
+ self.graph = Graph(self.backend, self.user)
+ self.graph.migrate(self.schema)
+
+ # nodes setup
+ self.ents = self.graph.nodes(ns.bsfs.Entity, {
+ URI('http://example.com/me/entity#1234'),
+ URI('http://example.com/me/entity#4321')})
+ self.tags = self.graph.nodes(ns.bsfs.Tag, {
+ URI('http://example.com/me/tag#1234'),
+ URI('http://example.com/me/tag#4321')})
+ # add some instances
+ self.ents.set(bse.tag, self.tags)
+ self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#1234')).set(bst.label, 'hello')
+ self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#4321')).set(bst.label, 'world')
+
+ def test_essentials(self): # __eq__, __hash__, __str__, __repr__
+ p_author = self.schema.predicate(bse.author)
+ p_tag = self.schema.predicate(bse.tag)
+ p_main = self.schema.predicate(bst.main)
+ # comparison
+ self.assertEqual(Walk(self.ents, [p_tag]), Walk(self.ents, [p_tag]))
+ self.assertEqual(hash(Walk(self.ents, [p_tag])), hash(Walk(self.ents, [p_tag])))
+ # comparison respects type
+ class Foo(Walk): pass
+ self.assertNotEqual(Walk(self.ents, [p_tag]), Foo(self.ents, [p_tag]))
+ self.assertNotEqual(hash(Walk(self.ents, [p_tag])), hash(Foo(self.ents, [p_tag])))
+ # comparison respects root
+ self.assertNotEqual(Walk(self.ents, [p_author]), Walk(self.tags, [p_author]))
+ self.assertNotEqual(hash(Walk(self.ents, [p_author])), hash(Walk(self.tags, [p_author])))
+ # comparison respects path
+ self.assertNotEqual(Walk(self.tags, [p_author]), Walk(self.tags, [p_main]))
+ self.assertNotEqual(hash(Walk(self.tags, [p_author])), hash(Walk(self.tags, [p_main])))
+ # string conversion
+ self.assertEqual(str(Walk(self.ents, [p_tag, p_main])),
+ 'Walk(@http://bsfs.ai/schema/Entity: http://bsfs.ai/schema/Entity#tag, http://bsfs.ai/schema/Tag#main)')
+ self.assertEqual(repr(Walk(self.ents, [p_tag, p_main])),
+ 'Walk(http://bsfs.ai/schema/Entity, (http://bsfs.ai/schema/Entity#tag, http://bsfs.ai/schema/Tag#main))')
+
+ def test_tail(self):
+ self.assertEqual(Walk(self.ents, (
+ self.schema.predicate(bse.tag),
+ )).tail,
+ self.schema.node(ns.bsfs.Tag))
+ self.assertEqual(Walk(self.ents, (
+ self.schema.predicate(bse.tag),
+ self.schema.predicate(bst.main),
+ )).tail,
+ self.schema.node(ns.bsfs.Entity))
+
+ def test_step(self):
+ tag_type = self.schema.node(ns.bsfs.Tag)
+ # step returns a predicate
+ self.assertEqual(Walk.step(self.schema, tag_type, 'subTagOf'),
+ (self.schema.predicate(bst.subTagOf), ))
+ # invalid step raises an error
+ self.assertRaises(ValueError, Walk.step, self.schema, tag_type, 'foobar')
+ # ambiguous step raises an error
+ self.assertRaises(ValueError, Walk.step, self.schema, tag_type, 'author')
+
+ def test_getattr(self): # __getattr__
+ walk = Walk(self.ents, (self.schema.predicate(bse.tag), ))
+ # first step
+ self.assertEqual(walk.subTagOf, Walk(self.ents, (
+ self.schema.predicate(bse.tag),
+ self.schema.predicate(bst.subTagOf),
+ )))
+ # second step
+ self.assertEqual(walk.subTagOf.main, Walk(self.ents, (
+ self.schema.predicate(bse.tag),
+ self.schema.predicate(bst.subTagOf),
+ self.schema.predicate(bst.main),
+ )))
+ # invalid step raises an error
+ self.assertRaises(ValueError, getattr, walk, 'foobar')
+ # ambiguous step raises an error
+ self.assertRaises(ValueError, getattr, walk, 'author')
+
+ def test_get(self): # get, __call__
+ walk = Walk(self.ents, (self.schema.predicate(bse.tag), ))
+ tags = {
+ self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#1234')),
+ self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#4321'))}
+ # get returns from Nodes.get
+ self.assertDictEqual(walk.get(), {
+ self.graph.node(ns.bsfs.Entity, URI('http://example.com/me/entity#1234')): tags,
+ self.graph.node(ns.bsfs.Entity, URI('http://example.com/me/entity#4321')): tags,
+ })
+ self.assertDictEqual(walk(), {
+ self.graph.node(ns.bsfs.Entity, URI('http://example.com/me/entity#1234')): tags,
+ self.graph.node(ns.bsfs.Entity, URI('http://example.com/me/entity#4321')): tags,
+ })
+ # get passes kwargs to Nodes.get
+ self.assertSetEqual(tags, walk.get(node=False))
+ self.assertSetEqual(tags, walk(node=False))
+ self.assertSetEqual(tags, set(walk.get(view=list, node=False)))
+ self.assertSetEqual(tags, set(walk(view=list, node=False)))
+ # get returns values if need be
+ self.assertSetEqual(walk.label(node=False), {'hello', 'world'})
+
+
+## main ##
+
+if __name__ == '__main__':
+ unittest.main()
+
+## EOF ##