class TestUnionGroup(unittest.TestCase): def setUp(self): self.store = TripleStore() self.store.add_triples(('a', 'name', 'name-a'), ('b', 'name', 'name-b'), ('a', 'weight', 'weight-a'), ('b', 'size', 'size-b')) self.p = UnionGroup(Pattern(self.store, VariableExpression('id'), LiteralExpression('name'), VariableExpression('name')), Pattern(self.store, VariableExpression('id'), LiteralExpression('weight'), VariableExpression('weight'))) def test_match_empty_solution(self): self.assertEqual( [dict(id='a', name='name-a'), dict(id='b', name='name-b'), dict(id='a', weight='weight-a')], list(self.p.match({})) ) def test_match_with_constraining_solution(self): self.assertEqual( [dict(id='a', name='name-a'), dict(id='a', weight='weight-a')], list(self.p.match({'id': 'a'})) ) self.assertEqual( [dict(id='b', name='name-b'), dict(id='a', weight='weight-a', name='name-b')], list(self.p.match({'name': 'name-b'})) ) self.assertEqual( [], list(self.p.match({'id': 'c'})) )
class TestQuery(unittest.TestCase): def setUp(self): self.store = TripleStore() self.store.add_triples(('a', 'name', 'name-a'), ('b', 'name', 'name-b'), ('a', 'weight', 'weight-a'), ('b', 'size', 'size-b'), ('a', 'height', 100)) def test_query_simple(self): self.assertEqual( [('a', 'name-a'), ('b', 'name-b')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name }')) ) def test_query_join(self): self.assertEqual( [('a', 'name-a', 'weight-a')], list(self.store.query('SELECT ?id ?name ?weight WHERE { ?id name ?name . ?id weight ?weight }')) ) def test_query_join_unmatchable(self): self.assertEqual( [], list(self.store.query('SELECT ?id ?weight WHERE { ?id name ?name . ?name weight ?weight }')) ) def test_query_union(self): self.assertEqual( [('a', 'name-a', None), ('b', 'name-b', None), ('a', None, 'weight-a')], list(self.store.query('SELECT ?id ?name ?weight WHERE { { ?id name ?name} UNION {?id weight ?weight} }')) ) def test_single_optional(self): self.assertEqual( [('a', 'name-a', 'weight-a'), ('b', 'name-b', None)], list(self.store.query('SELECT ?id ?value ?weight WHERE { ?id name ?value OPTIONAL {?id weight ?weight} }')) ) self.assertEqual( [('b', 'name-b', None)], list(self.store.query('SELECT ?id ?value ?weight WHERE { ?id name ?value OPTIONAL {?id weight ?weight} ?id size ?size }')) ) def test_multiple_optional(self): self.assertEqual( [('a', 'name-a', 'weight-a', None), ('b', 'name-b', None, 'size-b')], list(self.store.query('''SELECT ?id ?value ?weight ?size WHERE { ?id name ?value OPTIONAL {?id weight ?weight} OPTIONAL {?id size ?size} }''')) ) def test_group_optional(self): self.assertEqual( [('a', 'name-a', None, None), ('b', 'name-b', None, None)], list(self.store.query('''SELECT ?id ?value ?weight ?size WHERE { ?id name ?value OPTIONAL {?id weight ?weight . ?id size ?size} }''')) ) def test_star_has_right_column_order(self): q = self.store.query('SELECT * WHERE { ?id name ?name }') self.assertEqual(('id', 'name'), tuple(v.name for v in q.variables)) q = self.store.query('SELECT * WHERE { { ?id name ?name} UNION {?id weight ?weight} }') self.assertEqual(('id', 'name', 'weight'), tuple(v.name for v in q.variables)) q = self.store.query('SELECT * WHERE { ?id name ?value OPTIONAL {?id weight ?weight} }') self.assertEqual(('id', 'value', 'weight'), tuple(v.name for v in q.variables)) def test_filter(self): self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height > 99) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height > 100) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height >= 100) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height >= 101) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height < 101) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height < 100) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height <= 100) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height <= 99) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height != 100) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height != 101) }')) ) self.assertEqual( [], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height = 101) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height = 100) }')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER (?height = 2*50) }')) ) def test_complex_filter(self): self.assertEqual( [('b', 'name', 'name-b')], list(self.store.query('SELECT ?id ?property ?value WHERE { ?id ?property ?value FILTER (regex(?value, "^name-") && ?id != "a")}')) ) self.assertEqual( [(100,)], list(self.store.query('SELECT ?height WHERE { ?id height ?height FILTER ((2* -?height) = 2* -100) }')) ) def test_order_by(self): self.assertEqual( [('a', 'name-a'), ('b', 'name-b')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name } ORDER BY ?name')) ) self.assertEqual( [('a', 'name-a'), ('b', 'name-b')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name } ORDER BY ASC(?name)')) ) self.assertEqual( [('b', 'name-b'), ('a', 'name-a')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name } ORDER BY DESC(?name)')) ) def test_limit(self): self.assertEqual( [('a', 'name-a')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name } ORDER BY ?name LIMIT 1')) ) def test_order_by(self): self.assertEqual( [('b', 'name-b')], list(self.store.query('SELECT ?id ?name WHERE { ?id name ?name } ORDER BY ?name OFFSET 1')) ) def test_distinct(self): self.assertEqual( set([('a',), ('b',)]), set(self.store.query('SELECT DISTINCT ?id WHERE { { ?id name ?name} UNION {?id weight ?weight} }')) )