# imports import unittest # bsie imports from bsfs import schema as bsc from bsfs.graph import Graph, nodes from bsfs.namespace import ns from bsfs.query import ast from bsfs.triple_store import SparqlStore from bsfs.utils import URI, errors # objects to test from bsfs.graph.resolve import Filter ## code ## ns.bse = ns.bsfs.Entity() class TestFilter(unittest.TestCase): """ NOTE: The Filter resolver is relatively simple as it only checks and changes ast.filter.Is instances. Hence, we don't test all methods individually but all of them with respect to ast.filter.Is elements. """ def test_call(self): # tests resolve implicitly schema = bsc.from_string(''' prefix rdfs: prefix xsd: prefix bsfs: prefix bse: prefix bsl: prefix bsa: bsfs:Entity rdfs:subClassOf bsfs:Node . bsfs:Tag rdfs:subClassOf bsfs:Node . xsd:string rdfs:subClassOf bsfs:Literal . 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 bsa:Feature ; bsfs:dimension "5"^^xsd:integer . bse:colors rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range bsfs:Colors . bse:comment rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; 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 "false"^^xsd:boolean . bse:tag rdfs:subClassOf bsfs:Predicate ; rdfs:domain bsfs:Entity ; rdfs:range bsfs:Tag ; bsfs:unique "false"^^xsd:boolean . ''') backend = SparqlStore.Open() backend.schema = schema graph = Graph(backend, URI('http://example.com/me')) ents = graph.nodes(ns.bsfs.Entity, {URI('http://example.com/me/entity#1234'), URI('http://example.com/me/entity#4321')}) tags = graph.nodes(ns.bsfs.Tag, {URI('http://example.com/me/tag#1234'), URI('http://example.com/me/tag#4321')}) invalid = nodes.Nodes(None, '', schema.node(ns.bsfs.Node).child(ns.bsfs.Invalid), {'http://example.com/you/invalid#1234', 'http://example.com/you/invalid#4321'}) resolver = Filter(schema) # query can be None self.assertIsNone(resolver(schema.node(ns.bsfs.Entity), None)) # immediate Is self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Is(ents)), ast.filter.Or( ast.filter.Is('http://example.com/me/entity#1234'), ast.filter.Is('http://example.com/me/entity#4321') )) # only resolves nodes instances, not URIs self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Is('http://example.com/me/entity#1234')), ast.filter.Is('http://example.com/me/entity#1234')) self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Is(1234)), ast.filter.Is(1234)) # within And (also checks _value) self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.And( ast.filter.Is(ents), ast.filter.Any(ns.bse.comment, ast.filter.Equals('hello world')), )), ast.filter.And( ast.filter.Or( ast.filter.Is('http://example.com/me/entity#1234'), ast.filter.Is('http://example.com/me/entity#4321')), ast.filter.Any(ns.bse.comment, ast.filter.Equals('hello world')) )) # within Or (checks _bounded) self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Or( ast.filter.Is(ents), ast.filter.Any(ns.bse.filesize, ast.filter.LessThan(5)), )), ast.filter.Or( ast.filter.Or( ast.filter.Is('http://example.com/me/entity#1234'), ast.filter.Is('http://example.com/me/entity#4321')), ast.filter.Any(ns.bse.filesize, ast.filter.LessThan(5)) )) # Any-branched Is self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Any(ns.bse.tag, ast.filter.Is(tags))), ast.filter.Any(ns.bse.tag, ast.filter.Or( ast.filter.Is('http://example.com/me/tag#1234'), ast.filter.Is('http://example.com/me/tag#4321')), )) # All-branched Is self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.All(ns.bse.tag, ast.filter.Is(tags))), ast.filter.All(ns.bse.tag, ast.filter.Or( ast.filter.Is('http://example.com/me/tag#1234'), ast.filter.Is('http://example.com/me/tag#4321')), )) # Negated predicate self.assertEqual(resolver(schema.node(ns.bsfs.Tag), ast.filter.Any(ast.filter.Predicate(ns.bse.tag, reverse=True), ast.filter.Is(ents))), ast.filter.Any(ast.filter.Predicate(ns.bse.tag, reverse=True), ast.filter.Or( ast.filter.Is('http://example.com/me/entity#1234'), ast.filter.Is('http://example.com/me/entity#4321')), )) # negated Is self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Not(ast.filter.Is(ents))), ast.filter.Not( ast.filter.Or( ast.filter.Is('http://example.com/me/entity#1234'), ast.filter.Is('http://example.com/me/entity#4321')), )) # for sake of completeness: Has self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Has(ns.bse.comment)), ast.filter.Has(ns.bse.comment)) # for sake of completeness: Distance self.assertEqual(resolver(schema.node(ns.bsfs.Entity), ast.filter.Any(ns.bse.colors, ast.filter.Distance([1,2,3,4,5], 1))), ast.filter.Any(ns.bse.colors, ast.filter.Distance([1,2,3,4,5], 1))) # route errors self.assertRaises(errors.BackendError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Predicate(ns.bse.comment)) self.assertRaises(errors.BackendError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ast.filter.PredicateExpression(), ast.filter.Equals('foo'))) self.assertRaises(errors.BackendError, resolver._one_of, ast.filter.OneOf(ast.filter.Predicate(ns.bsfs.Predicate))) # for sake of coverage completeness: valid OneOf self.assertIsNotNone(resolver._one_of(ast.filter.OneOf(ast.filter.Predicate(ns.bse.colors)))) # check schema consistency self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Is(invalid)) # check immediate type compatibility self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Is(ents)) self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Entity), ast.filter.Is(tags)) # check type compatibility through branches self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ns.bse.comment, ast.filter.Is(tags))) self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ns.bse.invalid, ast.filter.Is(tags))) self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ast.filter.OneOf(ns.bse.comment, ns.bse.tag), ast.filter.Is(tags))) self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ast.filter.OneOf(ns.bse.comment, ns.bse.filesize), ast.filter.Is(tags))) self.assertRaises(errors.ConsistencyError, resolver, schema.node(ns.bsfs.Tag), ast.filter.Any(ast.filter.Predicate(ns.bse.tag, reverse=True), ast.filter.Is(tags))) ## main ## if __name__ == '__main__': unittest.main() ## EOF ##