aboutsummaryrefslogtreecommitdiffstats
path: root/test/schema
diff options
context:
space:
mode:
Diffstat (limited to 'test/schema')
-rw-r--r--test/schema/test_schema.py34
-rw-r--r--test/schema/test_serialize.py308
-rw-r--r--test/schema/test_types.py52
3 files changed, 107 insertions, 287 deletions
diff --git a/test/schema/test_schema.py b/test/schema/test_schema.py
index c19c226..32dbc93 100644
--- a/test/schema/test_schema.py
+++ b/test/schema/test_schema.py
@@ -66,30 +66,32 @@ class TestSchema(unittest.TestCase):
# literals
self.l_root = types.ROOT_LITERAL
self.l_number = types.ROOT_NUMBER
+ self.l_array = types.ROOT_ARRAY
+ self.l_time = types.ROOT_TIME
self.l_string = self.l_root.child(ns.xsd.string)
self.l_integer = self.l_root.child(ns.xsd.integer)
self.l_unused = self.l_root.child(ns.xsd.boolean)
- self.literals = [self.l_root, self.l_number, self.l_string, self.l_integer, self.l_unused]
+ self.f_root = types.ROOT_FEATURE
+ self.literals = [self.l_root, self.l_array, self.f_root, self.l_number, self.l_time, self.l_string, self.l_integer, self.l_unused]
# predicates
self.p_root = types.ROOT_PREDICATE
- self.f_root = types.ROOT_FEATURE
self.p_tag = self.p_root.child(ns.bse.tag, self.n_ent, self.n_tag, False)
self.p_group = self.p_tag.child(ns.bse.group, self.n_img, self.n_tag, False)
self.p_comment = self.p_root.child(ns.bse.comment, self.n_root, self.l_string, True)
- self.predicates = [self.p_root, self.f_root, self.p_tag, self.p_group, self.p_comment]
+ self.predicates = [self.p_root, self.p_tag, self.p_group, self.p_comment]
def test_construction(self):
# no args yields a minimal schema
schema = Schema()
self.assertSetEqual(set(schema.nodes()), {self.n_root})
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_number})
- self.assertSetEqual(set(schema.predicates()), {self.p_root, self.f_root})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_number, self.l_array, self.l_time, self.f_root})
+ self.assertSetEqual(set(schema.predicates()), {self.p_root})
# nodes and literals are optional
schema = Schema(self.predicates)
self.assertSetEqual(set(schema.nodes()), {self.n_root, self.n_ent, self.n_img, self.n_tag})
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number, self.l_time, self.l_array, self.f_root})
self.assertSetEqual(set(schema.predicates()), set(self.predicates))
# predicates, nodes, and literals are respected
@@ -110,21 +112,21 @@ class TestSchema(unittest.TestCase):
# literals are complete
schema = Schema(self.predicates, self.nodes, None)
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number, self.l_array, self.l_time, self.f_root})
schema = Schema(self.predicates, self.nodes, [])
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number, self.l_array, self.l_time, self.f_root})
schema = Schema(self.predicates, self.nodes, [self.l_string])
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_number, self.l_array, self.l_time, self.f_root})
schema = Schema(self.predicates, self.nodes, [self.l_integer])
- self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_integer, self.l_number})
+ self.assertSetEqual(set(schema.literals()), {self.l_root, self.l_string, self.l_integer, self.l_number, self.l_array, self.l_time, self.f_root})
schema = Schema(self.predicates, self.nodes, [self.l_integer, self.l_unused])
self.assertSetEqual(set(schema.literals()), set(self.literals))
# predicates are complete
schema = Schema([], self.nodes, self.literals)
- self.assertSetEqual(set(schema.predicates()), {self.p_root, self.f_root})
+ self.assertSetEqual(set(schema.predicates()), {self.p_root})
schema = Schema([self.p_group], self.nodes, self.literals)
- self.assertSetEqual(set(schema.predicates()), {self.p_root, self.f_root, self.p_tag, self.p_group})
+ self.assertSetEqual(set(schema.predicates()), {self.p_root, self.p_tag, self.p_group})
schema = Schema([self.p_group, self.p_comment], self.nodes, self.literals)
self.assertSetEqual(set(schema.predicates()), set(self.predicates))
@@ -176,14 +178,14 @@ 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.Literal, ns.bsfs.Number]
- p = [ns.bsfs.Feature, ns.bsfs.Predicate]
+ l = [ns.bsfs.Array, ns.bsfs.Feature, ns.bsfs.Literal, ns.bsfs.Number, ns.bsfs.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.Literal, ns.bsfs.Number, ns.xsd.boolean, ns.xsd.integer, ns.xsd.string]
- p = [ns.bse.comment, ns.bse.group, ns.bse.tag, ns.bsfs.Feature, ns.bsfs.Predicate]
+ l = [ns.bsfs.Array, ns.bsfs.Feature, ns.bsfs.Literal, ns.bsfs.Number, ns.bsfs.Time, ns.xsd.boolean, ns.xsd.integer, ns.xsd.string]
+ 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})')
def test_equality(self):
diff --git a/test/schema/test_serialize.py b/test/schema/test_serialize.py
index 205150a..fc6b20a 100644
--- a/test/schema/test_serialize.py
+++ b/test/schema/test_serialize.py
@@ -581,151 +581,60 @@ class TestFromString(unittest.TestCase):
def test_feature(self):
- # domain must be defined
- 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:array rdfs:subClassOf bsfs:Literal .
-
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ; # undefined symbol
- rdfs:range bsfs:array ;
- bsfs:unique "false"^^xsd:boolean .
- ''')
- # domain cannot be a literal
- 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Literal .
- bsfs:array rdfs:subClassOf bsfs:Literal .
-
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ; # literal instead of node
- rdfs:range bsfs:array ;
- bsfs:unique "false"^^xsd:boolean .
- ''')
-
- # range must be defined
- 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
-
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:array ; # undefined symbol
- bsfs:unique "false"^^xsd:boolean .
- ''')
- # range must be defined
- self.assertRaises(errors.ConsistencyError, from_string, '''
+ # additional features can be defined
+ f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors)
+ 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#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:Foo ; # undefined symbol
- bsfs:unique "false"^^xsd:boolean .
- ''')
- # range must be a node or a literal
- 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
-
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:Predicate ; # invalid symbol
- bsfs:unique "false"^^xsd:boolean .
- ''')
+ bsfs:Colors rdfs:subClassOf bsfs:Feature .
- # additional predicates can be defined
- n_ent = types.ROOT_NODE.child(ns.bsfs.Entity)
- l_array = types.ROOT_LITERAL.child(ns.bsfs.array)
- p_comment = types.ROOT_FEATURE.child(ns.bse.colors, domain=n_ent, range=l_array, unique=False)
- 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
- bsfs:array rdfs:subClassOf bsfs:Literal .
-
- bse:colors rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:array ;
- bsfs:unique "false"^^xsd:boolean .
'''))
# features inherit properties from parents
- n_ent = types.ROOT_NODE.child(ns.bsfs.Entity)
- l_array = types.ROOT_LITERAL.child(ns.bsfs.array)
- l_string = types.ROOT_LITERAL.child(ns.xsd.string)
- p_annotation = types.ROOT_FEATURE.child(ns.bsfs.Annotation, domain=n_ent, range=l_array,
- dimension=1234, dtype=ns.xsd.string)
- p_comment = p_annotation.child(ns.bse.colors, unique=True)
- self.assertEqual(Schema({p_comment}), from_string('''
+ 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)
+ 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#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
- bsfs:array rdfs:subClassOf bsfs:Literal .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bsfs:Annotation rdfs:subClassOf bsfs:Feature ; # inherits defaults from bsfs:Feature
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:array ;
- bsfs:dimension "1234"^^xsd:integer ;
- bsfs:dtype xsd:string .
+ 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:MainColor rdfs:subClassOf bsfs:Colors ; # inherits dimension from bsfs:Colors
+ bsfs:distance bsfs:cosine ; # overwrites bsfs:Feature
+ bsfs:dtype bsfs:f16 . # overwrites bsfs:Colors
- bse:colors rdfs:subClassOf bsfs:Annotation ; # inherits domain/range/etc. from bsfs:Annotation
- bsfs:unique "true"^^xsd:boolean . # overwrites bsfs:Predicate
'''))
# feature definition can be split across multiple statements.
# statements can be repeated
- n_ent = types.ROOT_NODE.child(ns.bsfs.Entity)
- p_foo = types.ROOT_FEATURE.child(ns.bse.foo, domain=n_ent, unique=True,
- dimension=1234, dtype=ns.bsfs.f32)
- self.assertEqual(Schema({p_foo}), from_string('''
+ f_colors = types.ROOT_FEATURE.child(ns.bsfs.Colors, dimension=1234, dtype=ns.bsfs.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#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bse:foo rdfs:subClassOf bsfs:Feature ;
- bsfs:unique "true"^^xsd:boolean ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dimension "1234"^^xsd:integer .
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
+ bsfs:dimension "1234"^^xsd:integer ; # non-conflicting repetition
bsfs:dtype bsfs:f32 .
'''))
@@ -736,75 +645,14 @@ class TestFromString(unittest.TestCase):
prefix bsfs: <http://bsfs.ai/schema/>
prefix bse: <http://bsfs.ai/schema/Entity#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Annotation rdfs:subClassOf bsfs:Feature .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
+ bsfs:ColorSpace rdfs:subClassOf bsfs:Feature .
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
- bsfs:unique "false"^^xsd:boolean .
-
- bse:foo rdfs:subClassOf bsfs:Annotation ;
- rdfs:domain bsfs:Node ;
- bsfs:unique "false"^^xsd:boolean .
+ bsfs:Colors rdfs:subClassOf bsfs:Feature .
+ bsfs:Colors rdfs:subClassOf bsfs:ColorSpace .
''')
- # cannot assign multiple conflicting domains 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
- bsfs:unique "false"^^xsd:boolean .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity . # conflicting domain
- ''')
- # cannot assign multiple conflicting ranges 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
- bsfs:array rdfs:subClassOf bsfs:Literal .
- bsfs:large_array rdfs:subClassOf bsfs:array .
- bsfs:small_array rdfs:subClassOf bsfs:array .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
- rdfs:range bsfs:large_array ;
- bsfs:unique "false"^^xsd:boolean .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:range bsfs:small_array . # conflicting range
- ''')
- # cannot assign multiple conflicting uniques 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#>
-
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
- rdfs:range bsfs:Node ;
- bsfs:unique "false"^^xsd:boolean .
-
- bse:foo rdfs:subClassOf bsfs:Feature ;
- bsfs:unique "true"^^xsd:boolean . # conflicting unique
- ''')
# cannot assign multiple conflicting dimensions to the same feature
self.assertRaises(errors.ConsistencyError, from_string, '''
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
@@ -812,15 +660,15 @@ class TestFromString(unittest.TestCase):
prefix bsfs: <http://bsfs.ai/schema/>
prefix bse: <http://bsfs.ai/schema/Entity#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dimension "1234"^^xsd:integer .
- bse:foo rdfs:subClassOf bsfs:Feature ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dimension "4321"^^xsd:integer . # conflicting dimension
+
''')
# cannot assign multiple conflicting dtypes to the same feature
self.assertRaises(errors.ConsistencyError, from_string, '''
@@ -829,14 +677,13 @@ class TestFromString(unittest.TestCase):
prefix bsfs: <http://bsfs.ai/schema/>
prefix bse: <http://bsfs.ai/schema/Entity#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dtype bsfs:f32 .
- bse:foo rdfs:subClassOf bsfs:Feature ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dtype bsfs:f16 . # conflicting dtype
''')
# cannot assign multiple conflicting distance metrics to the same feature
@@ -846,14 +693,13 @@ class TestFromString(unittest.TestCase):
prefix bsfs: <http://bsfs.ai/schema/>
prefix bse: <http://bsfs.ai/schema/Entity#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bsfs:Entity rdfs:subClassOf bsfs:Node .
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
- bse:foo rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Node ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:distance bsfs:euclidean .
- bse:foo rdfs:subClassOf bsfs:Feature ;
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:distance bsfs:cosine . # conflicting distance
''')
@@ -864,24 +710,28 @@ class TestFromString(unittest.TestCase):
prefix bsfs: <http://bsfs.ai/schema/>
prefix bse: <http://bsfs.ai/schema/Entity#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bse:colors rdfs:subClassOf bsfs:Feature ;
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
+
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dimension "1234"^^xsd:integer .
- ''').predicate(ns.bse.colors).annotations, {})
+ ''').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#>
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
- bse:colors rdfs:subClassOf bsfs:Feature ;
+ bsfs:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
+
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
bsfs:dimension "1234"^^xsd:integer ;
rdfs:label "hello world"^^xsd:string ;
bsfs:foo "1234"^^xsd:integer .
- ''').predicate(ns.bse.colors).annotations, {
+ ''').literal(ns.bsfs.Colors).annotations, {
ns.rdfs.label: 'hello world',
ns.bsfs.foo: 1234,
})
@@ -904,14 +754,14 @@ class TestFromString(unittest.TestCase):
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'),
- domain=n_ent, range=l_array, unique=True, dtype=ns.bsfs.f16, distance=ns.bsfs.euclidean)
+ 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)
# schema
ref = Schema(
- {p_annotation, p_tag, p_group, p_comment, f_colors, f_colors1234, f_colors4321},
+ {p_annotation, p_tag, p_group, p_comment},
{n_ent, n_tag, n_image},
- {l_string, l_integer, l_boolean})
+ {l_string, l_integer, l_boolean, f_colors, f_colors1234, f_colors4321})
# load from string
gen = from_string('''
# generic prefixes
@@ -932,21 +782,19 @@ 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:Array rdfs:subClassOf bsfs:Literal .
+ bsfs:Feature rdfs:subClassOf bsfs:Array.
bsfs:Number rdfs:subClassOf bsfs:Literal .
xsd:integer rdfs:subClassOf bsfs:Number .
xsd:boolean rdfs:subClassOf bsfs:Literal .
+
# abstract predicates
bsfs:Annotation rdfs:subClassOf bsfs:Predicate ;
rdfs:label "node annotation"^^xsd:string .
- bsfs:Feature rdfs:subClassOf bsfs:Predicate .
# feature instances
<http://bsfs.ai/schema/Feature/colors_spatial> rdfs:subClassOf bsfs:Feature ;
- rdfs:domain bsfs:Entity ;
- rdfs:range bsfs:array ;
- bsfs:unique "true"^^xsd:boolean ;
bsfs:dtype bsfs:f16 ;
bsfs:distance bsfs:euclidean ;
# annotations
@@ -986,15 +834,22 @@ 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.predicate(URI('http://bsfs.ai/schema/Feature/colors_spatial')).annotations, {
+ self.assertDictEqual(gen.literal(URI('http://bsfs.ai/schema/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.predicate(URI('http://bsfs.ai/schema/Feature/colors_spatial#1234')).annotations, {
+ self.assertDictEqual(gen.literal(URI('http://bsfs.ai/schema/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/>
+ bsfs:Entity rdfs:subClassOf bsfs:Node ;
+ bsfs:foo _:bar .
+ ''')
class TestToString(unittest.TestCase):
@@ -1002,6 +857,11 @@ class TestToString(unittest.TestCase):
def test_empty(self):
self.assertEqual(Schema(), from_string(to_string(Schema())))
+ def test_parse(self):
+ schema = Schema()
+ schema._nodes[ns.bsfs.Invalid] = 123 # NOTE: Access protected to force an invalid schema
+ self.assertRaises(TypeError, to_string, schema)
+
def test_literal(self):
# root literals
l_str = types.ROOT_LITERAL.child(ns.xsd.string)
@@ -1120,37 +980,29 @@ class TestToString(unittest.TestCase):
def test_feature(self):
- # auxiliary types
- n_ent = types.ROOT_NODE.child(ns.bsfs.Entity)
- l_array = types.ROOT_LITERAL.child(ns.bsfs.array)
# root features
f_colors = types.ROOT_FEATURE.child(URI('http://bsfs.ai/schema/Feature/colors'),
- range=l_array, unique=True, distance=ns.bsfs.cosine)
+ distance=ns.bsfs.cosine)
# derived features
f_colors1234 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors#1234'),
- dimension=1024, domain=n_ent) # inherits range/dtype/distance
+ dimension=1024) # inherits dtype, distance
f_colors4321 = f_colors.child(URI('http://bsfs.ai/schema/Feature/colors#4321'),
- dimension=2048, distance=ns.bsfs.euclidean) # inherits domain/range/dtype
+ dimension=2048, distance=ns.bsfs.euclidean) # inherits dtype
# create schema
- schema = Schema({f_colors, f_colors1234, f_colors4321})
+ schema = Schema(literals={f_colors, f_colors1234, f_colors4321})
schema_str = to_string(schema)
# all symbols are serialized
- self.assertIn('bsfs:Entity', schema_str)
- self.assertIn('bsfs:array', schema_str)
+ 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)
# inherited properties are not serialized
- self.assertIsNotNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#1234>[^\.]*rdfs:domain[^\.]', schema_str))
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>[^\.]*rdfs:range[^\.]', 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>[^\.]*rdfs:domain[^\.]', schema_str))
- self.assertIsNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#4321>[^\.]*rdfs:range[^\.]', schema_str))
self.assertIsNone(re.search(r'<http://bsfs\.ai/schema/Feature/colors#4321>[^\.]*bsfs:dtype[^\.]', schema_str))
# unserialize yields the original schema
self.assertEqual(schema, from_string(schema_str))
@@ -1163,11 +1015,11 @@ class TestToString(unittest.TestCase):
ns.bsfs.bar: False,
}
f_colors = types.ROOT_FEATURE.child(URI('http://bsfs.ai/schema/Feature/colors'),
- domain=n_ent, range=l_array, unique=True, dtype=ns.bsfs.f16, distance=ns.bsfs.euclidean,
+ dtype=ns.bsfs.f16, distance=ns.bsfs.euclidean,
**annotations)
self.assertDictEqual(
annotations,
- from_string(to_string(Schema({f_colors}))).predicate(URI('http://bsfs.ai/schema/Feature/colors')).annotations)
+ from_string(to_string(Schema(literals={f_colors}))).literal(URI('http://bsfs.ai/schema/Feature/colors')).annotations)
## main ##
diff --git a/test/schema/test_types.py b/test/schema/test_types.py
index 1eeafa1..c5895d2 100644
--- a/test/schema/test_types.py
+++ b/test/schema/test_types.py
@@ -274,21 +274,16 @@ class TestFeature(unittest.TestCase):
n_root = Node(ns.bsfs.Node, None)
l_root = Literal(ns.bsfs.Literal, None)
# dimension, dtype, and distance are respected
- feat = Feature(ns.bsfs.Feature, None, n_root, l_root, False,
- 1234, ns.bsfs.float, ns.bsfs.euclidean)
+ feat = Feature(ns.bsfs.Feature, None, 1234, ns.bsfs.float, ns.bsfs.euclidean)
self.assertEqual(1234, feat.dimension)
self.assertEqual(ns.bsfs.float, feat.dtype)
self.assertEqual(ns.bsfs.euclidean, feat.distance)
def test_equality(self):
n_ent = Node(ns.bsfs.Entity, Node(ns.bsfs.Node, None))
- l_array = Literal(ns.bsfs.array, Literal(ns.bsfs.Literal, None))
colors = Feature(
uri=ns.bse.colors,
parent=ROOT_FEATURE,
- domain=n_ent,
- range=l_array,
- unique=False,
dimension=1234,
dtype=ns.bsfs.float,
distance=ns.bsfs.euclidean,
@@ -297,29 +292,25 @@ class TestFeature(unittest.TestCase):
self.assertEqual(colors, colors)
self.assertEqual(hash(colors), hash(colors))
# instance is equal to a clone
- self.assertEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.float, ns.bsfs.euclidean))
- self.assertEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.float, ns.bsfs.euclidean)))
+ self.assertEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.float, ns.bsfs.euclidean))
+ self.assertEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.float, ns.bsfs.euclidean)))
# equality respects dimension
- self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 4321, ns.bsfs.float, ns.bsfs.euclidean))
- self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 4321, ns.bsfs.float, ns.bsfs.euclidean)))
+ self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, 4321, ns.bsfs.float, ns.bsfs.euclidean))
+ self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, 4321, ns.bsfs.float, ns.bsfs.euclidean)))
# equality respects dtype
- self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.integer, ns.bsfs.euclidean))
- self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.integer, ns.bsfs.euclidean)))
+ self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.integer, ns.bsfs.euclidean))
+ self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.integer, ns.bsfs.euclidean)))
# equality respects distance
- self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.float, ns.bsfs.cosine))
- self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, n_ent, l_array, False, 1234, ns.bsfs.float, ns.bsfs.cosine)))
+ self.assertNotEqual(colors, Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.float, ns.bsfs.cosine))
+ self.assertNotEqual(hash(colors), hash(Feature(ns.bse.colors, ROOT_FEATURE, 1234, ns.bsfs.float, ns.bsfs.cosine)))
def test_child(self):
n_root = Node(ns.bsfs.Node, None)
n_ent = Node(ns.bsfs.Entity, n_root)
l_root = Literal(ns.bsfs.Literal, None)
- l_array = Literal(ns.bsfs.array, l_root)
colors = Feature(
uri=ns.bse.colors,
parent=ROOT_FEATURE,
- domain=n_ent,
- range=l_array,
- unique=False,
dimension=1234,
dtype=ns.bsfs.float,
distance=ns.bsfs.euclidean,
@@ -329,16 +320,6 @@ class TestFeature(unittest.TestCase):
self.assertIsInstance(colors.child(ns.bse.foo), Feature)
# uri is respected
self.assertEqual(ns.bse.foo, colors.child(ns.bse.foo).uri)
- # domain is respected
- dom = Node(ns.bsfs.Image, n_ent)
- self.assertEqual(dom, colors.child(ns.bse.foo, domain=dom).domain)
- # range is respected
- rng = Literal(ns.bse.foo, l_array)
- self.assertEqual(rng, colors.child(ns.bse.foo, range=rng).range)
- # cannot set range to None
- self.assertEqual(l_array, colors.child(ns.bse.foo, range=None).range)
- # unique is respected
- self.assertTrue(colors.child(ns.bse.foo, unique=True).unique)
# dimension is respected
self.assertEqual(4321, colors.child(ns.bse.foo, dimension=4321).dimension)
# dtype is respected
@@ -351,13 +332,6 @@ class TestFeature(unittest.TestCase):
'bar': 123,
})
- # domain is inherited from parent
- self.assertEqual(n_root, ROOT_FEATURE.child(ns.bse.foo).domain)
- self.assertEqual(n_ent, colors.child(ns.bse.foo).domain)
- # range is inherited from parent
- self.assertEqual(l_array, colors.child(ns.bse.foo).range)
- # uniqueness is inherited from parent
- self.assertFalse(colors.child(ns.bse.foo).unique)
# dimension is inherited from parent
self.assertEqual(1234, colors.child(ns.bse.foo).dimension)
# dtype is inherited from parent
@@ -365,14 +339,6 @@ class TestFeature(unittest.TestCase):
# distance is inherited from parent
self.assertEqual(ns.bsfs.euclidean, colors.child(ns.bse.foo).distance)
- # domain must be subtype of parent's domain
- self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, domain=n_root)
- self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, domain=Node(ns.bsfs.Image, n_root))
- # range must be subtype of parent's range
- self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Literal(ns.bsfs.Literal, None))
- self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Literal(ns.bsfs.foo, Literal(ns.bsfs.Literal, None)))
- self.assertRaises(errors.ConsistencyError, colors.child, ns.bse.foo, range=Node(ns.bsfs.Tag, n_root))
-
## main ##