aboutsummaryrefslogtreecommitdiffstats
path: root/test/query
diff options
context:
space:
mode:
Diffstat (limited to 'test/query')
-rw-r--r--test/query/ast_test/__init__.py (renamed from test/query/ast/__init__.py)0
-rw-r--r--test/query/ast_test/test_filter_.py (renamed from test/query/ast/test_filter_.py)35
-rw-r--r--test/query/test_validator.py59
3 files changed, 80 insertions, 14 deletions
diff --git a/test/query/ast/__init__.py b/test/query/ast_test/__init__.py
index e69de29..e69de29 100644
--- a/test/query/ast/__init__.py
+++ b/test/query/ast_test/__init__.py
diff --git a/test/query/ast/test_filter_.py b/test/query/ast_test/test_filter_.py
index 4f69bdc..9eb92e2 100644
--- a/test/query/ast/test_filter_.py
+++ b/test/query/ast_test/test_filter_.py
@@ -15,7 +15,7 @@ from bsfs.utils import URI
from bsfs.query.ast.filter_ import _Expression, FilterExpression, PredicateExpression
from bsfs.query.ast.filter_ import _Branch, Any, All
from bsfs.query.ast.filter_ import _Agg, And, Or
-from bsfs.query.ast.filter_ import Not, Has
+from bsfs.query.ast.filter_ import Not, Has, Distance
from bsfs.query.ast.filter_ import _Value, Is, Equals, Substring, StartsWith, EndsWith
from bsfs.query.ast.filter_ import _Bounded, LessThan, GreaterThan
from bsfs.query.ast.filter_ import Predicate, OneOf
@@ -284,6 +284,39 @@ class TestValue(unittest.TestCase):
self.assertEqual(cls(f).value, f)
+class TestDistance(unittest.TestCase):
+ def test_essentials(self):
+ ref = (1,2,3)
+ # comparison
+ self.assertEqual(Distance(ref, 3), Distance(ref, 3))
+ self.assertEqual(hash(Distance(ref, 3)), hash(Distance(ref, 3)))
+ # comparison respects type
+ self.assertNotEqual(Distance(ref, 3), FilterExpression())
+ self.assertNotEqual(hash(Distance(ref, 3)), hash(FilterExpression()))
+ # comparison respects reference
+ self.assertNotEqual(Distance((1,2,3), 3, False), Distance((1,2), 3, False))
+ self.assertNotEqual(hash(Distance((1,2,3), 3, False)), hash(Distance((1,2), 3, False)))
+ self.assertNotEqual(Distance((1,2,3), 3, False), Distance((1,5,3), 3, False))
+ self.assertNotEqual(hash(Distance((1,2,3), 3, False)), hash(Distance((1,5,3), 3, False)))
+ # comparison respects threshold
+ self.assertNotEqual(Distance((1,2,3), 3, False), Distance((1,2,3), 3.1, False))
+ self.assertNotEqual(hash(Distance((1,2,3), 3, False)), hash(Distance((1,2,3), 3.1, False)))
+ # comparison respects strict flag
+ self.assertNotEqual(Distance((1,2,3), 3, False), Distance((1,2,3), 3, True))
+ self.assertNotEqual(hash(Distance((1,2,3), 3, False)), hash(Distance((1,2,3), 3, True)))
+ # string conversion
+ self.assertEqual(str(Distance(ref, 3, False)), 'Distance((1, 2, 3), 3.0, False)')
+ self.assertEqual(repr(Distance(ref, 3, False)), 'Distance((1, 2, 3), 3.0, False)')
+
+ def test_members(self):
+ self.assertEqual(Distance((1,2,3), 3, False).reference, (1,2,3))
+ self.assertEqual(Distance((3,2,1), 3, False).reference, (3,2,1))
+ self.assertEqual(Distance((1,2,3), 3, False).threshold, 3.0)
+ self.assertEqual(Distance((1,2,3), 53.45, False).threshold, 53.45)
+ self.assertEqual(Distance((1,2,3), 3, False).strict, False)
+ self.assertEqual(Distance((1,2,3), 3, True).strict, True)
+
+
class TestBounded(unittest.TestCase):
def test_essentials(self):
# comparison respects type
diff --git a/test/query/test_validator.py b/test/query/test_validator.py
index 4f8364a..dc9d913 100644
--- a/test/query/test_validator.py
+++ b/test/query/test_validator.py
@@ -21,7 +21,7 @@ from bsfs.query.validator import Filter
class TestFilter(unittest.TestCase):
def setUp(self):
- self.schema = _schema.Schema.from_string('''
+ self.schema = _schema.from_string('''
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
@@ -33,7 +33,19 @@ class TestFilter(unittest.TestCase):
bsfs:Tag rdfs:subClassOf bsfs:Node .
xsd:string rdfs:subClassOf bsfs:Literal .
- xsd:integer 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 .
+
+ bsfs:Colors rdfs:subClassOf bsfs:Feature ;
+ bsfs:dimension "5"^^xsd:integer ;
+ bsfs:dtype bsfs:f32 .
+
+ bse:color rdfs:subClassOf bsfs:Predicate ;
+ rdfs:domain bsfs:Node ;
+ rdfs:range bsfs:Colors ;
+ bsfs:unique "true"^^xsd:boolean .
bse:comment rdfs:subClassOf bsfs:Predicate ;
rdfs:domain bsfs:Node ;
@@ -69,8 +81,8 @@ class TestFilter(unittest.TestCase):
self.assertRaises(TypeError, self.validate, '1234', None)
self.assertRaises(TypeError, self.validate, self.schema.literal(ns.bsfs.URI), None)
# root_type must exist in the schema
- self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Node).get_child(ns.bsfs.Image), None)
- self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Entity).get_child(ns.bsfs.Image), None)
+ self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Image), None)
+ self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Entity).child(ns.bsfs.Image), None)
# valid query returns true
self.assertTrue(self.validate(self.schema.node(ns.bsfs.Entity),
ast.filter.Any(ast.filter.OneOf(ns.bse.tag, ns.bse.buddy),
@@ -85,6 +97,7 @@ class TestFilter(unittest.TestCase):
),
ast.filter.Not(ast.filter.Any(ns.bse.comment,
ast.filter.Not(ast.filter.Equals('hello world')))),
+ ast.filter.Any(ns.bse.color, ast.filter.Distance([1,2,3,4,5], 3)),
)))))
# invalid paths raise consistency error
self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Entity),
@@ -130,7 +143,7 @@ class TestFilter(unittest.TestCase):
# type must be a node
self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.literal(ns.bsfs.Literal), None)
# type must be in the schema
- self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).get_child(ns.bsfs.Invalid), None)
+ self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), None)
# predicate is verified
self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity),
ast.filter.Any(ns.bsfs.Invalid, ast.filter.Is('http://example.com/entity#1234')))
@@ -187,7 +200,7 @@ class TestFilter(unittest.TestCase):
self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.literal(ns.bsfs.Literal),
ast.filter.Has(ns.bse.tag))
# type must be in the schema
- self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.node(ns.bsfs.Node).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid),
ast.filter.Has(ns.bse.tag))
# has checks predicate
self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.node(ns.bsfs.Entity),
@@ -206,7 +219,7 @@ class TestFilter(unittest.TestCase):
self.assertRaises(errors.ConsistencyError, self.validate._is, self.schema.literal(ns.bsfs.Literal),
ast.filter.Is('http://example.com/foo'))
# type must be in the schema
- self.assertRaises(errors.ConsistencyError, self.validate._is, self.schema.node(ns.bsfs.Node).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._is, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid),
ast.filter.Is('http://example.com/foo'))
# is accepts correct expressions
self.assertIsNone(self.validate._is(self.schema.node(ns.bsfs.Entity), ast.filter.Is('http://example.com/entity#1234')))
@@ -222,13 +235,13 @@ class TestFilter(unittest.TestCase):
self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.node(ns.bsfs.Node),
ast.filter.EndsWith('hello world'))
# type must be in the schema
- self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.Equals('hello world'))
- self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.Substring('hello world'))
- self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.StartsWith('hello world'))
- self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.EndsWith('hello world'))
# value accepts correct expressions
self.assertIsNone(self.validate._value(self.schema.literal(ns.xsd.string), ast.filter.Equals('hello world')))
@@ -243,14 +256,34 @@ class TestFilter(unittest.TestCase):
self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.node(ns.bsfs.Node),
ast.filter.LessThan(0))
# type must be in the schema
- self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
ast.filter.GreaterThan(0))
- self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.bsfs.Literal).get_child(ns.bsfs.Invalid),
+ self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.bsfs.Literal).child(ns.bsfs.Invalid),
+ ast.filter.LessThan(0))
+ # type must be a number
+ self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.literal(ns.xsd.string),
ast.filter.LessThan(0))
# bounded accepts correct expressions
self.assertIsNone(self.validate._bounded(self.schema.literal(ns.xsd.integer), ast.filter.LessThan(0)))
self.assertIsNone(self.validate._bounded(self.schema.literal(ns.xsd.integer), ast.filter.GreaterThan(0)))
+ def test_distance(self):
+ # type must be a literal
+ 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),
+ 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),
+ ast.filter.Distance([1,2,3], 1, False))
+ # FIXME: reference must be a numpy array
+ # reference must have the correct dimension
+ self.assertRaises(errors.ConsistencyError, self.validate._distance, self.schema.literal(ns.bsfs.Colors),
+ ast.filter.Distance([1,2,3], 1, False))
+ # FIXME: reference must have the correct dtype
+ # distance accepts correct expressions
+ self.assertIsNone(self.validate._distance(self.schema.literal(ns.bsfs.Colors), ast.filter.Distance([1,2,3,4,5], 1, False)))
## main ##