def test_nametest_step(self): xp = xpath.parse('''author''') self.assert_(isinstance(xp, ast.Step)) self.assert_(xp.axis is None) # or should this be 'child', the default? self.assert_(isinstance(xp.node_test, ast.NameTest)) self.assert_(xp.node_test.prefix is None) self.assertEqual('author', xp.node_test.name) self.assertEqual(0, len(xp.predicates))
def test_function(self): xp = xpath.parse('''author[position() = 1]''') self.assert_(isinstance(xp.predicates[0], ast.BinaryExpression)) self.assertEqual('=', xp.predicates[0].op) self.assert_(isinstance(xp.predicates[0].left, ast.FunctionCall)) self.assertEqual('position', xp.predicates[0].left.name) self.assertEqual(0, len(xp.predicates[0].left.args)) self.assertEqual(1, xp.predicates[0].right)
def test_relative_path(self): xp = xpath.parse('''book//author/first-name''') self.assert_(isinstance(xp, ast.BinaryExpression)) self.assert_(isinstance(xp.left, ast.BinaryExpression)) self.assertEqual('book', xp.left.left.node_test.name) self.assertEqual('//', xp.left.op) self.assertEqual('author', xp.left.right.node_test.name) self.assertEqual('/', xp.op) self.assertEqual('first-name', xp.right.node_test.name)
def test_variable(self): xp = xpath.parse('''title[substring-after(text(), $pre:separator) = "world"]''') self.assertEqual('title', xp.node_test.name) self.assert_(isinstance(xp.predicates[0], ast.BinaryExpression)) self.assertEqual('=', xp.predicates[0].op) self.assertEqual('world', xp.predicates[0].right) # no quotes, just a string self.assert_(isinstance(xp.predicates[0].left, ast.FunctionCall)) self.assertEqual('substring-after', xp.predicates[0].left.name) self.assertEqual(2, len(xp.predicates[0].left.args)) self.assert_(isinstance(xp.predicates[0].left.args[0], ast.Step)) self.assertEqual('text', xp.predicates[0].left.args[0].node_test.name) self.assert_(isinstance(xp.predicates[0].left.args[1], ast.VariableReference)) self.assertEqual(('pre', 'separator'), xp.predicates[0].left.args[1].name)
def test_predicated_expression(self): xp = xpath.parse('''(book or article)[author/last-name = "Jones"]''') self.assert_(isinstance(xp, ast.PredicatedExpression)) self.assert_(isinstance(xp.base, ast.BinaryExpression)) self.assertEqual('book', xp.base.left.node_test.name) self.assertEqual('or', xp.base.op) self.assertEqual('article', xp.base.right.node_test.name) self.assertEqual(1, len(xp.predicates)) self.assertEqual('=', xp.predicates[0].op) self.assertEqual('Jones', xp.predicates[0].right) self.assertEqual('/', xp.predicates[0].left.op) self.assertEqual('author', xp.predicates[0].left.left.node_test.name) self.assertEqual('last-name', xp.predicates[0].left.right.node_test.name)
def __init__(self, xpath, manager, mapper, required=None, verbose_name=None, help_text=None): # compile xpath in order to catch an invalid xpath at load time etree.XPath(xpath) # NOTE: not saving compiled xpath because namespaces must be # passed in at compile time when evaluating an etree.XPath on a node self.xpath = xpath self.manager = manager self.mapper = mapper self.required = required self.verbose_name = verbose_name self.help_text = help_text # pre-parse the xpath for setters, etc self.parsed_xpath = parse(xpath) # adjust creation counter, save local copy of current count self.creation_counter = Field.creation_counter Field.creation_counter += 1
def test_lex_exceptions(self): # http://www.w3.org/TR/xpath/#exprlex describes several unusual # lexing rules. Verify them here. xp = xpath.parse('''***''') self.assert_(isinstance(xp, ast.BinaryExpression)) self.assertEqual('*', xp.op) self.assert_(isinstance(xp.left, ast.Step)) self.assert_(isinstance(xp.left.node_test, ast.NameTest)) self.assertEqual('*', xp.left.node_test.name) self.assert_(isinstance(xp.right, ast.Step)) self.assert_(isinstance(xp.right.node_test, ast.NameTest)) self.assertEqual('*', xp.right.node_test.name) xp = xpath.parse('''div div div''') self.assert_(isinstance(xp, ast.BinaryExpression)) self.assertEqual('div', xp.op) self.assert_(isinstance(xp.left, ast.Step)) self.assert_(isinstance(xp.left.node_test, ast.NameTest)) self.assertEqual('div', xp.left.node_test.name) self.assert_(isinstance(xp.right, ast.Step)) self.assert_(isinstance(xp.right.node_test, ast.NameTest)) self.assertEqual('div', xp.right.node_test.name) xp = xpath.parse('''div:div''') self.assert_(isinstance(xp, ast.Step)) self.assertEqual('div', xp.node_test.prefix) self.assertEqual('div', xp.node_test.name) xp = xpath.parse('''node/node()''') self.assert_(isinstance(xp, ast.BinaryExpression)) self.assertEqual('/', xp.op) self.assert_(isinstance(xp.left, ast.Step)) self.assert_(isinstance(xp.left.node_test, ast.NameTest)) self.assertEqual('node', xp.left.node_test.name) self.assert_(isinstance(xp.right, ast.Step)) self.assert_(isinstance(xp.right.node_test, ast.NodeType)) self.assertEqual('node', xp.right.node_test.name) xp = xpath.parse('''boolean(boolean)''') self.assert_(isinstance(xp, ast.FunctionCall)) self.assertEqual('boolean', xp.name) self.assertEqual(1, len(xp.args)) self.assert_(isinstance(xp.args[0], ast.Step)) self.assertEqual('boolean', xp.args[0].node_test.name) xp = xpath.parse('''parent::parent/parent:parent''') self.assertEqual('parent', xp.left.axis) self.assertEqual('parent', xp.left.node_test.name) self.assertEqual('parent', xp.right.node_test.prefix) self.assertEqual('parent', xp.right.node_test.name)
def test_step_predicate(self): xp = xpath.parse('''book[author]''') self.assertEqual('book', xp.node_test.name) self.assertEqual(1, len(xp.predicates)) self.assertEqual('author', xp.predicates[0].node_test.name)
def test_absolute_path(self): xp = xpath.parse('''/book//author''') self.assert_(isinstance(xp, ast.AbsolutePath)) self.assertEqual('/', xp.op) self.assertEqual('book', xp.relative.left.node_test.name)
def test_axis(self): xp = xpath.parse('''ancestor::lib:book''') self.assert_(isinstance(xp, ast.Step)) self.assertEqual('ancestor', xp.axis) self.assertEqual('lib', xp.node_test.prefix) self.assertEqual('book', xp.node_test.name)
def test_nodetype_step(self): xp = xpath.parse('''text()''') self.assert_(isinstance(xp, ast.Step)) self.assert_(isinstance(xp.node_test, ast.NodeType)) self.assertEqual('text', xp.node_test.name)
def round_trip(self, xpath_str): xp = xpath.parse(xpath_str) self.assertEqual(xpath_str, serialize(xp))