def test_dummy5(self): """test DummyExpression on the right hand side of "and" op""" xpb = XPathBuilder() xp = xpb.dummy() xp = xpb.foo & xp exp = '/foo' self.assertEqual(xp.tostring(), exp)
def test_path5(self): """test descendant axis""" xpb = XPathBuilder() xp = xpb.descendant('foo').bar.descendant('baz') # do not use abbreviated syntax exp = '/descendant::foo/bar/descendant::baz' self.assertEqual(xp.tostring(), exp)
def test_predicate10(self): """test a predicate with attribute and path expression (written ops)""" xpb = XPathBuilder() pred = xpb.attr('foo').equals('bar').log_or(xpb.foobar) xp = xpb.foo.bar.where(pred) exp = '/foo/bar[@foo = "bar" or /foobar]' self.assertEqual(xp.tostring(), exp)
def test_predicate4(self): """test a path expression with multiple predicates (written ops)""" xpb = XPathBuilder() xp = xpb.foo.bar.where(xpb.attr('name').not_equals('abc')) xp = xp.where(xpb.attr('x').equals('foo')) exp = '/foo/bar[@name != "abc"][@x = "foo"]' self.assertEqual(xp.tostring(), exp)
def test_dummy6(self): """test DummyExpression on the right hand side of "or" op""" xpb = XPathBuilder() xp = xpb.dummy() xp = xpb.bar | xp exp = '/bar' self.assertEqual(xp.tostring(), exp)
def test_predicate12(self): """test a "chained" predicate (written ops)""" xpb = XPathBuilder() pred = (xpb.attr('d').equals('e').log_and( xpb.foo.where(xpb.attr('z').equals('abc')))) xp = xpb.a.b.c.where(pred) exp = '/a/b/c[@d = "e" and /foo[@z = "abc"]]' self.assertEqual(xp.tostring(), exp)
def test_predicate8(self): """test a predicate with more conditions (written ops)""" xpb = XPathBuilder() pred = (xpb.attr('name').equals('foo').log_and( xpb.attr('x').equals('x'))) xp = xpb.foo.bar.where(pred) exp = '/foo/bar[@name = "foo" and @x = "x"]' self.assertEqual(xp.tostring(), exp)
def test_predicate12(self): """test a "chained" predicate (written ops)""" xpb = XPathBuilder() pred = (xpb.attr('d').equals('e') .log_and(xpb.foo.where(xpb.attr('z').equals('abc')))) xp = xpb.a.b.c.where(pred) exp = '/a/b/c[@d = "e" and /foo[@z = "abc"]]' self.assertEqual(xp.tostring(), exp)
def test_predicate8(self): """test a predicate with more conditions (written ops)""" xpb = XPathBuilder() pred = (xpb.attr('name').equals('foo') .log_and(xpb.attr('x').equals('x'))) xp = xpb.foo.bar.where(pred) exp = '/foo/bar[@name = "foo" and @x = "x"]' self.assertEqual(xp.tostring(), exp)
def test_dummy2(self): """test dummy method 2""" xpb = XPathBuilder() xp = xpb.dummy() self.assertFalse(xp) xp = xp & (xpb.attr('foo') == 'xyz') self.assertTrue(xp) exp = '@foo = "xyz"' self.assertEqual(xp.tostring(), exp)
def test_dummy1(self): """test dummy method 1""" xpb = XPathBuilder() xp = xpb.dummy() self.assertFalse(xp) xp = xp & xpb.foo.bar self.assertTrue(xp) exp = '/foo/bar' self.assertEqual(xp.tostring(), exp)
def test_exception1(self): """test invalid expression tree""" xpb = XPathBuilder() pred = xpb.attr('foo') == 'bar' path = xpb.foo.bar pred_expr = path[pred] self.assertEqual(pred_expr.tostring(), '/foo/bar[@foo = "bar"]') pred.reparent(None) self.assertRaises(XPathSyntaxError, pred_expr.tostring)
def test_generator2(self): """test a non generator (everything happens in place) (written ops)""" xpb = XPathBuilder() xp = xpb.foo xp = xp.bar xp = xp.baz.where(xpb.attr('x').equals('y')) xp = xp.where(1) exp = '/foo/bar/baz[@x = "y"][1]' self.assertEqual(xp.tostring(), exp)
def test_generator1(self): """test a non generator (everything happens in place)""" xpb = XPathBuilder() xp = xpb.foo xp = xp.bar xp = xp.baz[xpb.attr('x') == 'y'] xp = xp[1] exp = '/foo/bar/baz[@x = "y"][1]' self.assertEqual(xp.tostring(), exp)
def test_request2(self): """test find_request (with validation)""" RequestCollection.SCHEMA = self.fixture_file('collection_request.xsd') xpb = XPathBuilder() xp = xpb.state[xpb.attr('name') == 'new'] collection = find_request(xp) self.assertTrue(len(collection.request[:]) == 1) self.assertEqual(collection.get('matches'), '1') self.assertEqual(collection.request[0].action.get('type'), 'submit') self.assertEqual(collection.request.action.get('type'), 'submit')
def test_context_item2(self): """test context item (disabled) for the initial expression""" xpb = XPathBuilder(context_item=False) xp1 = xpb.foo.bar xp1_exp = '/foo/bar' xp2 = xpb.context(True).foo.bar xp2_exp = './foo/bar' self.assertEqual(xp1.tostring(), xp1_exp) self.assertEqual(xp2.tostring(), xp2_exp) self.assertFalse(xpb.context_item)
def test_generator3(self): """test a xpath generator""" xpb = XPathBuilder() xp1 = xp2 = None base_xp = xpb.base.foo[xpb.attr('abc') == 'x'] with base_xp as b: xp1 = b().bar.text() == 'foo' xp2 = b().x.y.z[42] base_exp = '/base/foo[@abc = "x"]' xp1_exp = '/base/foo[@abc = "x"]/bar/text() = "foo"' xp2_exp = '/base/foo[@abc = "x"]/x/y/z[42]' self.assertEqual(base_xp.tostring(), base_exp) self.assertEqual(xp1.tostring(), xp1_exp) self.assertEqual(xp2.tostring(), xp2_exp)
def test_generator4(self): """test a xpath generator (written ops)""" xpb = XPathBuilder() xp1 = xp2 = None base_xp = xpb.base.foo.where(xpb.attr('abc').equals('x')) with base_xp as b: xp1 = b().bar.text().equals('foo') xp2 = b().x.y.z.where(42) base_exp = '/base/foo[@abc = "x"]' xp1_exp = '/base/foo[@abc = "x"]/bar/text() = "foo"' xp2_exp = '/base/foo[@abc = "x"]/x/y/z[42]' self.assertEqual(base_xp.tostring(), base_exp) self.assertEqual(xp1.tostring(), xp1_exp) self.assertEqual(xp2.tostring(), xp2_exp)
def test_pathop12(self): """test parenthesize (unusual use case)""" xpb = XPathBuilder() # braces not needed xp = xpb.foo & (xpb.bar.foo).parenthesize() | xpb.foobar exp = '/foo and (/bar/foo) or /foobar' self.assertEqual(xp.tostring(), exp)
def test_pathop13(self): """test parenthesize (unusual use case) (written ops)""" xpb = XPathBuilder() # braces not needed xp = xpb.foo.log_and(xpb.bar.foo.parenthesize()).log_or(xpb.foobar) exp = '/foo and (/bar/foo) or /foobar' self.assertEqual(xp.tostring(), exp)
def test_path6(self): """test preceding axis""" xpb = XPathBuilder() xp = xpb.foo.bar.preceding('baz').foobar # no abbreviated syntax for the preceding axis (afaik) exp = '/foo/bar/preceding::baz/foobar' self.assertEqual(xp.tostring(), exp)
def test_non_hashable1(self): """test hash() on an expression""" xpb = XPathBuilder() xp = xpb.foo.bar d = {} self.assertRaises(TypeError, hash, xp) self.assertRaises(TypeError, d.setdefault, xp, 'key')
def test_path7(self): """test parent axis""" xpb = XPathBuilder() xp = xpb.foo.bar.parent('baz').foobar # do not use abbreviated syntax exp = '/foo/bar/parent::baz/foobar' self.assertEqual(xp.tostring(), exp)
def test_pathop9(self): """test "and" and "or" with explicit parentheses (written ops)""" xpb = XPathBuilder() xp = (xpb.foo.bar.log_or(xpb.foobar).parenthesize().log_and( xpb.action.source)) exp = '(/foo/bar or /foobar) and /action/source' self.assertEqual(xp.tostring(), exp)
def _find_requests(cls, tgt_project, tgt_package, info): """Returns a collection of requests.""" xpb = XPathBuilder(is_relative=True) xp = xpb.dummy() by_kind, xp = cls._build_by_predicate(xpb, info, info.state) if not by_kind: xp = cls._add_states(xpb, xpb.dummy(), info.state) xp = (xpb.state.attr('name') == 'review') & xp.parenthesize() if tgt_project is not None: xp = xp & (xpb.action.target.attr('project') == tgt_project) if tgt_package is not None: xp = xp & (xpb.action.target.attr('package') == tgt_package) logger().debug(xp.tostring()) res = find_request(xp=xp, apiurl=info.apiurl) collection = [r for r in res] return collection
def test_pathop3(self): """test "|" (or) path expression""" xpb = XPathBuilder() # do not confuse with xpath's union op! xp = xpb.a.b.c | xpb.foo exp = '/a/b/c or /foo' self.assertEqual(xp.tostring(), exp)
def test_path8(self): """test a path join""" xpb = XPathBuilder() xp_1 = xpb.foo.baz xp_2 = xpb.bar.abc.join(xp_1) exp = '/bar/abc/foo/baz' self.assertEqual(xp_1, xp_2) self.assertEqual(xp_2.tostring(), exp)
def test_pathop11(self): """test parenthesize more complex path expression (written ops)""" xpb = XPathBuilder() xp = (xpb.foo.log_and(xpb.bar).log_or(xpb.baz).parenthesize().log_and( xpb.foobar)) exp = '(/foo and /bar or /baz) and /foobar' self.assertEqual(xp.tostring(), exp) # different notation but same xpath expression (no explicit braces!) xp = ((xpb.foo.log_and(xpb.bar.log_or( xpb.baz))).parenthesize().log_and(xpb.foobar))
def _find_reviews(cls, request, info): """Returns a list of reviews. If no reviews were found an empty list is returned. """ xpb = XPathBuilder(context_item=True) by_kind, xp = cls._build_by_predicate(xpb, info, []) if not by_kind: # return all reviews xp = xpb.review logger().debug(xp.tostring()) return request.findall(xp.tostring())
def _find_requests(cls, project, package, info): """Returns a collection of requests.""" xpb = XPathBuilder(is_relative=True) xp = xpb.dummy() # state has at least one element for state in info.state: xp = xp | xpb.state.attr('name') == state xp = xp.parenthesize() if info.user is not None: xp = xp & ((xpb.state.attr('who') == info.user) | (xpb.history.attr('who') == info.user)).parenthesize() if project is not None: tmp = ((xpb.action.target.attr('project') == project) | (xpb.action.source.attr('project') == project)) xp = xp & tmp.parenthesize() if package is not None: tmp = ((xpb.action.target.attr('package') == package) | (xpb.action.source.attr('package') == package)) xp = xp & tmp.parenthesize() logger().debug(xp.tostring()) res = find_request(xp=xp, apiurl=info.apiurl) collection = [r for r in res] return collection
def test_request1(self): """test find_request""" xpb = XPathBuilder() xp = xpb.state[(xpb.attr('name') == 'new') | (xpb.attr('name') == 'review')] xp = xp & (xpb.action.target[xpb.attr('project') == 'prj'] | xpb.action.source[xpb.attr('project') == 'prj'] ).parenthesize() collection = find_request(xp) self.assertTrue(len(collection.request[:]) == 3) self.assertEqual(collection.request[0].get('id'), '1') self.assertEqual(collection.request[0].action.source.get('project'), 'foo') self.assertEqual(collection.request[1].get('id'), '42') self.assertEqual(collection.request[1].action.get('type'), 'submit') self.assertEqual(collection.request[2].get('id'), '108') self.assertEqual(collection.request[2].review[2].get('by_group'), 'autobuild-team') # test __iter__ method of the collection ids = ['1', '42', '108'] for r in collection: self.assertEqual(r.get('id'), ids.pop(0)) self.assertTrue(len(ids) == 0)
def test_tree_mode2(self): """test list context in tree mode""" xpb = XPathBuilder() xp = xpb.foo.bar xp.tree_mode(True, xp) bar = xpb.bar bar.tree_mode(True, xp) baz = xpb.baz baz.tree_mode(True, xp) foo_bar = xpb.foo.bar foo_bar.tree_mode(True, xp) self.assertTrue(xp.is_tree_mode()) l = [bar, foo_bar, xp, baz] self.assertTrue(xp in l) l.remove(xp) self.assertTrue(len(l) == 3) self.assertFalse(xp in l) xp.tree_mode(False, xp) self.assertFalse(xp.is_tree_mode())
def test_generator5(self): """test a xpath generator (path join - append generated)""" xpb = XPathBuilder() xp = None base_xp = xpb.base.foo.bar base_gen = None with base_xp as b: base_gen = b xp = b().join(xpb.a.b.c[3]) exp = '/base/foo/bar/a/b/c[3]' base_exp = '/base/foo/bar' # check tree structure self.assertTrue(base_xp._parent is None) self.assertTrue(len(base_xp._children[0]._children[0]._children) == 0) self.assertTrue(base_gen._parent is None) self.assertTrue(len(base_gen._children) == 0) # check xpath self.assertEqual(xp.tostring(), exp) self.assertEqual(base_xp.tostring(), base_exp) self.assertEqual(base_gen.tostring(), base_exp)
def test_request4(self): """test find_request (validation fails)""" RequestCollection.SCHEMA = self.fixture_file('collection_request.xsd') xpb = XPathBuilder() xp = xpb.state[xpb.attr('name') == 'declined'] self.assertRaises(etree.DocumentInvalid, find_request, xp)
def test_relative3(self): """test a relative path expression (relative method)""" xpb = XPathBuilder() xp = xpb.foo.bar[xpb.relative(True).x.y.log_or(xpb.relative(True).z)] exp = '/foo/bar[x/y or z]' self.assertEqual(xp.tostring(), exp)
def test_dummy3(self): """test DummyExpression's parenthesize method""" xpb = XPathBuilder() xp = xpb.dummy() self.assertTrue(xp.parenthesize() is xp)
def test_dummy4(self): """test DummyExpression negate (log_not)""" xpb = XPathBuilder() xp = xpb.dummy() self.assertTrue(xp.log_not() is xp)
def test_predicate7(self): """test a predicate with more conditions""" xpb = XPathBuilder() xp = xpb.foo.bar[(xpb.attr('name') == 'foo') & (xpb.attr('x') == 'x')] exp = '/foo/bar[@name = "foo" and @x = "x"]' self.assertEqual(xp.tostring(), exp)
def test_predicate3(self): """test a path expression with multiple predicates""" xpb = XPathBuilder() xp = xpb.foo.bar[xpb.attr('name') != 'abc'][xpb.attr('x') == 'foo'] exp = '/foo/bar[@name != "abc"][@x = "foo"]' self.assertEqual(xp.tostring(), exp)
def test_predicate9(self): """test a predicate with attribute and path expression""" xpb = XPathBuilder() xp = xpb.foo.bar[(xpb.attr('foo') == 'bar') | xpb.foobar] exp = '/foo/bar[@foo = "bar" or /foobar]' self.assertEqual(xp.tostring(), exp)
def test_context_item4(self): """test context item (nested expression) (written ops)""" xpb = XPathBuilder() xp = xpb.foo.where(xpb.context(True).bar.log_or(xpb.context(True).baz)) exp = '/foo[./bar or ./baz]' self.assertEqual(xp.tostring(), exp)
def test_context_item3(self): """test context item (nested expression)""" xpb = XPathBuilder() xp = xpb.foo[xpb.context(True).bar | xpb.context(True).baz] exp = '/foo[./bar or ./baz]' self.assertEqual(xp.tostring(), exp)
def test_predicate11(self): """test a "chained" predicate""" xpb = XPathBuilder() xp = xpb.a.b.c[(xpb.attr('d') == 'e') & xpb.foo[xpb.attr('z') == 'ab']] exp = '/a/b/c[@d = "e" and /foo[@z = "ab"]]' self.assertEqual(xp.tostring(), exp)
def test_predicate13(self): """test contains function""" xpb = XPathBuilder() xp = xpb.foo.bar[xpb.attr('x').contains('foo')] exp = '/foo/bar[contains(@x, "foo")]' self.assertEqual(xp.tostring(), exp)