diff options
31 files changed, 594 insertions, 638 deletions
diff --git a/bsfs/graph/ac/null.py b/bsfs/graph/ac/null.py index 3a391aa..c9ec7d0 100644 --- a/bsfs/graph/ac/null.py +++ b/bsfs/graph/ac/null.py @@ -24,7 +24,7 @@ class NullAC(base.AccessControlBase): def is_protected_predicate(self, pred: schema.Predicate) -> bool: """Return True if a predicate cannot be modified manually.""" - return pred.uri == ns.bsm.t_created + return pred.uri == ns.bsn.t_created def create(self, node_type: schema.Node, guids: typing.Iterable[URI]): """Perform post-creation operations on nodes, e.g. ownership information.""" diff --git a/bsfs/graph/nodes.py b/bsfs/graph/nodes.py index 74f4c4f..47b0217 100644 --- a/bsfs/graph/nodes.py +++ b/bsfs/graph/nodes.py @@ -170,7 +170,7 @@ class Nodes(): self._backend.commit() except ( - errors.PermissionDeniedError, # tried to set a protected predicate (ns.bsm.t_created) + errors.PermissionDeniedError, # tried to set a protected predicate errors.ConsistencyError, # node types are not in the schema or don't match the predicate errors.InstanceError, # guids/values don't have the correct type TypeError, # value is supposed to be a Nodes instance @@ -394,7 +394,7 @@ class Nodes(): self._backend.create(node_type, missing) # add bookkeeping triples self._backend.set(node_type, missing, - self._backend.schema.predicate(ns.bsm.t_created), [time.time()]) + self._backend.schema.predicate(ns.bsn.t_created), [time.time()]) # add permission triples self._ac.create(node_type, missing) # return available nodes diff --git a/bsfs/graph/resolve.py b/bsfs/graph/resolve.py index 95dcfc1..a58eb67 100644 --- a/bsfs/graph/resolve.py +++ b/bsfs/graph/resolve.py @@ -27,8 +27,8 @@ class Filter(): input: Any(ns.bse.tag, Is(Nodes(...))) output: Any(ns.bse.tag, Or(Is(...), Is(...), ...))) - >>> tags = graph.node(ns.bsfs.Tag, 'http://example.com/me/tag#1234') - >>> graph.get(ns.bsfs.Entity, ast.filter.Any(ns.bse.tag, ast.filter.Is(tags))) + >>> tags = graph.node(ns.bsn.Tag, 'http://example.com/me/tag#1234') + >>> graph.get(ns.bsn.Entity, ast.filter.Any(ns.bse.tag, ast.filter.Is(tags))) """ diff --git a/bsfs/graph/schema.nt b/bsfs/graph/schema.nt index cba5e80..37bba5e 100644 --- a/bsfs/graph/schema.nt +++ b/bsfs/graph/schema.nt @@ -4,15 +4,16 @@ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix xsd: <http://www.w3.org/2001/XMLSchema#> # bsfs prefixes -prefix bsfs: <http://bsfs.ai/schema/> -prefix bsm: <http://bsfs.ai/schema/Meta#> +prefix bsfs: <https://schema.bsfs.io/core/> +prefix bsl: <https://schema.bsfs.io/core/Literal/> +prefix bsn: <https://schema.bsfs.io/core/Node#> # literals -bsfs:Number rdfs:subClassOf bsfs:Literal . -xsd:float rdfs:subClassOf bsfs:Number . +bsl:Number rdfs:subClassOf bsfs:Literal . +xsd:float rdfs:subClassOf bsl:Number . # predicates -bsm:t_created rdfs:subClassOf bsfs:Predicate ; +bsn:t_created rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:float ; bsfs:unique "true"^^xsd:boolean . diff --git a/bsfs/namespace/__init__.py b/bsfs/namespace/__init__.py index 1784808..76f39a2 100644 --- a/bsfs/namespace/__init__.py +++ b/bsfs/namespace/__init__.py @@ -4,11 +4,10 @@ import typing # inner-module imports from . import predefined as ns -from .namespace import ClosedNamespace, Namespace +from .namespace import Namespace # exports __all__: typing.Sequence[str] = ( - 'ClosedNamespace', 'Namespace', 'ns', ) diff --git a/bsfs/namespace/namespace.py b/bsfs/namespace/namespace.py index 0a62b78..b388f53 100644 --- a/bsfs/namespace/namespace.py +++ b/bsfs/namespace/namespace.py @@ -3,97 +3,52 @@ import typing # bsfs imports -from bsfs.utils import URI, typename +from bsfs.utils import URI # exports __all__: typing.Sequence[str] = ( - 'ClosedNamespace', 'Namespace', + 'FinalNamespace', ) ## code ## -class Namespace(): - """A namespace consists of a common prefix that is used in a set of URIs. - Note that the prefix must include the separator between - path and fragment (typically a '#' or a '/'). - """ - - # namespace prefix. - prefix: URI - - # fragment separator. - fsep: str - - # path separator. - psep: str - - def __init__(self, prefix: URI, fsep: str = '#', psep: str = '/'): - # ensure prefix type - prefix = URI(prefix) - # truncate fragment separator - while prefix.endswith(fsep): - prefix = URI(prefix[:-1]) - # truncate path separator - while prefix.endswith(psep): - prefix = URI(prefix[:-1]) - # store members - self.prefix = prefix - self.fsep = fsep - self.psep = psep - - def __eq__(self, other: typing.Any) -> bool: - return isinstance(other, type(self)) \ - and self.prefix == other.prefix \ - and self.fsep == other.fsep \ - and self.psep == other.psep +class Namespace(URI): + """The Namespace allows you to incrementally append path segments to an URI. - def __hash__(self) -> int: - return hash((type(self), self.prefix, self.fsep, self.psep)) + Segments are separated by `Namespace.sep` ('/'). + The `__call__` method signals that the URI is complete until the query part. - def __str__(self) -> str: - return str(self.prefix) - - def __repr__(self) -> str: - return f'{typename(self)}({self.prefix}, {self.fsep}, {self.psep})' - - def __getattr__(self, fragment: str) -> URI: - """Return prefix + fragment.""" - return URI(self.prefix + self.fsep + fragment) - - def __getitem__(self, fragment: str) -> URI: - """Alias for getattr(self, fragment).""" - return self.__getattr__(fragment) + """ - def __add__(self, value: typing.Any) -> 'Namespace': - """Concatenate another namespace to this one.""" - if not isinstance(value, str): - return NotImplemented - return Namespace(self.prefix + self.psep + value, self.fsep, self.psep) + # path separator + sep: str = '/' + def __getattr__(self, query: str) -> 'Namespace': + """Append the *query* to the current value and return as Namespace.""" + return Namespace(self + self.sep + query) -class ClosedNamespace(Namespace): - """Namespace that covers a restricted set of URIs.""" + def __call__(self, sep: str = '#') -> 'FinalNamespace': + """Finalize the namespace.""" + return FinalNamespace(self, sep) - # set of permissible fragments. - fragments: typing.Set[str] - def __init__(self, prefix: URI, *args: str, fsep: str = '#', psep: str = '/'): - super().__init__(prefix, fsep, psep) - self.fragments = set(args) +# FIXME: Integrate FinalNamespace into Namespace? Do we need to have both? +class FinalNamespace(URI): + """The FinalNamespace allows you to append a fragment to an URI.""" - def __eq__(self, other: typing.Any) -> bool: - return super().__eq__(other) and self.fragments == other.fragments + # fragment separator + sep: str - def __hash__(self) -> int: - return hash((type(self), self.prefix, tuple(sorted(self.fragments)))) + def __new__(cls, value: str, sep: str = '#'): + inst = URI.__new__(cls, value) + inst.sep = sep + return inst def __getattr__(self, fragment: str) -> URI: - """Return prefix + fragment or raise a KeyError if the fragment is not part of this namespace.""" - if fragment not in self.fragments: - raise KeyError(f'{fragment} is not a valid fragment of namespace {self.prefix}') - return super().__getattr__(fragment) + """Append the *fragment* to the current value and return as URI.""" + return URI(self + self.sep + fragment) ## EOF ## diff --git a/bsfs/namespace/predefined.py b/bsfs/namespace/predefined.py index 15f12ac..8b60d39 100644 --- a/bsfs/namespace/predefined.py +++ b/bsfs/namespace/predefined.py @@ -2,29 +2,28 @@ # imports import typing -# bsfs imports -from bsfs.utils import URI - # inner-module imports -from . import namespace +from .namespace import Namespace, FinalNamespace # essential bsfs namespaces -bsfs: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema'), fsep='/') - +bsfs = Namespace('https://schema.bsfs.io/core') # additional bsfs namespaces -bse: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema/Entity')) -bsm: namespace.Namespace = namespace.Namespace(URI('http://bsfs.ai/schema/Meta')) +bsd = bsfs.distance() +bsl = bsfs.Literal +bsn = bsfs.Node() # generic namespaces -rdf: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/1999/02/22-rdf-syntax-ns')) -rdfs: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/2000/01/rdf-schema')) -schema: namespace.Namespace = namespace.Namespace(URI('http://schema.org'), fsep='/') -xsd: namespace.Namespace = namespace.Namespace(URI('http://www.w3.org/2001/XMLSchema')) +rdf = FinalNamespace('http://www.w3.org/1999/02/22-rdf-syntax-ns') +rdfs = FinalNamespace('http://www.w3.org/2000/01/rdf-schema') +xsd = FinalNamespace('http://www.w3.org/2001/XMLSchema') +schema = FinalNamespace('http://schema.org', sep='/') +# exports __all__: typing.Sequence[str] = ( - 'bse', + 'bsd', 'bsfs', - 'bsm', + 'bsl', + 'bsn', 'rdf', 'rdfs', 'schema', diff --git a/bsfs/query/ast/filter_.py b/bsfs/query/ast/filter_.py index 56c982e..610fdb4 100644 --- a/bsfs/query/ast/filter_.py +++ b/bsfs/query/ast/filter_.py @@ -10,7 +10,8 @@ For example, consider the following AST: >>> Any(ns.bse.collection, ... And( ... Equals('hello'), -... Any(ns.bsm.guid, Any(ns.bsm.guid, Equals('hello'))), +... Is('hello world'), +... Any(ns.bse.tag, Equals('world')), ... Any(ns.bst.label, Equals('world')), ... All(ns.bst.label, Not(Equals('world'))), ... ) diff --git a/bsfs/query/matcher.py b/bsfs/query/matcher.py index 5f3b07e..17c9c8e 100644 --- a/bsfs/query/matcher.py +++ b/bsfs/query/matcher.py @@ -215,8 +215,8 @@ class Filter(): two following queries are semantically identical, but structurally different, and would therefore not match: - >>> ast.filter.OneOf(ast.filter.Predicate(ns.bse.filename)) - >>> ast.filter.Predicate(ns.bse.filename) + >>> ast.filter.OneOf(ast.filter.Predicate(ns.bse.name)) + >>> ast.filter.Predicate(ns.bse.name) """ diff --git a/bsfs/query/validator.py b/bsfs/query/validator.py index 1ce44e9..10ca492 100644 --- a/bsfs/query/validator.py +++ b/bsfs/query/validator.py @@ -177,7 +177,7 @@ class Filter(): if not type_ <= dom: raise errors.ConsistencyError(f'expected type {dom}, found {type_}') # node.count is a numerical expression - self._parse_filter_expression(self.schema.literal(ns.bsfs.Number), node.count) + self._parse_filter_expression(self.schema.literal(ns.bsl.Number), node.count) def _distance(self, type_: bsc.Vertex, node: ast.filter.Distance): # type is a Literal @@ -218,7 +218,7 @@ class Filter(): if type_ not in self.schema.literals(): raise errors.ConsistencyError(f'literal {type_} is not in the schema') # type must be a numerical - if not type_ <= self.schema.literal(ns.bsfs.Number): + if not type_ <= self.schema.literal(ns.bsl.Number): raise errors.ConsistencyError(f'expected a number type, found {type_}') # FIXME: Check if node.value corresponds to type_ diff --git a/bsfs/schema/serialize.py b/bsfs/schema/serialize.py index b05b289..ea8b2f4 100644 --- a/bsfs/schema/serialize.py +++ b/bsfs/schema/serialize.py @@ -241,13 +241,14 @@ def to_string(schema_inst: schema.Schema, fmt: str = 'turtle') -> str: graph.add(triple) # add known namespaces for readability # FIXME: more generically? - graph.bind('bse', rdflib.URIRef(ns.bse[''])) - graph.bind('bsfs', rdflib.URIRef(ns.bsfs[''])) - graph.bind('bsm', rdflib.URIRef(ns.bsm[''])) - graph.bind('rdf', rdflib.URIRef(ns.rdf[''])) - graph.bind('rdfs', rdflib.URIRef(ns.rdfs[''])) - graph.bind('schema', rdflib.URIRef(ns.schema[''])) - graph.bind('xsd', rdflib.URIRef(ns.xsd[''])) + graph.bind('bsfs', rdflib.URIRef(ns.bsfs + '/')) + graph.bind('bsl', rdflib.URIRef(ns.bsl + '/')) + graph.bind('bsn', rdflib.URIRef(ns.bsn + '#')) + graph.bind('bse', rdflib.URIRef(ns.bsfs.Entity() + '#')) + graph.bind('rdf', rdflib.URIRef(ns.rdf)) + graph.bind('rdfs', rdflib.URIRef(ns.rdfs)) + graph.bind('schema', rdflib.URIRef(ns.schema)) + graph.bind('xsd', rdflib.URIRef(ns.xsd)) # serialize to turtle return graph.serialize(format=fmt) diff --git a/bsfs/schema/types.py b/bsfs/schema/types.py index 104580d..5834df8 100644 --- a/bsfs/schema/types.py +++ b/bsfs/schema/types.py @@ -376,31 +376,31 @@ ROOT_LITERAL = Literal( ) ROOT_BLOB = Literal( - uri=ns.bsfs.BinaryBlob, + uri=ns.bsl.BinaryBlob, parent=ROOT_LITERAL, ) ROOT_NUMBER = Literal( - uri=ns.bsfs.Number, + uri=ns.bsl.Number, parent=ROOT_LITERAL, ) ROOT_TIME = Literal( - uri=ns.bsfs.Time, + uri=ns.bsl.Time, parent=ROOT_LITERAL, ) ROOT_ARRAY = Literal( - uri=ns.bsfs.Array, + uri=ns.bsl.Array, parent=ROOT_LITERAL, ) ROOT_FEATURE = Feature( - uri=ns.bsfs.Feature, + uri=ns.bsl.Array.Feature, parent=ROOT_ARRAY, dimension=1, - dtype=ns.bsfs.f16, - distance=ns.bsfs.euclidean, + dtype=ns.bsfs.dtype().f16, + distance=ns.bsd.euclidean, ) # essential predicates diff --git a/bsfs/triple_store/sparql/distance.py b/bsfs/triple_store/sparql/distance.py index 9b58088..2c2f355 100644 --- a/bsfs/triple_store/sparql/distance.py +++ b/bsfs/triple_store/sparql/distance.py @@ -43,9 +43,9 @@ def manhatten(fst, snd) -> float: # Known distance functions. DISTANCE_FU = { - ns.bsfs.euclidean: euclid, - ns.bsfs.cosine: cosine, - ns.bsfs.manhatten: manhatten, + ns.bsd.euclidean: euclid, + ns.bsd.cosine: cosine, + ns.bsd.manhatten: manhatten, } ## EOF ## diff --git a/bsfs/triple_store/sparql/sparql.py b/bsfs/triple_store/sparql/sparql.py index 68c0027..99e67d6 100644 --- a/bsfs/triple_store/sparql/sparql.py +++ b/bsfs/triple_store/sparql/sparql.py @@ -28,7 +28,7 @@ __all__: typing.Sequence[str] = ( ## code ## -rdflib.term.bind(ns.bsfs.BinaryBlob, bytes, constructor=base64.b64decode) +rdflib.term.bind(ns.bsl.BinaryBlob, bytes, constructor=base64.b64decode) class _Transaction(): """Lightweight rdflib transactions for in-memory databases.""" @@ -335,8 +335,8 @@ class SparqlStore(base.TripleStoreBase): # convert value if isinstance(predicate.range, bsc.Literal): dtype = rdflib.URIRef(predicate.range.uri) - if predicate.range <= self.schema.literal(ns.bsfs.BinaryBlob): - dtype = rdflib.URIRef(ns.bsfs.BinaryBlob) + if predicate.range <= self.schema.literal(ns.bsl.BinaryBlob): + dtype = rdflib.URIRef(ns.bsl.BinaryBlob) value = base64.b64encode(value) value = rdflib.Literal(value, datatype=dtype) elif isinstance(predicate.range, bsc.Node): diff --git a/test/apps/schema-1.nt b/test/apps/schema-1.nt index e57146d..4daf0ad 100644 --- a/test/apps/schema-1.nt +++ b/test/apps/schema-1.nt @@ -3,8 +3,8 @@ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix xsd: <http://www.w3.org/2001/XMLSchema#> # common bsfs prefixes -prefix bsfs: <http://bsfs.ai/schema/> -prefix bse: <http://bsfs.ai/schema/Entity#> +prefix bsfs: <http://schema.bsfs.io/core/> +prefix bse: <http://schema.bsfs.io/core/Node/Entity#> # essential nodes bsfs:Entity rdfs:subClassOf bsfs:Node . diff --git a/test/apps/schema-2.nt b/test/apps/schema-2.nt index 4c5468f..4eb2467 100644 --- a/test/apps/schema-2.nt +++ b/test/apps/schema-2.nt @@ -3,8 +3,8 @@ prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> prefix xsd: <http://www.w3.org/2001/XMLSchema#> # common bsfs prefixes -prefix bsfs: <http://bsfs.ai/schema/> -prefix bse: <http://bsfs.ai/schema/Entity#> +prefix bsfs: <http://schema.bsfs.io/core/> +prefix bse: <http://schema.bsfs.io/core/Node/Entity#> # essential nodes bsfs:Entity rdfs:subClassOf bsfs:Node . diff --git a/test/graph/ac/test_null.py b/test/graph/ac/test_null.py index b695e7e..142bc23 100644 --- a/test/graph/ac/test_null.py +++ b/test/graph/ac/test_null.py @@ -15,6 +15,8 @@ from bsfs.graph.ac.null import NullAC ## code ## +ns.bse = ns.bsfs.Entity() + class TestNullAC(unittest.TestCase): def setUp(self): self.backend = SparqlStore() @@ -22,18 +24,19 @@ class TestNullAC(unittest.TestCase): 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 bsm: <http://bsfs.ai/schema/Meta#> - prefix bse: <http://bsfs.ai/schema/Entity#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsn: <https://schema.bsfs.io/core/Node#> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . # predicates mandated by Nodes - bsm:t_created rdfs:subClassOf bsfs:Predicate ; + bsn:t_created rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . @@ -59,7 +62,7 @@ class TestNullAC(unittest.TestCase): self.p_author = self.backend.schema.predicate(ns.bse.author) self.p_filesize = self.backend.schema.predicate(ns.bse.filesize) self.p_tag = self.backend.schema.predicate(ns.bse.tag) - self.p_created = self.backend.schema.predicate(ns.bsm.t_created) + self.p_created = self.backend.schema.predicate(ns.bsn.t_created) self.ent_type = self.backend.schema.node(ns.bsfs.Entity) self.ent_ids = {URI('http://www.example.com/me/entity#1234'), URI('http://www.example.com/me/entity#4321')} diff --git a/test/graph/test_graph.py b/test/graph/test_graph.py index e6d5ae4..167168d 100644 --- a/test/graph/test_graph.py +++ b/test/graph/test_graph.py @@ -19,12 +19,14 @@ from bsfs.graph.graph import Graph ## code ## +ns.bse = ns.bsfs.Entity() + class TestGraph(unittest.TestCase): def setUp(self): self.backend = SparqlStore.Open() self.backend.schema = schema.from_string(''' prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix bsfs: <http://bsfs.ai/schema/> + prefix bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node . ''') self.user = URI('http://example.com/me') @@ -129,12 +131,13 @@ class TestGraph(unittest.TestCase): target_1 = schema.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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; @@ -154,11 +157,12 @@ class TestGraph(unittest.TestCase): self.assertEqual(graph.schema, target_1 + schema.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 bsm: <http://bsfs.ai/schema/Meta#> - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:float rdfs:subClassOf bsfs:Number . - bsm:t_created rdfs:subClassOf bsfs:Predicate ; + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bsn: <https://schema.bsfs.io/core/Node#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:float rdfs:subClassOf bsl:Number . + bsn:t_created rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:float ; bsfs:unique "true"^^xsd:boolean . @@ -168,12 +172,13 @@ class TestGraph(unittest.TestCase): target_2 = schema.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 bsfs: <http://schema.bsfs.io/core/> + prefix bse: <http://schema.bsfs.io/core/Node/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; @@ -195,11 +200,12 @@ class TestGraph(unittest.TestCase): self.assertEqual(graph.schema, target_2 + schema.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 bsm: <http://bsfs.ai/schema/Meta#> - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:float rdfs:subClassOf bsfs:Number . - bsm:t_created rdfs:subClassOf bsfs:Predicate ; + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bsn: <https://schema.bsfs.io/core/Node#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:float rdfs:subClassOf bsl:Number . + bsn:t_created rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:float ; bsfs:unique "true"^^xsd:boolean . @@ -211,8 +217,8 @@ class TestGraph(unittest.TestCase): graph.migrate(schema.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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . @@ -264,8 +270,8 @@ class TestGraph(unittest.TestCase): graph.migrate(schema.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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . diff --git a/test/graph/test_nodes.py b/test/graph/test_nodes.py index dca887a..afe7522 100644 --- a/test/graph/test_nodes.py +++ b/test/graph/test_nodes.py @@ -21,7 +21,8 @@ from bsfs.graph.nodes import Nodes ## code ## -bst = Namespace('http://bsfs.ai/schema/Tag') +ns.bse = ns.bsfs.Entity() +ns.bst = ns.bsfs.Tag() class TestNodes(unittest.TestCase): def setUp(self): @@ -31,20 +32,21 @@ class TestNodes(unittest.TestCase): 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 bsm: <http://bsfs.ai/schema/Meta#> - prefix bse: <http://bsfs.ai/schema/Entity#> - prefix bst: <http://bsfs.ai/schema/Tag#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsn: <https://schema.bsfs.io/core/Node#> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bst: <https://schema.bsfs.io/core/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 . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . # predicates mandated by Nodes - bsm:t_created rdfs:subClassOf bsfs:Predicate ; + bsn:t_created rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . @@ -87,19 +89,19 @@ class TestNodes(unittest.TestCase): (rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)), (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)), - (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)), - (rdflib.URIRef(ns.bsm.t_created), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef(ns.bsl.Array), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.BinaryBlob), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Array.Feature), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Array)), + (rdflib.URIRef(ns.bsl.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Time), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Number)), + (rdflib.URIRef(ns.bsn.t_created), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), (rdflib.URIRef(ns.bse.comment), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), (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(bst.representative), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef(bst.label), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef(ns.bst.representative), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef(ns.bst.label), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), } # Nodes constructor args self.user = URI('http://example.com/me') @@ -111,9 +113,9 @@ 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(bst.representative) - self.p_label = self.backend.schema.predicate(bst.label) - self.t_created = self.backend.schema.predicate(ns.bsm.t_created) + self.p_representative = self.backend.schema.predicate(ns.bst.representative) + self.p_label = self.backend.schema.predicate(ns.bst.label) + self.t_created = self.backend.schema.predicate(ns.bsn.t_created) self.ent_ids = { URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321'), @@ -144,11 +146,11 @@ class TestNodes(unittest.TestCase): class Foo(SparqlStore): pass backend = Foo.Open() backend.schema = self.backend.schema - nodes = Nodes(backend, self.ac, self.ent_type, self.ent_ids) - self.assertEqual(repr(nodes), f'Nodes({backend}, {self.ac}, {self.ent_type}, {self.ent_ids})') + nodes = Nodes(backend, self.ac, self.ent_type, {URI('http://example.com/me/entity#1234')}) + self.assertEqual(repr(nodes), f"Nodes({backend}, {self.ac}, {self.ent_type}, {{'http://example.com/me/entity#1234'}})") # repr respects user - nodes = Nodes(self.backend, NullAC(self.backend, URI('http://example.com/you')), self.ent_type, self.ent_ids) - self.assertEqual(repr(nodes), f'Nodes({self.backend}, NullAC(http://example.com/you), {self.ent_type}, {self.ent_ids})') + nodes = Nodes(self.backend, NullAC(self.backend, URI('http://example.com/you')), self.ent_type, {URI('http://example.com/me/entity#1234')}) + self.assertEqual(repr(nodes), f"Nodes({self.backend}, NullAC(http://example.com/you), {self.ent_type}, {{'http://example.com/me/entity#1234'}})") def test_equality(self): nodes = Nodes(self.backend, self.ac, self.ent_type, self.ent_ids) @@ -197,8 +199,8 @@ class TestNodes(unittest.TestCase): # check triples self.assertSetEqual(set(self.backend._graph), self.schema_triples | { # entity definitions - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), # bookkeeping (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), @@ -208,8 +210,8 @@ class TestNodes(unittest.TestCase): self.assertSetEqual(self.ent_ids, nodes._ensure_nodes(self.ent_type, self.ent_ids)) self.assertSetEqual(set(self.backend._graph), self.schema_triples | { # entity definitions - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), # bookkeeping (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), @@ -223,13 +225,13 @@ class TestNodes(unittest.TestCase): # check triples self.assertSetEqual(set(self.backend._graph), self.schema_triples | { # previous triples - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), # new triples - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), + (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), + (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_tag_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_tag_created, datatype=rdflib.XSD.integer)), }) @@ -254,8 +256,8 @@ class TestNodes(unittest.TestCase): # verify triples self.assertSetEqual(set(self.backend._graph), self.schema_triples | { # entity definitions - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), # bookkeeping (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), @@ -273,15 +275,15 @@ class TestNodes(unittest.TestCase): # verify triples self.assertSetEqual(set(self.backend._graph), self.schema_triples | { # previous values - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_ent_created, datatype=rdflib.XSD.integer)), # tag definitions - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), + (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), + (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), # tag bookkeeping (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_tag_created, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.URIRef(self.t_created.uri), rdflib.Literal(t_tag_created, datatype=rdflib.XSD.integer)), @@ -306,8 +308,8 @@ class TestNodes(unittest.TestCase): self.assertEqual(nodes, nodes.set(self.p_filesize.uri, 1234)) self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), # links exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), @@ -316,10 +318,10 @@ class TestNodes(unittest.TestCase): self.assertEqual(nodes, nodes.set(self.p_tag.uri, Nodes(self.backend, self.ac, self.tag_type, self.tag_ids))) self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), + (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), # links exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.p_tag.uri), rdflib.URIRef('http://example.com/me/tag#1234')), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.p_tag.uri), rdflib.URIRef('http://example.com/me/tag#4321')), @@ -360,10 +362,10 @@ class TestNodes(unittest.TestCase): }.items())) self.assertTrue(set(self.backend._graph).issuperset({ # nodes exist - (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity')), - (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), - (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag')), + (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity')), + (rdflib.URIRef('http://example.com/me/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), + (rdflib.URIRef('http://example.com/me/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag')), # links exist (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.URIRef(self.p_filesize.uri), rdflib.Literal(1234, datatype=rdflib.XSD.integer)), @@ -406,9 +408,9 @@ class TestNodes(unittest.TestCase): .set(ns.bse.filesize, 4321) \ .set(ns.bse.tag, Nodes(self.backend, self.ac, self.tag_type, {'http://example.com/me/tag#4321'})) Nodes(self.backend, self.ac, self.tag_type, {'http://example.com/me/tag#1234'}) \ - .set(bst.label, 'tag_label_1234') + .set(ns.bst.label, 'tag_label_1234') Nodes(self.backend, self.ac, self.tag_type, {'http://example.com/me/tag#4321'}) \ - .set(bst.label, 'tag_label_4321') + .set(ns.bst.label, 'tag_label_4321') # setup: get nodes instance nodes = Nodes(self.backend, self.ac, self.ent_type, self.ent_ids) @@ -424,18 +426,18 @@ class TestNodes(unittest.TestCase): Nodes(self.backend, self.ac, 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)), { + self.assertDictEqual(nodes.get((ns.bse.tag, ns.bst.label)), { Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#1234'}): {'tag_label_1234'}, Nodes(self.backend, self.ac, 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.ac, self.ent_type, {'http://example.com/me/entity#1234'}), (ns.bse.tag, bst.label), 'tag_label_1234'), - (Nodes(self.backend, self.ac, 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, ns.bst.label), path=True, view=list)), [ + (Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#1234'}), (ns.bse.tag, ns.bst.label), 'tag_label_1234'), + (Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#4321'}), (ns.bse.tag, ns.bst.label), 'tag_label_4321'), ]) - self.assertCountEqual(list(nodes.get([ns.bse.tag, bst.label], path=True, view=list)), [ - (Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#1234'}), [ns.bse.tag, bst.label], 'tag_label_1234'), - (Nodes(self.backend, self.ac, 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, ns.bst.label], path=True, view=list)), [ + (Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#1234'}), [ns.bse.tag, ns.bst.label], 'tag_label_1234'), + (Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#4321'}), [ns.bse.tag, ns.bst.label], 'tag_label_4321'), ]) # paths must be URI or sequence thereof self.assertRaises(TypeError, nodes.get, 1234) @@ -444,16 +446,16 @@ class TestNodes(unittest.TestCase): self.assertRaises(ValueError, nodes.get, 'hello world') 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)) + self.assertRaises(errors.ConsistencyError, nodes.get, (ns.bse.tag, ns.bst.invalid)) # can pass multiple paths - self.assertDictEqual(nodes.get(ns.bse.filesize, (ns.bse.tag, bst.label)), { + self.assertDictEqual(nodes.get(ns.bse.filesize, (ns.bse.tag, ns.bst.label)), { Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#1234'}): { ns.bse.filesize: 1234, - (ns.bse.tag, bst.label): {'tag_label_1234'}, + (ns.bse.tag, ns.bst.label): {'tag_label_1234'}, }, Nodes(self.backend, self.ac, self.ent_type, {'http://example.com/me/entity#4321'}): { ns.bse.filesize: 4321, - (ns.bse.tag, bst.label): {'tag_label_4321'}, + (ns.bse.tag, ns.bst.label): {'tag_label_4321'}, }, }) # get respects view diff --git a/test/graph/test_resolve.py b/test/graph/test_resolve.py index accb565..e09b1cc 100644 --- a/test/graph/test_resolve.py +++ b/test/graph/test_resolve.py @@ -16,6 +16,8 @@ from bsfs.graph.resolve import Filter ## code ## +ns.bse = ns.bsfs.Entity() + class TestFilter(unittest.TestCase): """ @@ -30,18 +32,20 @@ class TestFilter(unittest.TestCase): 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array . + xsd:integer rdfs:subClassOf bsl:Number . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "5"^^xsd:integer . bse:colors rdfs:subClassOf bsfs:Predicate ; diff --git a/test/graph/test_result.py b/test/graph/test_result.py index 099234a..8960ef6 100644 --- a/test/graph/test_result.py +++ b/test/graph/test_result.py @@ -13,6 +13,8 @@ from bsfs.graph.result import to_list_view, to_dict_view ## code ## +ns.bse = ns.bsfs.Entity() + class TestListView(unittest.TestCase): def setUp(self): self.triples_111 = [('ent#1234', ns.bse.iso, 123)] diff --git a/test/graph/test_walk.py b/test/graph/test_walk.py index 346896b..4b844da 100644 --- a/test/graph/test_walk.py +++ b/test/graph/test_walk.py @@ -15,8 +15,8 @@ from bsfs.graph.walk import Walk ## code ## -bse = ns.bse -bst = Namespace('http://bsfs.ai/schema/Tag') +ns.bse = ns.bsfs.Entity() +ns.bst = ns.bsfs.Tag() class TestWalk(unittest.TestCase): def setUp(self): @@ -24,9 +24,9 @@ class TestWalk(unittest.TestCase): 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#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bst: <https://schema.bsfs.io/core/Tag#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . @@ -73,14 +73,14 @@ class TestWalk(unittest.TestCase): 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') + self.ents.set(ns.bse.tag, self.tags) + self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#1234')).set(ns.bst.label, 'hello') + self.graph.node(ns.bsfs.Tag, URI('http://example.com/me/tag#4321')).set(ns.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) + p_author = self.schema.predicate(ns.bse.author) + p_tag = self.schema.predicate(ns.bse.tag) + p_main = self.schema.predicate(ns.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]))) @@ -96,18 +96,18 @@ class TestWalk(unittest.TestCase): 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)') + 'Walk(@https://schema.bsfs.io/core/Entity: https://schema.bsfs.io/core/Entity#tag, https://schema.bsfs.io/core/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))') + 'Walk(https://schema.bsfs.io/core/Entity, (https://schema.bsfs.io/core/Entity#tag, https://schema.bsfs.io/core/Tag#main))') def test_tail(self): self.assertEqual(Walk(self.ents, ( - self.schema.predicate(bse.tag), + self.schema.predicate(ns.bse.tag), )).tail, self.schema.node(ns.bsfs.Tag)) self.assertEqual(Walk(self.ents, ( - self.schema.predicate(bse.tag), - self.schema.predicate(bst.main), + self.schema.predicate(ns.bse.tag), + self.schema.predicate(ns.bst.main), )).tail, self.schema.node(ns.bsfs.Entity)) @@ -115,24 +115,24 @@ class TestWalk(unittest.TestCase): 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), )) + (self.schema.predicate(ns.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), )) + walk = Walk(self.ents, (self.schema.predicate(ns.bse.tag), )) # first step self.assertEqual(walk.subTagOf, Walk(self.ents, ( - self.schema.predicate(bse.tag), - self.schema.predicate(bst.subTagOf), + self.schema.predicate(ns.bse.tag), + self.schema.predicate(ns.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), + self.schema.predicate(ns.bse.tag), + self.schema.predicate(ns.bst.subTagOf), + self.schema.predicate(ns.bst.main), ))) # invalid step raises an error self.assertRaises(ValueError, getattr, walk, 'foobar') @@ -140,7 +140,7 @@ class TestWalk(unittest.TestCase): self.assertRaises(ValueError, getattr, walk, 'author') def test_get(self): # get, __call__ - walk = Walk(self.ents, (self.schema.predicate(bse.tag), )) + walk = Walk(self.ents, (self.schema.predicate(ns.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'))} diff --git a/test/namespace/test_namespace.py b/test/namespace/test_namespace.py index ec2f393..f7bf02a 100644 --- a/test/namespace/test_namespace.py +++ b/test/namespace/test_namespace.py @@ -7,7 +7,7 @@ import unittest from bsfs.utils import URI # objects to test -from bsfs.namespace.namespace import Namespace, ClosedNamespace +from bsfs.namespace.namespace import Namespace, FinalNamespace ## code ## @@ -15,108 +15,48 @@ from bsfs.namespace.namespace import Namespace, ClosedNamespace class TestNamespace(unittest.TestCase): def test_essentials(self): # string conversion - self.assertEqual(str(Namespace('http://example.org/')), 'http://example.org') - self.assertEqual(str(Namespace('http://example.org#')), 'http://example.org') - self.assertEqual(repr(Namespace('http://example.org/')), 'Namespace(http://example.org, #, /)') - self.assertEqual(repr(Namespace('http://example.org#')), 'Namespace(http://example.org, #, /)') - self.assertEqual(repr(Namespace('http://example.org', fsep='.')), 'Namespace(http://example.org, ., /)') - self.assertEqual(repr(Namespace('http://example.org', psep='.')), 'Namespace(http://example.org, #, .)') - # repeated separators are truncated - self.assertEqual(str(Namespace('http://example.org////')), 'http://example.org') - self.assertEqual(str(Namespace('http://example.org####')), 'http://example.org') - self.assertEqual(repr(Namespace('http://example.org///##')), 'Namespace(http://example.org, #, /)') + self.assertEqual(str(Namespace('http://example.org')), 'http://example.org') + self.assertEqual(repr(Namespace('http://example.org')), "'http://example.org'") # comparison - class Foo(Namespace): pass - self.assertEqual(Namespace('http://example.org/'), Namespace('http://example.org/')) - self.assertEqual(Namespace('http://example.org/'), Namespace('http://example.org')) - self.assertEqual(Namespace('http://example.org/'), Namespace('http://example.org#')) - self.assertNotEqual(Namespace('http://example.org'), Namespace('http://example.org', fsep='.')) - self.assertNotEqual(Namespace('http://example.org'), Namespace('http://example.org', psep='.')) - self.assertNotEqual(Namespace('http://example.org/'), Foo('http://example.org/')) - self.assertNotEqual(Foo('http://example.org/'), Namespace('http://example.org/')) - # hashing - self.assertEqual(hash(Namespace('http://example.org/')), hash(Namespace('http://example.org/'))) - self.assertEqual(hash(Namespace('http://example.org/')), hash(Namespace('http://example.org'))) - self.assertEqual(hash(Namespace('http://example.org/')), hash(Namespace('http://example.org#'))) + self.assertEqual(Namespace('http://example.org'), Namespace('http://example.org')) + self.assertEqual(hash(Namespace('http://example.org')), hash(Namespace('http://example.org'))) + # Namespace compares to string + self.assertEqual(Namespace('http://example.org'), 'http://example.org') + self.assertEqual(hash(Namespace('http://example.org')), hash('http://example.org')) + # URI must match + self.assertNotEqual(Namespace('http://example.org'), Namespace('http://example.com')) self.assertNotEqual(hash(Namespace('http://example.org')), hash(Namespace('http://example.com'))) - self.assertNotEqual(hash(Namespace('http://example.org')), hash(Namespace('http://example.org', fsep='.'))) - self.assertNotEqual(hash(Namespace('http://example.org')), hash(Namespace('http://example.org', psep='.'))) - self.assertNotEqual(hash(Namespace('http://example.org/')), hash(Foo('http://example.org/'))) - self.assertNotEqual(hash(Foo('http://example.org/')), hash(Namespace('http://example.org/'))) def test_getattr(self): - self.assertEqual(Namespace('http://example.org/').foo, 'http://example.org#foo') - self.assertEqual(Namespace('http://example.org/').bar, 'http://example.org#bar') - self.assertEqual(Namespace('http://example.org/', fsep='/').foo, 'http://example.org/foo') - self.assertEqual(Namespace('http://example.org/', fsep='/').bar, 'http://example.org/bar') - self.assertEqual(Namespace('http://example.org', fsep='/').foo, 'http://example.org/foo') - self.assertEqual(Namespace('http://example.org', fsep='/').bar, 'http://example.org/bar') - self.assertEqual(Namespace('http://example.org#', fsep='/').foo, 'http://example.org#/foo') - self.assertEqual(Namespace('http://example.org#', fsep='/').bar, 'http://example.org#/bar') - self.assertEqual(Namespace('http://example.org/me#').foo, 'http://example.org/me#foo') - self.assertEqual(Namespace('http://example.org/me#').bar, 'http://example.org/me#bar') + self.assertEqual(Namespace('http://example.org').foo, Namespace('http://example.org/foo')) + self.assertEqual(Namespace('http://example.org').bar, Namespace('http://example.org/bar')) - def test_getitem(self): - self.assertEqual(Namespace('http://example.org')['foo'], 'http://example.org#foo') - self.assertEqual(Namespace('http://example.org')['bar'], 'http://example.org#bar') - self.assertEqual(Namespace('http://example.org', fsep='/')['foo'], 'http://example.org/foo') - self.assertEqual(Namespace('http://example.org', fsep='/')['bar'], 'http://example.org/bar') - self.assertEqual(Namespace('http://example.org/me#')['foo'], 'http://example.org/me#foo') - self.assertEqual(Namespace('http://example.org/me#')['bar'], 'http://example.org/me#bar') + def test_call(self): + self.assertEqual(Namespace('http://example.org')(), FinalNamespace('http://example.org', sep='#')) + self.assertEqual(Namespace('http://example.org').foo(), FinalNamespace('http://example.org/foo', sep='#')) - def test_add(self): - self.assertEqual(Namespace('http://example.org') + 'foo', Namespace('http://example.org/foo')) - self.assertEqual(Namespace('http://example.org', psep='.') + 'foo', Namespace('http://example.org.foo', psep='.')) - self.assertEqual(Namespace('http://example.org') + 'foo' + 'bar', Namespace('http://example.org/foo/bar')) - # can add URIs - self.assertEqual(Namespace('http://example.org') + URI('foo'), Namespace('http://example.org/foo')) - # can only add strings - self.assertRaises(TypeError, operator.add, Namespace('http://example.org'), 1234) - self.assertRaises(TypeError, operator.add, Namespace('http://example.org'), Namespace('http://example.com')) - - -class TestClosedNamespace(unittest.TestCase): +class TestFinalNamespace(unittest.TestCase): def test_essentials(self): - # string conversion - self.assertEqual(str(ClosedNamespace('http://example.org/')), 'http://example.org') - self.assertEqual(str(ClosedNamespace('http://example.org#')), 'http://example.org') - self.assertEqual(repr(ClosedNamespace('http://example.org/')), 'ClosedNamespace(http://example.org, #, /)') - self.assertEqual(repr(ClosedNamespace('http://example.org#')), 'ClosedNamespace(http://example.org, #, /)') - self.assertEqual(repr(ClosedNamespace('http://example.org', fsep='.')), 'ClosedNamespace(http://example.org, ., /)') - self.assertEqual(repr(ClosedNamespace('http://example.org', psep='.')), 'ClosedNamespace(http://example.org, #, .)') + # string conversion + self.assertEqual(str(FinalNamespace('http://example.org')), 'http://example.org') + self.assertEqual(repr(FinalNamespace('http://example.org')), "'http://example.org'") # comparison - class Foo(ClosedNamespace): pass - self.assertEqual(ClosedNamespace('http://example.org'), ClosedNamespace('http://example.org#')) - self.assertEqual(ClosedNamespace('http://example.org'), ClosedNamespace('http://example.org')) - self.assertEqual(ClosedNamespace('http://example.org'), ClosedNamespace('http://example.org/')) - self.assertEqual(ClosedNamespace('http://example.org/', 'foo', 'bar'), ClosedNamespace('http://example.org/', 'foo', 'bar')) - self.assertNotEqual(ClosedNamespace('http://example.org/', 'foo'), ClosedNamespace('http://example.org/', 'bar')) - self.assertNotEqual(ClosedNamespace('http://example.org/'), Foo('http://example.org/')) - self.assertNotEqual(Foo('http://example.org/'), ClosedNamespace('http://example.org/')) - # hashing - self.assertEqual(hash(ClosedNamespace('http://example.org')), hash(ClosedNamespace('http://example.org'))) - self.assertEqual(hash(ClosedNamespace('http://example.org')), hash(ClosedNamespace('http://example.org/'))) - self.assertEqual(hash(ClosedNamespace('http://example.org')), hash(ClosedNamespace('http://example.org#'))) - self.assertEqual(hash(ClosedNamespace('http://example.org/', 'foo', 'bar')), hash(ClosedNamespace('http://example.org/', 'foo', 'bar'))) - self.assertNotEqual(hash(ClosedNamespace('http://example.org/', 'foo')), hash(ClosedNamespace('http://example.org/', 'bar'))) - self.assertNotEqual(hash(ClosedNamespace('http://example.org/')), hash(Foo('http://example.org/'))) - self.assertNotEqual(hash(Foo('http://example.org/')), hash(ClosedNamespace('http://example.org/'))) + self.assertEqual(FinalNamespace('http://example.org'), FinalNamespace('http://example.org')) + self.assertEqual(hash(FinalNamespace('http://example.org')), hash(FinalNamespace('http://example.org'))) + # FinalNamespace compares to string + self.assertEqual(FinalNamespace('http://example.org'), 'http://example.org') + self.assertEqual(hash(FinalNamespace('http://example.org')), hash('http://example.org')) + # URI must match + self.assertNotEqual(FinalNamespace('http://example.org'), FinalNamespace('http://example.com')) + self.assertNotEqual(hash(FinalNamespace('http://example.org')), hash(FinalNamespace('http://example.com'))) + # separator is ignored + self.assertEqual(FinalNamespace('http://example.org'), FinalNamespace('http://example.org', sep='/')) + self.assertEqual(hash(FinalNamespace('http://example.org')), hash(FinalNamespace('http://example.org', sep='/'))) def test_getattr(self): - self.assertEqual(ClosedNamespace('http://example.org/', 'foo', 'bar').foo, 'http://example.org#foo') - self.assertEqual(ClosedNamespace('http://example.org/', 'bar', 'bar').bar, 'http://example.org#bar') - self.assertEqual(ClosedNamespace('http://example.org/me#', 'foo', 'bar').foo, 'http://example.org/me#foo') - self.assertEqual(ClosedNamespace('http://example.org/me#', 'foo', 'bar').bar, 'http://example.org/me#bar') - self.assertRaises(KeyError, getattr, ClosedNamespace('http://example.org/', 'bar', 'bar'), 'foobar') - self.assertRaises(KeyError, getattr, ClosedNamespace('http://example.org#', 'bar', 'bar'), 'foobar') - - def test_getitem(self): - self.assertEqual(ClosedNamespace('http://example.org/', 'foo', 'bar')['foo'], 'http://example.org#foo') - self.assertEqual(ClosedNamespace('http://example.org/', 'foo', 'bar')['bar'], 'http://example.org#bar') - self.assertEqual(ClosedNamespace('http://example.org/me#', 'foo', 'bar')['foo'], 'http://example.org/me#foo') - self.assertEqual(ClosedNamespace('http://example.org/me#', 'foo', 'bar')['bar'], 'http://example.org/me#bar') - self.assertRaises(KeyError, ClosedNamespace('http://example.org/', 'bar', 'bar').__getitem__, 'foobar') - self.assertRaises(KeyError, ClosedNamespace('http://example.org#', 'bar', 'bar').__getitem__, 'foobar') + self.assertEqual(FinalNamespace('http://example.org').foo, FinalNamespace('http://example.org#foo')) + self.assertEqual(FinalNamespace('http://example.org').bar, FinalNamespace('http://example.org#bar')) + self.assertEqual(FinalNamespace('http://example.org', sep='/').bar, FinalNamespace('http://example.org/bar')) ## main ## diff --git a/test/query/test_validator.py b/test/query/test_validator.py index bbfd2e6..418463e 100644 --- a/test/query/test_validator.py +++ b/test/query/test_validator.py @@ -14,26 +14,29 @@ from bsfs.query.validator import Filter, Fetch ## code ## +ns.bse = ns.bsfs.Entity() + class TestFilter(unittest.TestCase): def setUp(self): self.schema = _schema.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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:URI rdfs:subClassOf bsfs:Literal . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + bsl:Array rdfs:subClassOf bsfs:Literal . + <https://schema.bsfs.io/core/Literal/Array/Feature> rdfs:subClassOf bsl:Array . + xsd:integer rdfs:subClassOf bsl:Number . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf <https://schema.bsfs.io/core/Literal/Array/Feature> ; bsfs:dimension "5"^^xsd:integer ; bsfs:dtype bsfs:f32 . @@ -267,10 +270,10 @@ class TestFilter(unittest.TestCase): self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.node(ns.bsfs.Node), ast.filter.Distance([1,2,3], 1, False)) # type must be a feature - self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.literal(ns.bsfs.Array), + self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.literal(ns.bsl.Array), ast.filter.Distance([1,2,3], 1, False)) # type must be in the schema - self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.literal(ns.bsfs.Feature).child(ns.bsfs.Invalid), + self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.literal(ns.bsl.Array.Feature).child(ns.bsfs.Invalid), ast.filter.Distance([1,2,3], 1, False)) # FIXME: reference must be a numpy array # reference must have the correct dimension @@ -287,8 +290,8 @@ class TestFetch(unittest.TestCase): 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . diff --git a/test/schema/test_schema.py b/test/schema/test_schema.py index f9ddb68..f52cf95 100644 --- a/test/schema/test_schema.py +++ b/test/schema/test_schema.py @@ -14,6 +14,8 @@ from bsfs.schema.schema import Schema ## code ## +ns.bse = ns.bsfs.Entity() + class TestSchema(unittest.TestCase): def setUp(self): @@ -21,8 +23,9 @@ class TestSchema(unittest.TestCase): 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . @@ -31,7 +34,7 @@ class TestSchema(unittest.TestCase): xsd:string rdfs:subClassOf bsfs:Literal . bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + xsd:integer rdfs:subClassOf bsl:Number . xsd:boolean rdfs:subClassOf bsfs:Literal . bse:tag rdfs:subClassOf bsfs:Predicate ; @@ -174,13 +177,13 @@ class TestSchema(unittest.TestCase): self.assertEqual(str(Schema(self.predicates, self.nodes, self.literals)), 'Schema()') # repr conversion with only default nodes, literals, and predicates n = [ns.bsfs.Node] - l = [ns.bsfs.Array, ns.bsfs.BinaryBlob, ns.bsfs.Feature, ns.bsfs.Literal, ns.bsfs.Number, ns.bsfs.Time] + l = [ns.bsfs.Literal, ns.bsl.Array, ns.bsl.Array.Feature, ns.bsl.BinaryBlob, ns.bsl.Number, ns.bsl.Time] p = [ns.bsfs.Predicate] self.assertEqual(repr(Schema()), f'Schema({n}, {l}, {p})') self.assertEqual(repr(Schema([], [], [])), f'Schema({n}, {l}, {p})') # repr conversion n = [ns.bsfs.Entity, ns.bsfs.Image, ns.bsfs.Node, ns.bsfs.Tag, ns.bsfs.Unused] - l = [ns.bsfs.Array, ns.bsfs.BinaryBlob, ns.bsfs.Feature, ns.bsfs.Literal, ns.bsfs.Number, ns.bsfs.Time, ns.xsd.boolean, ns.xsd.integer, ns.xsd.string] + l = [ns.xsd.boolean, ns.xsd.integer, ns.xsd.string, ns.bsfs.Literal, ns.bsl.Array, ns.bsl.Array.Feature, ns.bsl.BinaryBlob, ns.bsl.Number, ns.bsl.Time] p = [ns.bse.comment, ns.bse.group, ns.bse.tag, ns.bsfs.Predicate] self.assertEqual(repr(Schema(self.predicates, self.nodes, self.literals)), f'Schema({n}, {l}, {p})') diff --git a/test/schema/test_serialize.py b/test/schema/test_serialize.py index 84512e9..7d5d3ae 100644 --- a/test/schema/test_serialize.py +++ b/test/schema/test_serialize.py @@ -14,6 +14,8 @@ from bsfs.schema.serialize import from_string, to_string ## code ## +ns.bse = ns.bsfs.Entity() + class TestFromString(unittest.TestCase): def test_empty(self): @@ -25,7 +27,7 @@ class TestFromString(unittest.TestCase): # must not have circular dependencies self.assertRaises(errors.ConsistencyError, from_string, ''' prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix bsfs: <http://bsfs.ai/schema/> + prefix bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node . # ah, a nice circular dependency bsfs:Entity rdfs:subClassOf bsfs:Document . @@ -39,8 +41,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> xsd:string rdfs:subClassOf bsfs:Literal . @@ -54,7 +56,7 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Document rdfs:subClassOf bsfs:Node . @@ -66,8 +68,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({}, {n_unused}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:unused rdfs:subClassOf bsfs:Node . # unused symbol ''')) @@ -80,8 +82,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({}, {n_ent, n_tag, n_doc, n_image}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> # nodes inherit from same parent bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -100,8 +102,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_filename}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . @@ -116,7 +118,7 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -124,7 +126,7 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node ; rdfs:label "hello world"^^xsd:string ; @@ -141,8 +143,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -156,7 +158,7 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> xsd:string rdfs:subClassOf bsfs:Literal . xsd:name rdfs:subClassOf bsfs:Literal . @@ -168,8 +170,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({}, {}, {l_unused}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> xsd:unused rdfs:subClassOf bsfs:Literal . # unused symbol ''')) @@ -182,13 +184,14 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({}, {}, {l_string, l_integer, l_unsigned, l_signed}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> # literals inherit from same parent xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . # literals inherit from same parent xsd:unsigned rdfs:subClassOf xsd:integer . @@ -203,8 +206,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_filename}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . @@ -219,7 +222,7 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> xsd:string rdfs:subClassOf bsfs:Literal . @@ -227,7 +230,7 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> xsd:string rdfs:subClassOf bsfs:Literal ; rdfs:label "hello world"^^xsd:string ; @@ -244,8 +247,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> xsd:string rdfs:subClassOf bsfs:Literal . @@ -258,8 +261,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Literal . xsd:string rdfs:subClassOf bsfs:Literal . @@ -274,8 +277,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -288,8 +291,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -302,8 +305,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -320,8 +323,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_comment}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . @@ -340,8 +343,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_comment}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . @@ -362,8 +365,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_comment}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . @@ -383,8 +386,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_foo}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -405,8 +408,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_foobar}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Image rdfs:subClassOf bsfs:Entity . @@ -421,8 +424,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Image rdfs:subClassOf bsfs:Entity . @@ -444,8 +447,8 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema({p_foobar}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Image rdfs:subClassOf bsfs:Entity . @@ -460,8 +463,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Image rdfs:subClassOf bsfs:Entity . @@ -478,8 +481,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Annotation rdfs:subClassOf bsfs:Predicate . @@ -499,8 +502,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -516,8 +519,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -533,8 +536,8 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -551,8 +554,8 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bse:comment rdfs:subClassOf bsfs:Predicate ; rdfs:range bsfs:Node . @@ -561,8 +564,8 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bse:comment rdfs:subClassOf bsfs:Predicate ; rdfs:range bsfs:Node ; @@ -581,70 +584,78 @@ class TestFromString(unittest.TestCase): self.assertEqual(Schema(literals={f_colors}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature . + bsfs:Colors rdfs:subClassOf bsa:Feature . ''')) # features inherit properties from parents - f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors, dimension=1234, dtype=ns.bsfs.i32) - f_main_colors = f_colors.child(ns.bsfs.MainColor, distance=ns.bsfs.cosine, dtype=ns.bsfs.f16) + f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors, dimension=1234, dtype=ns.bsfs.dtype().i32) + f_main_colors = f_colors.child(ns.bsfs.MainColor, distance=ns.bsfs.cosine, dtype=ns.bsfs.dtype().f16) self.assertEqual(Schema(literals={f_colors, f_main_colors}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; # inherits distance from bsfs:Feature - bsfs:dimension "1234"^^xsd:integer ; # overwrites bsfs:Feature - bsfs:dtype bsfs:i32 . # overwrites bsfs:Feature + bsfs:Colors rdfs:subClassOf bsa:Feature ; # inherits distance from bsa:Feature + bsfs:dimension "1234"^^xsd:integer ; # overwrites bsa:Feature + bsfs:dtype <https://schema.bsfs.io/core/dtype#i32> . # overwrites bsa:Feature bsfs:MainColor rdfs:subClassOf bsfs:Colors ; # inherits dimension from bsfs:Colors - bsfs:distance bsfs:cosine ; # overwrites bsfs:Feature - bsfs:dtype bsfs:f16 . # overwrites bsfs:Colors + bsfs:distance bsfs:cosine ; # overwrites bsa:Feature + bsfs:dtype <https://schema.bsfs.io/core/dtype#f16> . # overwrites bsfs:Colors ''')) # feature definition can be split across multiple statements. # statements can be repeated - f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors, dimension=1234, dtype=ns.bsfs.f32) + f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors, dimension=1234, dtype=ns.bsfs.dtype().f32) self.assertEqual(Schema(literals={f_colors}), 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "1234"^^xsd:integer . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "1234"^^xsd:integer ; # non-conflicting repetition - bsfs:dtype bsfs:f32 . + bsfs:dtype <https://schema.bsfs.io/core/dtype#f32> . ''')) # cannot define the same feature from multiple parents self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. - bsfs:ColorSpace rdfs:subClassOf bsfs:Feature . + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. + bsfs:ColorSpace rdfs:subClassOf bsa:Feature . - bsfs:Colors rdfs:subClassOf bsfs:Feature . + bsfs:Colors rdfs:subClassOf bsa:Feature . bsfs:Colors rdfs:subClassOf bsfs:ColorSpace . ''') @@ -652,16 +663,18 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "1234"^^xsd:integer . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "4321"^^xsd:integer . # conflicting dimension ''') @@ -669,32 +682,36 @@ class TestFromString(unittest.TestCase): self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; - bsfs:dtype bsfs:f32 . + bsfs:Colors rdfs:subClassOf bsa:Feature ; + bsfs:dtype <https://schema.bsfs.io/core/dtype#i32> . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; - bsfs:dtype bsfs:f16 . # conflicting dtype + bsfs:Colors rdfs:subClassOf bsa:Feature ; + bsfs:dtype <https://schema.bsfs.io/core/dtype#f16> . # conflicting dtype ''') # cannot assign multiple conflicting distance metrics to the same feature self.assertRaises(errors.ConsistencyError, 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:distance bsfs:euclidean . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:distance bsfs:cosine . # conflicting distance ''') @@ -702,26 +719,30 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "1234"^^xsd:integer . ''').literal(ns.bsfs.Colors).annotations, {}) self.assertDictEqual(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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "1234"^^xsd:integer ; rdfs:label "hello world"^^xsd:string ; bsfs:foo "1234"^^xsd:integer . @@ -748,10 +769,10 @@ class TestFromString(unittest.TestCase): p_group = p_tag.child(ns.bse.group, domain=n_image, unique=True) p_comment = p_annotation.child(ns.bse.comment, range=l_string) # features - f_colors = types.ROOT_FEATURE.child(URI('http://bsfs.ai/schema/Feature/colors_spatial'), - dtype=ns.bsfs.f16, distance=ns.bsfs.euclidean) - f_colors1234 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors_spatial#1234'), dimension=1024) - f_colors4321 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors_spatial#4321'), dimension=2048) + f_colors = types.ROOT_FEATURE.child(URI('https://schema.bsfs.io/core/Feature/colors_spatial'), + dtype=ns.bsfs.dtype().f16, distance=ns.bsfs.euclidean) + f_colors1234 = f_colors.child(URI('https://schema.bsfs.io/core/Feature/colors_spatial#1234'), dimension=1024) + f_colors4321 = f_colors.child(URI('https://schema.bsfs.io/core/Feature/colors_spatial#4321'), dimension=2048) # schema ref = Schema( {p_annotation, p_tag, p_group, p_comment}, @@ -764,8 +785,10 @@ class TestFromString(unittest.TestCase): prefix xsd: <http://www.w3.org/2001/XMLSchema#> # bsfs prefixes - prefix bsfs: <http://bsfs.ai/schema/> - prefix bse: <http://bsfs.ai/schema/Entity#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> # nodes bsfs:Entity rdfs:subClassOf bsfs:Node ; @@ -777,10 +800,10 @@ class TestFromString(unittest.TestCase): # literals xsd:string rdfs:subClassOf bsfs:Literal ; rdfs:label "A sequence of characters"^^xsd:string . - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array. - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array. + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . xsd:boolean rdfs:subClassOf bsfs:Literal . @@ -789,19 +812,19 @@ class TestFromString(unittest.TestCase): rdfs:label "node annotation"^^xsd:string . # feature instances - <http://bsfs.ai/schema/Feature/colors_spatial> rdfs:subClassOf bsfs:Feature ; - bsfs:dtype bsfs:f16 ; + <https://schema.bsfs.io/core/Feature/colors_spatial> rdfs:subClassOf bsa:Feature ; + bsfs:dtype <https://schema.bsfs.io/core/dtype#f16> ; bsfs:distance bsfs:euclidean ; # annotations rdfs:label "ColorsSpatial instances. Dimension depends on instance."^^xsd:string ; bsfs:first_arg "1234"^^xsd:integer ; bsfs:second_arg "hello world"^^xsd:string . - <http://bsfs.ai/schema/Feature/colors_spatial#1234> rdfs:subClassOf <http://bsfs.ai/schema/Feature/colors_spatial> ; + <https://schema.bsfs.io/core/Feature/colors_spatial#1234> rdfs:subClassOf <https://schema.bsfs.io/core/Feature/colors_spatial> ; bsfs:dimension "1024"^^xsd:integer ; rdfs:label "Main colors spatial instance"^^xsd:string . - <http://bsfs.ai/schema/Feature/colors_spatial#4321> rdfs:subClassOf <http://bsfs.ai/schema/Feature/colors_spatial> ; + <https://schema.bsfs.io/core/Feature/colors_spatial#4321> rdfs:subClassOf <https://schema.bsfs.io/core/Feature/colors_spatial> ; bsfs:dimension "2048"^^xsd:integer . # predicate instances @@ -829,19 +852,19 @@ class TestFromString(unittest.TestCase): self.assertDictEqual(gen.node(ns.bsfs.Tag).annotations, {ns.rdfs.label: 'Tag'}) self.assertDictEqual(gen.literal(ns.xsd.string).annotations, {ns.rdfs.label: 'A sequence of characters'}) self.assertDictEqual(gen.predicate(ns.bsfs.Annotation).annotations, {ns.rdfs.label: 'node annotation'}) - self.assertDictEqual(gen.literal(URI('http://bsfs.ai/schema/Feature/colors_spatial')).annotations, { + self.assertDictEqual(gen.literal(URI('https://schema.bsfs.io/core/Feature/colors_spatial')).annotations, { ns.rdfs.label: 'ColorsSpatial instances. Dimension depends on instance.', ns.bsfs.first_arg: 1234, ns.bsfs.second_arg: 'hello world', }) - self.assertDictEqual(gen.literal(URI('http://bsfs.ai/schema/Feature/colors_spatial#1234')).annotations, { + self.assertDictEqual(gen.literal(URI('https://schema.bsfs.io/core/Feature/colors_spatial#1234')).annotations, { ns.rdfs.label: 'Main colors spatial instance'}) self.assertDictEqual(gen.predicate(ns.bse.tag).annotations, {ns.rdfs.label: 'connect entity to a tag'}) # blank nodes result in an error self.assertRaises(errors.BackendError, from_string, ''' prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> - prefix bsfs: <http://bsfs.ai/schema/> + prefix bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node ; bsfs:foo _:bar . ''') @@ -976,29 +999,29 @@ class TestToString(unittest.TestCase): def test_feature(self): # root features - f_colors = types.ROOT_FEATURE.child(URI('http://bsfs.ai/schema/Feature/colors'), + f_colors = types.ROOT_FEATURE.child(URI('https://schema.bsfs.io/core/Feature/colors'), distance=ns.bsfs.cosine) # derived features - f_colors1234 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors#1234'), + f_colors1234 = f_colors.child(URI('https://schema.bsfs.io/core/Feature/colors#1234'), dimension=1024) # inherits dtype, distance - f_colors4321 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors#4321'), + f_colors4321 = f_colors.child(URI('https://schema.bsfs.io/core/Feature/colors#4321'), dimension=2048, distance=ns.bsfs.euclidean) # inherits dtype # create schema schema = Schema(literals={f_colors, f_colors1234, f_colors4321}) schema_str = to_string(schema) # all symbols are serialized - self.assertIn('bsfs:Array', schema_str) - self.assertIn('<http://bsfs.ai/schema/Feature/colors', schema_str) - self.assertIn('<http://bsfs.ai/schema/Feature/colors#1234', schema_str) - self.assertIn('<http://bsfs.ai/schema/Feature/colors#4321', schema_str) + self.assertIn('bsl:Array', schema_str) + self.assertIn('<https://schema.bsfs.io/core/Feature/colors', schema_str) + self.assertIn('<https://schema.bsfs.io/core/Feature/colors#1234', schema_str) + self.assertIn('<https://schema.bsfs.io/core/Feature/colors#4321', schema_str) # inherited properties are not serialized - self.assertIsNotNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#1234>[^\.]*bsfs:dimension[^\.]', schema_str)) - self.assertIsNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#1234>[^\.]*bsfs:dtype[^\.]', schema_str)) - self.assertIsNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#1234>[^\.]*bsfs:distance[^\.]', schema_str)) - self.assertIsNotNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#4321>[^\.]*bsfs:dimension[^\.]', schema_str)) - self.assertIsNotNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#4321>[^\.]*bsfs:distance[^\.]', schema_str)) - self.assertIsNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#4321>[^\.]*bsfs:dtype[^\.]', schema_str)) + self.assertIsNotNone(re.search(r'<https://schema.bsfs\.io/core/Feature/colors#1234>.*[^\.]*bsfs:dimension[^\.]', schema_str)) + self.assertIsNone(re.search(r'<https://schema\.bsfs\.io/core/Feature/colors#1234>.*[^\.]*bsfs:dtype[^\.]', schema_str)) + self.assertIsNone(re.search(r'<https://schema\.bsfs\.io/core/Feature/colors#1234>.*[^\.]*bsfs:distance[^\.]', schema_str)) + self.assertIsNotNone(re.search(r'<https://schema\.bsfs\.io/core/Feature/colors#4321>.*[^\.]*bsfs:dimension[^\.]', schema_str)) + self.assertIsNotNone(re.search(r'<https://schema\.bsfs\.io/core/Feature/colors#4321>.*[^\.]*bsfs:distance[^\.]', schema_str)) + self.assertIsNone(re.search(r'<https://schema\.bsfs\.io/core/Feature/colors#4321>.*[^\.]*bsfs:dtype[^\.]', schema_str)) # unserialize yields the original schema self.assertEqual(schema, from_string(schema_str)) @@ -1009,12 +1032,12 @@ class TestToString(unittest.TestCase): ns.bsfs.foo: 1234, ns.bsfs.bar: False, } - f_colors = types.ROOT_FEATURE.child(URI('http://bsfs.ai/schema/Feature/colors'), - dtype=ns.bsfs.f16, distance=ns.bsfs.euclidean, + f_colors = types.ROOT_FEATURE.child(URI('https://schema.bsfs.io/core/Feature/colors'), + dtype=ns.bsfs.dtype().f16, distance=ns.bsfs.euclidean, **annotations) self.assertDictEqual( annotations, - from_string(to_string(Schema(literals={f_colors}))).literal(URI('http://bsfs.ai/schema/Feature/colors')).annotations) + from_string(to_string(Schema(literals={f_colors}))).literal(URI('https://schema.bsfs.io/core/Feature/colors')).annotations) ## main ## diff --git a/test/schema/test_types.py b/test/schema/test_types.py index f87d857..9bfa8c5 100644 --- a/test/schema/test_types.py +++ b/test/schema/test_types.py @@ -14,6 +14,8 @@ from bsfs.schema.types import _Type, Vertex, Node, Literal, Predicate, Feature ## code ## +ns.bse = ns.bsfs.Entity() + class TestType(unittest.TestCase): def test_parents(self): diff --git a/test/triple_store/sparql/test_parse_fetch.py b/test/triple_store/sparql/test_parse_fetch.py index 9284608..1d793e7 100644 --- a/test/triple_store/sparql/test_parse_fetch.py +++ b/test/triple_store/sparql/test_parse_fetch.py @@ -15,10 +15,9 @@ from bsfs.triple_store.sparql.parse_fetch import Fetch ## code ## -bsfs = Namespace('http://bsfs.ai/schema', fsep='/') -bse = Namespace('http://bsfs.ai/schema/Entity') -bst = Namespace('http://bsfs.ai/schema/Tag') -bsc = Namespace('http://bsfs.ai/schema/Collection') +ns.bse = ns.bsfs.Entity() +ns.bst = ns.bsfs.Tag() +ns.bsc = ns.bsfs.Collection() class TestParseFetch(unittest.TestCase): @@ -27,10 +26,10 @@ class TestParseFetch(unittest.TestCase): 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#> - prefix bsc: <http://bsfs.ai/schema/Collection#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bst: <https://schema.bsfs.io/core/Tag#> + prefix bsc: <https://schema.bsfs.io/core/Collection#> # nodes bsfs:Entity rdfs:subClassOf bsfs:Node . @@ -83,43 +82,43 @@ class TestParseFetch(unittest.TestCase): # graph to test queries self.graph = rdflib.Graph() # schema hierarchies - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Entity'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Node'))) - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Collection'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Node'))) - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Tag'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Node'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Entity'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Node'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Collection'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Node'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Tag'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Node'))) # entities - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity'))) - self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) # tags - self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag'))) - self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag'))) # collections - self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Collection'))) - self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Collection'))) + self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Collection'))) + self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Collection'))) # entity literals - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(bse.rank), rdflib.Literal('1234', datatype=rdflib.XSD.integer))) - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(bse.filename), rdflib.Literal('filename_1234', datatype=rdflib.XSD.string))) - #self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(bse.rank), rdflib.Literal('4321', datatype=rdflib.XSD.integer))) - self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(bse.filename), rdflib.Literal('filename_4321', datatype=rdflib.XSD.string))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.rank), rdflib.Literal('1234', datatype=rdflib.XSD.integer))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.filename), rdflib.Literal('filename_1234', datatype=rdflib.XSD.string))) + #self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(ns.bse.rank), rdflib.Literal('4321', datatype=rdflib.XSD.integer))) + self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(ns.bse.filename), rdflib.Literal('filename_4321', datatype=rdflib.XSD.string))) # tag literals - self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.URIRef(bst.label), rdflib.Literal('tag_label_1234', datatype=rdflib.XSD.string))) - self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.URIRef(bst.label), rdflib.Literal('tag_label_4321', datatype=rdflib.XSD.string))) + self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.URIRef(ns.bst.label), rdflib.Literal('tag_label_1234', datatype=rdflib.XSD.string))) + self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.URIRef(ns.bst.label), rdflib.Literal('tag_label_4321', datatype=rdflib.XSD.string))) # collection literals - self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(bsc.label), rdflib.Literal('collection_label_1234', datatype=rdflib.XSD.string))) - self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(bsc.rating), rdflib.Literal('1234', datatype=rdflib.XSD.integer))) - self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(bsc.label), rdflib.Literal('collection_label_4321', datatype=rdflib.XSD.string))) - self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(bsc.rating), rdflib.Literal('4321', datatype=rdflib.XSD.integer))) + self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(ns.bsc.label), rdflib.Literal('collection_label_1234', datatype=rdflib.XSD.string))) + self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(ns.bsc.rating), rdflib.Literal('1234', datatype=rdflib.XSD.integer))) + self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(ns.bsc.label), rdflib.Literal('collection_label_4321', datatype=rdflib.XSD.string))) + self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(ns.bsc.rating), rdflib.Literal('4321', datatype=rdflib.XSD.integer))) # entity-tag links - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(bse.tag), rdflib.URIRef('http://example.com/tag#1234'))) - self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(bse.tag), rdflib.URIRef('http://example.com/tag#4321'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.tag), rdflib.URIRef('http://example.com/tag#1234'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(ns.bse.tag), rdflib.URIRef('http://example.com/tag#4321'))) # entity-collection links - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(bse.collection), rdflib.URIRef('http://example.com/collection#1234'))) - self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(bse.collection), rdflib.URIRef('http://example.com/collection#4321'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.collection), rdflib.URIRef('http://example.com/collection#1234'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef(ns.bse.collection), rdflib.URIRef('http://example.com/collection#4321'))) # collection-tag links - self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(bsc.tag), rdflib.URIRef('http://example.com/tag#1234'))) - self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(bsc.tag), rdflib.URIRef('http://example.com/tag#4321'))) + self.graph.add((rdflib.URIRef('http://example.com/collection#1234'), rdflib.URIRef(ns.bsc.tag), rdflib.URIRef('http://example.com/tag#1234'))) + self.graph.add((rdflib.URIRef('http://example.com/collection#4321'), rdflib.URIRef(ns.bsc.tag), rdflib.URIRef('http://example.com/tag#4321'))) # tag-entity links # NOTE: cross-over - self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.URIRef(bst.main), rdflib.URIRef('http://example.com/entity#4321'))) - self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.URIRef(bst.main), rdflib.URIRef('http://example.com/entity#1234'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.URIRef(ns.bst.main), rdflib.URIRef('http://example.com/entity#4321'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.URIRef(ns.bst.main), rdflib.URIRef('http://example.com/entity#1234'))) # default parser self.parser = Fetch(self.schema) @@ -135,7 +134,7 @@ class TestParseFetch(unittest.TestCase): # __call__ requires a parseable root self.assertRaises(errors.BackendError, self.parser, self.ent, ast.filter.FilterExpression()) # __call__ returns an executable query - q = self.parser(self.ent, ast.fetch.Fetch(bse.tag, ast.fetch.Value(bst.label, 'label'))) + q = self.parser(self.ent, ast.fetch.Fetch(ns.bse.tag, ast.fetch.Value(ns.bst.label, 'label'))) self.assertSetEqual(set(q(self.graph)), { (rdflib.URIRef('http://example.com/entity#1234'), rdflib.Literal('tag_label_1234', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/entity#4321'), rdflib.Literal('tag_label_4321', datatype=rdflib.XSD.string)), @@ -149,8 +148,8 @@ class TestParseFetch(unittest.TestCase): def test_all(self): # multiple values query q = self.parser(self.ent, ast.fetch.All( - ast.fetch.Value(bse.filename, name='filename'), - ast.fetch.Value(bse.rank, name='rank')), + ast.fetch.Value(ns.bse.filename, name='filename'), + ast.fetch.Value(ns.bse.rank, name='rank')), ) self.assertSetEqual(set(q.names), {'filename', 'rank'}) if q.names == ('filename', 'rank'): @@ -165,8 +164,8 @@ class TestParseFetch(unittest.TestCase): }) # mixed values and node query q = self.parser(self.ent, ast.fetch.All( - ast.fetch.Value(bse.filename, name='filename'), - ast.fetch.Node(bse.tag, name='tag'), + ast.fetch.Value(ns.bse.filename, name='filename'), + ast.fetch.Node(ns.bse.tag, name='tag'), )) self.assertSetEqual(set(q.names), {'filename', 'tag'}) if q.names == ('filename', 'tag'): @@ -180,9 +179,9 @@ class TestParseFetch(unittest.TestCase): (rdflib.URIRef('http://example.com/entity#4321'), rdflib.URIRef('http://example.com/tag#4321'), rdflib.Literal('filename_4321', datatype=rdflib.XSD.string)), }) # multiple values and second hop - q = self.parser(self.ent, ast.fetch.Fetch(bse.tag, ast.fetch.All( + q = self.parser(self.ent, ast.fetch.Fetch(ns.bse.tag, ast.fetch.All( ast.fetch.This(name='tag'), - ast.fetch.Value(bst.label, name='label'), + ast.fetch.Value(ns.bst.label, name='label'), ))) self.assertSetEqual(set(q.names), {'tag', 'label'}) if q.names == ('tag', 'label'): @@ -200,13 +199,13 @@ class TestParseFetch(unittest.TestCase): def test_fetch(self): # two-hop query - q = self.parser(self.ent, ast.fetch.Fetch(bse.tag, ast.fetch.Value(bst.label, 'tag_label'))) + q = self.parser(self.ent, ast.fetch.Fetch(ns.bse.tag, ast.fetch.Value(ns.bst.label, 'tag_label'))) self.assertSetEqual(set(q(self.graph)), { (rdflib.URIRef('http://example.com/entity#1234'), rdflib.Literal('tag_label_1234', datatype=rdflib.XSD.string)), (rdflib.URIRef('http://example.com/entity#4321'), rdflib.Literal('tag_label_4321', datatype=rdflib.XSD.string)), }) # three-hop-query - q = self.parser(self.ent, ast.fetch.Fetch(bse.tag, ast.fetch.Fetch(bst.main, ast.fetch.Value(bse.rank, 'entity_rank')))) + q = self.parser(self.ent, ast.fetch.Fetch(ns.bse.tag, ast.fetch.Fetch(ns.bst.main, ast.fetch.Value(ns.bse.rank, 'entity_rank')))) self.assertSetEqual(set(q(self.graph)), { (rdflib.URIRef('http://example.com/entity#1234'), None), (rdflib.URIRef('http://example.com/entity#4321'), rdflib.Literal('1234', datatype=rdflib.XSD.integer)), @@ -215,9 +214,9 @@ class TestParseFetch(unittest.TestCase): def test_node(self): # cannot use the internal hop name - self.assertRaises(errors.BackendError, self.parser, self.ent, ast.fetch.Node(bse.tag, self.parser.ngen.prefix[1:] + '123')) + self.assertRaises(errors.BackendError, self.parser, self.ent, ast.fetch.Node(ns.bse.tag, self.parser.ngen.prefix[1:] + '123')) # a simple Node statement - q = self.parser(self.ent, ast.fetch.Node(bse.tag, 'tag')) + q = self.parser(self.ent, ast.fetch.Node(ns.bse.tag, 'tag')) self.assertSetEqual(set(q.names), {'tag'}) self.assertSetEqual(set(q(self.graph)), { (rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef('http://example.com/tag#1234')), @@ -227,9 +226,9 @@ class TestParseFetch(unittest.TestCase): def test_value(self): # cannot use the internal hop name - self.assertRaises(errors.BackendError, self.parser, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(bse.filename, self.parser.ngen.prefix[1:] + '123')) + self.assertRaises(errors.BackendError, self.parser, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, self.parser.ngen.prefix[1:] + '123')) # a simple Value statement - q = self.parser(self.ent, ast.fetch.Value(bse.filename, 'filename')) + q = self.parser(self.ent, ast.fetch.Value(ns.bse.filename, 'filename')) self.assertSetEqual(set(q.names), {'filename'}) self.assertSetEqual(set(q(self.graph)), { (rdflib.URIRef('http://example.com/entity#1234'), rdflib.Literal('filename_1234', datatype=rdflib.XSD.string)), diff --git a/test/triple_store/sparql/test_parse_filter.py b/test/triple_store/sparql/test_parse_filter.py index 5b6ca8a..a45f2ef 100644 --- a/test/triple_store/sparql/test_parse_filter.py +++ b/test/triple_store/sparql/test_parse_filter.py @@ -15,6 +15,8 @@ from bsfs.triple_store.sparql.parse_filter import Filter ## code ## +ns.bse = ns.bsfs.Entity() + class TestParseFilter(unittest.TestCase): def setUp(self): # schema @@ -22,25 +24,28 @@ class TestParseFilter(unittest.TestCase): 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsd: <https://schema.bsfs.io/core/distance#> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array . - bsfs:Number rdfs:subClassOf bsfs:Literal . + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array . + bsl:Number rdfs:subClassOf bsfs:Literal . bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Image rdfs:subClassOf bsfs:Entity . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + xsd:integer rdfs:subClassOf bsl:Number . bsfs:URI rdfs:subClassOf bsfs:Literal . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "4"^^xsd:integer ; bsfs:dtype xsd:integer ; - bsfs:distance bsfs:euclidean . + bsfs:distance bsd:euclidean . bse:colors rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; @@ -81,18 +86,18 @@ class TestParseFilter(unittest.TestCase): # graph to test queries self.graph = rdflib.Graph() # schema hierarchies - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Entity'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Node'))) - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Image'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Entity'))) - self.graph.add((rdflib.URIRef('http://bsfs.ai/schema/Tag'), rdflib.RDFS.subClassOf, rdflib.URIRef('http://bsfs.ai/schema/Node'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Entity'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Node'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Image'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) + self.graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Tag'), rdflib.RDFS.subClassOf, rdflib.URIRef('https://schema.bsfs.io/core/Node'))) # entities - self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity'))) - self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Entity'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) + self.graph.add((rdflib.URIRef('http://example.com/entity#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) # tags - self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag'))) - self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Tag'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag'))) + self.graph.add((rdflib.URIRef('http://example.com/tag#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Tag'))) # images - self.graph.add((rdflib.URIRef('http://example.com/image#1234'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Image'))) - self.graph.add((rdflib.URIRef('http://example.com/image#4321'), rdflib.RDF.type, rdflib.URIRef('http://bsfs.ai/schema/Image'))) + self.graph.add((rdflib.URIRef('http://example.com/image#1234'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Image'))) + self.graph.add((rdflib.URIRef('http://example.com/image#4321'), rdflib.RDF.type, rdflib.URIRef('https://schema.bsfs.io/core/Image'))) # node comments self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.comment), rdflib.Literal('Me, Myself, and I', datatype=rdflib.XSD.string))) self.graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.comment), rdflib.Literal('hello world', datatype=rdflib.XSD.string))) diff --git a/test/triple_store/sparql/test_sparql.py b/test/triple_store/sparql/test_sparql.py index f45ca37..a7e7d37 100644 --- a/test/triple_store/sparql/test_sparql.py +++ b/test/triple_store/sparql/test_sparql.py @@ -15,22 +15,25 @@ from bsfs.triple_store.sparql.sparql import SparqlStore ## code ## +ns.bse = ns.bsfs.Entity() + class TestSparqlStore(unittest.TestCase): def setUp(self): 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . bsfs:User rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - bsfs:BinaryBlob rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + bsl:BinaryBlob rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . # non-unique literal bse:comment rdfs:subClassOf bsfs:Predicate ; @@ -59,7 +62,7 @@ class TestSparqlStore(unittest.TestCase): # binary range bse:asset rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; - rdfs:range bsfs:BinaryBlob . + rdfs:range bsl:BinaryBlob . ''') self.schema_triples = { @@ -68,12 +71,12 @@ class TestSparqlStore(unittest.TestCase): (rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)), (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)), - (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)), + (rdflib.URIRef(ns.bsl.Array), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.BinaryBlob), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Array.Feature), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Array)), + (rdflib.URIRef(ns.bsl.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Time), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Number)), (rdflib.URIRef(ns.bse.comment), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), (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)), @@ -101,7 +104,7 @@ class TestSparqlStore(unittest.TestCase): store.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 bsfs: <https://schema.bsfs.io/core/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Document rdfs:subClassOf bsfs:Entity . @@ -206,10 +209,10 @@ class TestSparqlStore(unittest.TestCase): curr = curr + 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#> - prefix bsc: <http://bsfs.ai/schema/Collection#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bst: <https://schema.bsfs.io/core/Tag#> + prefix bsc: <https://schema.bsfs.io/core/Collection#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . @@ -255,16 +258,16 @@ class TestSparqlStore(unittest.TestCase): (rdflib.URIRef(ns.xsd.boolean), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), (rdflib.URIRef(ns.bse.shared), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), (rdflib.URIRef(ns.bse.partOf), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Tag#usedIn'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Collection#tag'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Tag#usedIn'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Collection#tag'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), }) # add some instances of the new classes p_partOf = curr.predicate(ns.bse.partOf) p_shared = curr.predicate(ns.bse.shared) - p_usedIn = curr.predicate('http://bsfs.ai/schema/Tag#usedIn') - p_ctag = curr.predicate('http://bsfs.ai/schema/Collection#tag') - p_principal = curr.predicate('http://bsfs.ai/schema/Tag#principal') + p_usedIn = curr.predicate('https://schema.bsfs.io/core/Tag#usedIn') + p_ctag = curr.predicate('https://schema.bsfs.io/core/Collection#tag') + p_principal = curr.predicate('https://schema.bsfs.io/core/Tag#principal') store.create(curr.node(ns.bsfs.Collection), {URI('http://example.com/me/collection#1234'), URI('http://example.com/me/collection#4321')}) # add some more triples store.set(curr.node(ns.bsfs.Entity), ent_ids, p_shared, {True}) @@ -283,9 +286,9 @@ class TestSparqlStore(unittest.TestCase): (rdflib.URIRef(ns.xsd.boolean), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), (rdflib.URIRef(ns.bse.shared), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), (rdflib.URIRef(ns.bse.partOf), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Tag#usedIn'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Collection#tag'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Tag#usedIn'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Collection#tag'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), # collections (rdflib.URIRef('http://example.com/me/collection#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Collection)), (rdflib.URIRef('http://example.com/me/collection#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Collection)), @@ -309,17 +312,18 @@ class TestSparqlStore(unittest.TestCase): curr = 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#> + prefix bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bst: <https://schema.bsfs.io/core/Tag#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . bsfs:User rdfs:subClassOf bsfs:Node . xsd:boolean rdfs:subClassOf bsfs:Literal . - bsfs:Number rdfs:subClassOf bsfs:Literal . - xsd:integer rdfs:subClassOf bsfs:Number . + bsl:Number rdfs:subClassOf bsfs:Literal . + xsd:integer rdfs:subClassOf bsl:Number . bse:filesize rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; @@ -360,16 +364,16 @@ class TestSparqlStore(unittest.TestCase): (rdflib.URIRef(ns.bsfs.Tag), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)), (rdflib.URIRef(ns.bsfs.User), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Node)), (rdflib.URIRef(ns.xsd.boolean), 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)), - (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Number)), + (rdflib.URIRef(ns.bsl.Array), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.BinaryBlob), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Array.Feature), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Array)), + (rdflib.URIRef(ns.bsl.Number), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.bsl.Time), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Literal)), + (rdflib.URIRef(ns.xsd.integer), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsl.Number)), (rdflib.URIRef(ns.bse.shared), 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.filesize), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), - (rdflib.URIRef('http://bsfs.ai/schema/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), + (rdflib.URIRef('https://schema.bsfs.io/core/Tag#principal'), rdflib.RDFS.subClassOf, rdflib.URIRef(ns.bsfs.Predicate)), # node instances (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), (rdflib.URIRef('http://example.com/me/entity#4321'), rdflib.RDF.type, rdflib.URIRef(ns.bsfs.Entity)), @@ -400,13 +404,15 @@ class TestSparqlStore(unittest.TestCase): invalid = 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> + prefix bsl: <https://schema.bsfs.io/core/Literal/> + prefix bsa: <https://schema.bsfs.io/core/Literal/Array/> - bsfs:Array rdfs:subClassOf bsfs:Literal . - bsfs:Feature rdfs:subClassOf bsfs:Array . + bsl:Array rdfs:subClassOf bsfs:Literal . + bsa:Feature rdfs:subClassOf bsl:Array . - bsfs:Colors rdfs:subClassOf bsfs:Feature ; + bsfs:Colors rdfs:subClassOf bsa:Feature ; bsfs:dimension "4"^^xsd:integer ; bsfs:distance bsfs:foobar . @@ -417,8 +423,8 @@ class TestSparqlStore(unittest.TestCase): invalid = 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Entity . # inconsistent with previous tag definition @@ -433,8 +439,8 @@ class TestSparqlStore(unittest.TestCase): invalid = 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 bsfs: <https://schema.bsfs.io/core/> + prefix bse: <https://schema.bsfs.io/core/Entity#> bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:User rdfs:subClassOf bsfs:Node . @@ -945,9 +951,9 @@ class TestSparqlStore(unittest.TestCase): p_asset = store.schema.predicate(ns.bse.asset) store.set(ent_type, ent_ids, p_asset, {bytes(range(128)), bytes(range(128, 256))}) blob1 = rdflib.Literal('AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn8=', - datatype=rdflib.URIRef(ns.bsfs.BinaryBlob)) + datatype=rdflib.URIRef(ns.bsl.BinaryBlob)) blob2 = rdflib.Literal('gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8=', - datatype=rdflib.URIRef(ns.bsfs.BinaryBlob)) + datatype=rdflib.URIRef(ns.bsl.BinaryBlob)) self.assertTrue(set(store._graph).issuperset({ (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_asset.uri), blob1), (rdflib.URIRef('http://example.com/me/entity#1234'), rdflib.URIRef(p_asset.uri), blob2), diff --git a/test/triple_store/sparql/test_utils.py b/test/triple_store/sparql/test_utils.py index 8f894bb..44a1299 100644 --- a/test/triple_store/sparql/test_utils.py +++ b/test/triple_store/sparql/test_utils.py @@ -16,6 +16,8 @@ from bsfs.triple_store.sparql.utils import GenHopName, Query ## code ## +ns.bse = ns.bsfs.Entity() + class TestGenHopName(unittest.TestCase): def test_next(self): # baseline @@ -40,7 +42,7 @@ class TestGenHopName(unittest.TestCase): class TestQuery(unittest.TestCase): def setUp(self): - self.root_type = 'http://bsfs.ai/schema/Entity' + self.root_type = 'https://schema.bsfs.io/core/Entity' self.root_head = '?root' self.select = (('?head', 'name'), ) self.where = f'?root <{ns.bse.tag}> ?head' @@ -56,8 +58,8 @@ class TestQuery(unittest.TestCase): self.assertEqual(q, Query(self.root_type, self.root_head, self.select, self.where)) self.assertEqual(hash(q), hash(Query(self.root_type, self.root_head, self.select, self.where))) # comparison respects root_type - self.assertNotEqual(q, Query('http://bsfs.ai/schema/Tag', self.root_head, self.select, self.where)) - self.assertNotEqual(hash(q), hash(Query('http://bsfs.ai/schema/Tag', self.root_head, self.select, self.where))) + self.assertNotEqual(q, Query('https://schema.bsfs.io/core/Tag', self.root_head, self.select, self.where)) + self.assertNotEqual(hash(q), hash(Query('https://schema.bsfs.io/core/Tag', self.root_head, self.select, self.where))) # comparison respects root_head self.assertNotEqual(q, Query(self.root_type, '?foo', self.select, self.where)) self.assertNotEqual(hash(q), hash(Query(self.root_type, '?foo', self.select, self.where))) @@ -69,7 +71,7 @@ class TestQuery(unittest.TestCase): self.assertNotEqual(hash(q), hash(Query(self.root_type, self.root_head, self.select, '?root bse:filename ?head'))) # string conversion self.assertEqual(str(q), q.query) - self.assertEqual(repr(q), "Query(http://bsfs.ai/schema/Entity, ?root, (('?head', 'name'),), ?root <http://bsfs.ai/schema/Entity#tag> ?head)") + self.assertEqual(repr(q), "Query(https://schema.bsfs.io/core/Entity, ?root, (('?head', 'name'),), ?root <https://schema.bsfs.io/core/Entity#tag> ?head)") def test_add(self): q = Query(self.root_type, self.root_head, self.select, self.where) @@ -77,7 +79,7 @@ class TestQuery(unittest.TestCase): self.assertRaises(TypeError, operator.add, q, 1234) self.assertRaises(TypeError, operator.add, q, 'foobar') # root type and head must match - self.assertRaises(ValueError, operator.add, q, Query('http://bsfs.ai/schema/Tag', self.root_head)) + self.assertRaises(ValueError, operator.add, q, Query('https://schema.bsfs.io/core/Node/Tag', self.root_head)) self.assertRaises(ValueError, operator.add, q, Query(self.root_type, '?foobar')) # select and were are combined combo = q + Query(self.root_type, self.root_head, (('?foo', 'bar'), ), f'?root <{ns.bse.filename}> ?foo') @@ -113,23 +115,23 @@ class TestQuery(unittest.TestCase): return value # query composes a valid query q = Query(self.root_type, self.root_head, self.select, self.where) - self.assertEqual(normalize(q.query), normalize(f'select distinct ?root (?head as ?name) where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <http://bsfs.ai/schema/Entity> . ?root <{ns.bse.tag}> ?head }} order by str(?root)')) + self.assertEqual(normalize(q.query), normalize(f'select distinct ?root (?head as ?name) where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <https://schema.bsfs.io/core/Entity> . ?root <{ns.bse.tag}> ?head }} order by str(?root)')) # select and where are optional q = Query(self.root_type, self.root_head) - self.assertEqual(normalize(q.query), normalize(f'select distinct ?root where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <http://bsfs.ai/schema/Entity> . }} order by str(?root)')) + self.assertEqual(normalize(q.query), normalize(f'select distinct ?root where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <https://schema.bsfs.io/core/Entity> . }} order by str(?root)')) # select and where need not to correspond q = Query(self.root_type, self.root_head, (('?head', 'name'), )) - self.assertEqual(normalize(q.query), normalize(f'select distinct ?root (?head as ?name) where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <http://bsfs.ai/schema/Entity> . }} order by str(?root)')) + self.assertEqual(normalize(q.query), normalize(f'select distinct ?root (?head as ?name) where {{ ?root <{ns.rdf.type}>/<{ns.rdfs.subClassOf}>* <https://schema.bsfs.io/core/Entity> . }} order by str(?root)')) # query is used for string representation self.assertEqual(str(q), q.query) def test_call(self): graph = rdflib.Graph() # schema - graph.add((rdflib.URIRef('http://bsfs.ai/schema/Document'), rdflib.URIRef(ns.rdfs.subClassOf), rdflib.URIRef('http://bsfs.ai/schema/Entity'))) + graph.add((rdflib.URIRef('https://schema.bsfs.io/core/Document'), rdflib.URIRef(ns.rdfs.subClassOf), rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) # nodes - graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.rdf.type), rdflib.URIRef('http://bsfs.ai/schema/Entity'))) - graph.add((rdflib.URIRef('http://example.com/doc#1234'), rdflib.URIRef(ns.rdf.type), rdflib.URIRef('http://bsfs.ai/schema/Document'))) + graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.rdf.type), rdflib.URIRef('https://schema.bsfs.io/core/Entity'))) + graph.add((rdflib.URIRef('http://example.com/doc#1234'), rdflib.URIRef(ns.rdf.type), rdflib.URIRef('https://schema.bsfs.io/core/Document'))) # links graph.add((rdflib.URIRef('http://example.com/entity#1234'), rdflib.URIRef(ns.bse.tag), rdflib.Literal('tag#1234', datatype=rdflib.XSD.string))) graph.add((rdflib.URIRef('http://example.com/doc#1234'), rdflib.URIRef(ns.bse.tag), rdflib.Literal('tag#1234', datatype=rdflib.XSD.string))) |