def test_simple_match(self): """Check the base .match() method""" query = Query().match('') expected = '\n'.join(( 'MATCH (_a)', 'RETURN _a', )) self.assertEqual(str(query), expected) query = Query().match('SomeLabel') expected = '\n'.join(( 'MATCH (_a:SomeLabel)', 'RETURN _a', )) self.assertEqual(str(query), expected) query = Query().match('SomeLabel', 'var') expected = '\n'.join(( 'MATCH (var:SomeLabel)', 'RETURN var', )) self.assertEqual(str(query), expected) query = Query().match('SomeLabel:OtherLabel') expected = '\n'.join(( 'MATCH (_a:SomeLabel:OtherLabel)', 'RETURN _a', )) self.assertEqual(str(query), expected)
def test_bad_chain_query(self): """ Check if match/to/by/with_/connected_through statements are being applied in a correct order """ for method in ('with_', 'to', 'by', 'connected_through'): with self.assertRaisesRegex( exceptions.BadQuery, r'A matching query should start with a `match` method', ): getattr(Query(), method)('') for method in ('with_', 'to', 'by'): with self.assertRaisesRegex( exceptions.BadQuery, r'Two nodes should be connected through an edge', ): getattr(Query().match(''), method)('') with self.assertRaisesRegex( exceptions.BadQuery, r'Edge can not exist right after another edge', ): Query().match('').connected_through('').connected_through('') with self.assertRaisesRegex( exceptions.BadQuery, r'Method `match` can only be used once per query', ): Query().match('').match('')
def test_simple_where(self): """Check the .where() method with only .match()""" query = (Query().match('', 'a').where('exists(a.name)').where('a.age = 2')) expected = '\n'.join(( 'MATCH (a)', 'WHERE exists(a.name)', ' AND a.age = 2', 'RETURN a', )) self.assertEqual(str(query), expected)
def test_match_with_edge(self): """Test the most basic query with an edge""" class SomeNode(Node): """Node example""" class AnEdge(Edge): """Edge example""" query = (Query().match('').connected_through('').to('')) expected = '\n'.join(( 'MATCH (_a)-[_b]->(_c)', 'RETURN _a, _b, _c', )) self.assertEqual(str(query), expected) query = ( Query().match(SomeNode).connected_through(AnEdge).by(SomeNode)) expected = '\n'.join(( 'MATCH (_a:SomeNode)<-[_b:ANEDGE]-(_c:SomeNode)', 'RETURN _a, _b, _c', )) self.assertEqual(str(query), expected)
def test_match_with_node_class(self): """Simple match query, but passing a class instead of a string""" class OneNode(Node): """Node example""" query = Query().match(OneNode) expected = '\n'.join(( 'MATCH (_a:OneNode)', 'RETURN _a', )) self.assertEqual(str(query), expected) class TwoNode(Node): """Node example""" class Neo: """Neo with labels""" labels = ('Two', 'Node') query = Query().match(TwoNode, 'q') expected = '\n'.join(( 'MATCH (q:Node:Two)', 'RETURN q', )) self.assertEqual(str(query), expected)
def test_match_with_hops(self): """Test min_hops and max_hops in the `connected_through` method""" query = (Query().match('').connected_through( '', min_hops=1).to('').connected_through( '', max_hops=3).to('').connected_through( '', min_hops=1, max_hops=3).to('').connected_through('').to('')) expected = '\n'.join(( 'MATCH _f = (_a)-[*1..]->(_g),', ' _l = (_g)-[*..3]->(_m),', ' _r = (_m)-[*1..3]->(_s),', ' (_s)-[_t]->(_u)', 'WITH *, relationships(_f) AS _b, nodes(_f)[1..-1] AS _d,', ' relationships(_l) AS _h, nodes(_l)[1..-1] AS _j,', ' relationships(_r) AS _n, nodes(_r)[1..-1] AS _p', 'RETURN _a, _b, _d, _g, _h, _j, _m, _n, _p, _s, _t, _u', )) print(str(query)) self.assertEqual(str(query), expected)
def test_where_with_node(self): """Check the .where() method with a Node as a parameter""" class SomeNode(Node): """Node example""" attr = attributes.AnyAttr(prop_name='name') query = (Query().match( SomeNode, 'f').where(SomeNode.attr == 2).where('exists(f.something)').where( SomeNode.attr != '2')) expected = '\n'.join(( 'MATCH (f:SomeNode)', 'WHERE f.name = $a', ' AND exists(f.something)', ' AND f.name <> $b', 'RETURN f', )) self.assertEqual(str(query), expected) expected = {'a': 2, 'b': '2'} self.assertEqual(query.get_vars(), expected)
def test_where_with_edge(self): """Check the .where() method with a Node as a parameter""" class SomeNode(Node): """Node example""" attr = attributes.AnyAttr(prop_name='node_name') class SomeEdge(Edge): """Edge example""" attr = attributes.AnyAttr(prop_name='edge_name') query = (Query().match( SomeNode, 'f').where(SomeNode.attr == 2).connected_through( SomeEdge, '_a').where(SomeEdge.attr != '2').with_('')) expected = '\n'.join(( 'MATCH (f:SomeNode)-[_a:SOMEEDGE]-(_b)', 'WHERE f.node_name = $a,', ' AND _a.edge_name <> $b', 'RETURN _a, _b, f', )) self.assertEqual(str(query), expected) expected = {'a': 2, 'b': '2'} self.assertEqual(query.get_vars(), expected)