# imports import unittest # bsfs imports from bsfs import schema as _schema from bsfs.namespace import ns from bsfs.query import ast from bsfs.utils import errors # objects to test 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: prefix xsd: prefix bsfs: prefix bse: prefix bsl: bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:URI rdfs:subClassOf bsfs:Literal . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . bsl:Number rdfs:subClassOf bsfs:Literal . bsl:Array rdfs:subClassOf bsfs:Literal . rdfs:subClassOf bsl:Array . xsd:integer rdfs:subClassOf bsl:Number . bsfs:Colors rdfs:subClassOf ; 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 ; rdfs:range xsd:string ; bsfs:unique "false"^^xsd:boolean . bse:filesize rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range xsd:integer ; bsfs:unique "true"^^xsd:boolean . bse:tag rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range bsfs:Tag ; bsfs:unique "false"^^xsd:boolean . bse:label rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Tag ; rdfs:range xsd:string ; bsfs:unique "true"^^xsd:boolean . bse:buddy rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range bsfs:Node ; bsfs:unique "false"^^xsd:boolean . ''') self.validate = Filter(self.schema) def test_call(self): # tests validate implicitly # root_type must be a _schema.Node self.assertRaises(TypeError, self.validate, 1234, None) 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).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), ast.filter.Or( ast.filter.Is('http://example.com/symbol#1234'), ast.filter.All(ns.bse.comment, ast.filter.StartsWith('foo')), ast.filter.And( ast.filter.Has(ns.bse.comment, ast.filter.Or( ast.filter.GreaterThan(5), ast.filter.LessThan(1), ) ), 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), ast.filter.Any(ast.filter.OneOf(ns.bse.tag, ns.bse.buddy), ast.filter.Or( ast.filter.All(ns.bse.comment, ast.filter.Equals('hello world')), ast.filter.All(ns.bse.label, ast.filter.Equals('hello world')), # domain mismatch ))) def test_routing(self): self.assertRaises(errors.BackendError, self.validate._parse_filter_expression, ast.filter.FilterExpression(), self.schema.node(ns.bsfs.Node)) self.assertRaises(errors.BackendError, self.validate._parse_predicate_expression, ast.filter.PredicateExpression()) def test_predicate(self): # predicate must be in the schema self.assertRaises(errors.ConsistencyError, self.validate._predicate, ast.filter.Predicate(ns.bse.invalid)) # predicate must have a range self.assertRaises(errors.BackendError, self.validate._predicate, ast.filter.Predicate(ns.bsfs.Predicate)) # predicate returns domain and range self.assertEqual(self.validate._predicate(ast.filter.Predicate(ns.bse.tag)), (self.schema.node(ns.bsfs.Entity), self.schema.node(ns.bsfs.Tag))) # reverse is applied self.assertEqual(self.validate._predicate(ast.filter.Predicate(ns.bse.tag, reverse=True)), (self.schema.node(ns.bsfs.Tag), self.schema.node(ns.bsfs.Entity))) def test_one_of(self): # domains must both be nodes or literals self.assertRaises(errors.ConsistencyError, self.validate._one_of, ast.filter.OneOf(ns.bse.tag, ast.filter.Predicate(ns.bse.label, reverse=True))) # domains must be related self.assertRaises(errors.ConsistencyError, self.validate._one_of, ast.filter.OneOf(ns.bse.tag, ns.bse.label)) # ranges must both be nodes or literals self.assertRaises(errors.ConsistencyError, self.validate._one_of, ast.filter.OneOf(ns.bse.tag, ns.bse.comment)) # ranges must be related self.assertRaises(errors.ConsistencyError, self.validate._one_of, ast.filter.OneOf(ns.bse.tag, ast.filter.Predicate(ns.bse.buddy, reverse=True))) # one_of returns most specific domain self.assertEqual(self.validate._one_of(ast.filter.OneOf(ns.bse.comment, ns.bse.label)), (self.schema.node(ns.bsfs.Tag), self.schema.literal(ns.xsd.string))) # one_of returns the most generic range self.assertEqual(self.validate._one_of(ast.filter.OneOf(ns.bse.tag, ns.bse.buddy)), (self.schema.node(ns.bsfs.Entity), self.schema.node(ns.bsfs.Node))) def test_branch(self): # 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).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'))) # predicate must match the domain self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node), ast.filter.Any(ns.bse.tag, ast.filter.Is('http://example.com/tag#1234'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Tag), ast.filter.Any(ns.bse.tag, ast.filter.Is('http://example.com/tag#1234'))) # child expression must be valid self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.filter.Any(ns.bse.tag, ast.filter.Equals('hello world'))) # branch accepts valid expressions self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.filter.Any(ns.bse.tag, ast.filter.Is('http://example.com/entity#1234')))) self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.filter.All(ns.bse.tag, ast.filter.Is('http://example.com/entity#1234')))) def test_agg(self): # agg evaluates child expressions self.assertRaises(errors.ConsistencyError, self.validate._agg, self.schema.node(ns.bsfs.Entity), ast.filter.And(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Equals('hello world'))) self.assertRaises(errors.ConsistencyError, self.validate._agg, self.schema.literal(ns.xsd.string), ast.filter.And(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Equals('hello world'))) self.assertRaises(errors.ConsistencyError, self.validate._agg, self.schema.node(ns.bsfs.Entity), ast.filter.Or(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Equals('hello world'))) self.assertRaises(errors.ConsistencyError, self.validate._agg, self.schema.literal(ns.xsd.string), ast.filter.Or(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Equals('hello world'))) # agg works on nodes self.assertIsNone(self.validate._agg(self.schema.node(ns.bsfs.Entity), ast.filter.And(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Is('http://example.com/entity#4321')))) self.assertIsNone(self.validate._agg(self.schema.node(ns.bsfs.Entity), ast.filter.Or(ast.filter.Is('http://example.com/entity#1234'), ast.filter.Is('http://example.com/entity#4321')))) # agg works on literals self.assertIsNone(self.validate._agg(self.schema.literal(ns.xsd.string), ast.filter.And(ast.filter.Equals('foobar'), ast.filter.Equals('hello world')))) self.assertIsNone(self.validate._agg(self.schema.literal(ns.xsd.string), ast.filter.Or(ast.filter.Equals('foobar'), ast.filter.Equals('hello world')))) def test_not(self): # not evaluates child expressions self.assertRaises(errors.ConsistencyError, self.validate._not, self.schema.node(ns.bsfs.Entity), ast.filter.Not(ast.filter.Equals('hello world'))) self.assertRaises(errors.ConsistencyError, self.validate._not, self.schema.literal(ns.xsd.string), ast.filter.Not(ast.filter.Is('http://example.com/entity#1234'))) # not works on nodes self.assertIsNone(self.validate._not(self.schema.node(ns.bsfs.Entity), ast.filter.Not(ast.filter.Is('http://example.com/entity#1234')))) # not works on literals self.assertIsNone(self.validate._not(self.schema.literal(ns.xsd.string), ast.filter.Not(ast.filter.Equals('hello world')))) def test_has(self): # type must be node 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).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), ast.filter.Has(ns.bse.invalid)) # predicate must match domain self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.node(ns.bsfs.Tag), ast.filter.Has(ns.bse.tag)) # has checks count expression self.assertRaises(errors.ConsistencyError, self.validate._has, self.schema.node(ns.bsfs.Entity), ast.filter.Has(ns.bse.tag, ast.filter.Is('http://example.com/entity#1234'))) # has accepts correct expressions self.assertIsNone(self.validate._has(self.schema.node(ns.bsfs.Entity), ast.filter.Has(ns.bse.tag, ast.filter.GreaterThan(5)))) def test_is(self): # type must be node 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).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'))) def test_value(self): # type must be literal self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.node(ns.bsfs.Node), ast.filter.Equals('hello world')) self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.node(ns.bsfs.Node), ast.filter.Substring('hello world')) self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.node(ns.bsfs.Node), ast.filter.StartsWith('hello world')) 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).child(ns.bsfs.Invalid), ast.filter.Equals('hello world')) 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).child(ns.bsfs.Invalid), ast.filter.StartsWith('hello world')) 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'))) self.assertIsNone(self.validate._value(self.schema.literal(ns.xsd.string), ast.filter.Substring('hello world'))) self.assertIsNone(self.validate._value(self.schema.literal(ns.xsd.string), ast.filter.StartsWith('hello world'))) self.assertIsNone(self.validate._value(self.schema.literal(ns.xsd.string), ast.filter.EndsWith('hello world'))) def test_bounded(self): # type must be literal self.assertRaises(errors.ConsistencyError, self.validate._bounded, self.schema.node(ns.bsfs.Node), ast.filter.GreaterThan(0)) 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).child(ns.bsfs.Invalid), ast.filter.GreaterThan(0)) 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.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.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 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))) class TestFetch(unittest.TestCase): def setUp(self): self.schema = _schema.from_string(''' prefix rdfs: prefix xsd: prefix bsfs: prefix bse: bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . bse:filename rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Node ; rdfs:range xsd:string . bse:tag rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range bsfs:Tag . bse:label rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Tag ; rdfs:range xsd:string . ''') self.validate = Fetch(self.schema) def test_call(self): # tests validate implicitly # call accepts correct expressions self.assertTrue(self.validate(self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.tag, ast.fetch.Value(ns.bse.label, 'value')))) self.assertTrue(self.validate(self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this')))) self.assertTrue(self.validate(self.schema.node(ns.bsfs.Entity), ast.fetch.This('this'))) self.assertTrue(self.validate(self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.This('this'), ast.fetch.Node(ns.bse.tag, 'node'), ast.fetch.Value(ns.bse.filename, 'value')))) # type must be a Node self.assertRaises(TypeError, self.validate, 1234, ast.fetch.This('this')) self.assertRaises(TypeError, self.validate, 'foobar', ast.fetch.This('this')) self.assertRaises(TypeError, self.validate, self.schema.literal(ns.bsfs.Literal), ast.fetch.This('this')) # type must be in the schema self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch.FetchExpression()) # expression must be a fetch expression self.assertRaises(TypeError, self.validate, self.schema.node(ns.bsfs.Entity), 1234) self.assertRaises(TypeError, self.validate, self.schema.node(ns.bsfs.Entity), 'hello') self.assertRaises(TypeError, self.validate, self.schema.node(ns.bsfs.Entity), ast.filter.FilterExpression()) # expression must be valid self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.tag, ast.fetch.Node(ns.bse.label, 'node'))) self.assertRaises(errors.ConsistencyError, self.validate, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.tag, 'value')) def test_routing(self): # Node passes _branch, _named, and _node checks self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Node), ast.fetch.Node(ns.bse.tag, 'node')) # fails in _branch self.assertRaises(errors.BackendError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.tag, '')) # fails in _named self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.label, 'node')) # fails in _node # Value passes _branch, _named, and _value checks self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Node), ast.fetch.Value(ns.bse.label, 'value')) # fails in _branch self.assertRaises(errors.BackendError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, '')) # fails in _named self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.tag, 'value')) # fails in _value # Fetch passes _branch and _fetch checks self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this'))) # fails in _branch self.assertRaises(errors.ConsistencyError, self.validate._parse_fetch_expression, self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.filename, ast.fetch.This('this'))) # fails in _fetch # invalid expressions cannot be parsed type_ = self.schema.node(ns.bsfs.Node) self.assertRaises(errors.BackendError, self.validate._parse_fetch_expression, type_, ast.filter.FilterExpression()) self.assertRaises(errors.BackendError, self.validate._parse_fetch_expression, type_, 1234) self.assertRaises(errors.BackendError, self.validate._parse_fetch_expression, type_, 'hello world') def test_all(self): # all accepts correct expressions self.assertIsNone(self.validate._all(self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.Value(ns.bse.filename, 'value'), ast.fetch.Node(ns.bse.tag, 'node')))) # child expressions must be valid self.assertRaises(errors.ConsistencyError, self.validate._all, self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.Value(ns.bse.tag, 'value'))) self.assertRaises(errors.ConsistencyError, self.validate._all, self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.Value(ns.bse.filename, 'value'), ast.fetch.Node(ns.bse.filename, 'node'))) self.assertRaises(errors.ConsistencyError, self.validate._all, self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.Value(ns.bse.tag, 'value'), ast.fetch.Node(ns.bse.tag, 'node'))) self.assertRaises(errors.ConsistencyError, self.validate._all, self.schema.node(ns.bsfs.Entity), ast.fetch.All(ast.fetch.Value(ns.bse.tag, 'value'), ast.fetch.Node(ns.bse.filename, 'node'))) def test_branch(self): # branch accepts correct expressions self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch._Branch(ns.bse.filename))) self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this')))) self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, 'value'))) self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.tag, 'node'))) # type must be a node self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.literal(ns.bsfs.Literal), ast.fetch._Branch(ns.bse.filename)) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.literal(ns.bsfs.Literal), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.literal(ns.bsfs.Literal), ast.fetch.Value(ns.bse.filename, 'value')) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.literal(ns.bsfs.Literal), ast.fetch.Node(ns.bse.tag, 'node')) # type must be in the schema self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch._Branch(ns.bse.filename)) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch.Value(ns.bse.filename, 'value')) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch.Node(ns.bse.tag, 'node')) # predicate must be in the schema self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch._Branch(ns.bse.invalid)) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.invalid, ast.fetch.This('this'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.invalid, 'value')) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.invalid, 'node')) # predicate's domain must be related to the type self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch._Branch(ns.bse.label)) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Fetch(ns.bse.label, ast.fetch.This('this'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.label, 'node')) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.label, 'value')) # predicate's domain cannot be a supertype self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node), ast.fetch._Branch(ns.bse.tag)) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.tag, ast.fetch.This('this'))) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node), ast.fetch.Node(ns.bse.tag, 'node')) self.assertRaises(errors.ConsistencyError, self.validate._branch, self.schema.node(ns.bsfs.Node), ast.fetch.Value(ns.bse.tag, 'value')) # predicate's domain can be a subtype self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch._Branch(ns.bse.filename))) self.assertIsNone(self.validate._branch(self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, 'value'))) def test_fetch(self): # fetch accepts correct expressions self.assertIsNone(self.validate._fetch(self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.tag, ast.fetch.Value(ns.bse.label, 'value')))) # range must be a node self.assertRaises(errors.ConsistencyError, self.validate._fetch, self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.filename, ast.fetch.This('this'))) # child expression must be valid self.assertRaises(errors.ConsistencyError, self.validate._fetch, self.schema.node(ns.bsfs.Node), ast.fetch.Fetch(ns.bse.tag, ast.fetch.Node(ns.bse.label, 'node'))) def test_named(self): # named accepts correct expressions self.assertIsNone(self.validate._named(self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.tag, 'node'))) self.assertIsNone(self.validate._named(self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, 'value'))) # name must be non-empty self.assertRaises(errors.BackendError, self.validate._named, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.tag, '')) self.assertRaises(errors.BackendError, self.validate._named, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, '')) def test_node(self): # node accepts correct expressions self.assertIsNone(self.validate._node(self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.tag, 'node'))) # range must be a node self.assertRaises(errors.ConsistencyError, self.validate._node, self.schema.node(ns.bsfs.Entity), ast.fetch.Node(ns.bse.filename, 'node')) def test_value(self): # value accepts correct expressions self.assertIsNone(self.validate._value(self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.filename, 'value'))) # range must be a literal self.assertRaises(errors.ConsistencyError, self.validate._value, self.schema.node(ns.bsfs.Entity), ast.fetch.Value(ns.bse.tag, 'value')) def test_this(self): # this accepts correct expressions self.assertIsNone(self.validate._this(self.schema.node(ns.bsfs.Entity), ast.fetch.This('this'))) # type must be a node self.assertRaises(errors.ConsistencyError, self.validate._this, self.schema.literal(ns.bsfs.Literal), ast.fetch.This('this')) self.assertRaises(errors.ConsistencyError, self.validate._this, self.schema.predicate(ns.bsfs.Predicate), ast.fetch.This('this')) # type must be in the schema self.assertRaises(errors.ConsistencyError, self.validate._this, self.schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), ast.fetch.This('this')) # name must be non-empty self.assertRaises(errors.BackendError, self.validate._this, self.schema.node(ns.bsfs.Entity), ast.fetch.This('')) ## main ## if __name__ == '__main__': unittest.main() ## EOF ##