cmlenz@1: # -*- coding: utf-8 -*-
cmlenz@1: #
cmlenz@66: # Copyright (C) 2006 Edgewall Software
cmlenz@1: # All rights reserved.
cmlenz@1: #
cmlenz@1: # This software is licensed as described in the file COPYING, which
cmlenz@1: # you should have received as part of this distribution. The terms
cmlenz@66: # are also available at http://markup.edgewall.org/wiki/License.
cmlenz@1: #
cmlenz@1: # This software consists of voluntary contributions made by many
cmlenz@1: # individuals. For the exact contribution history, see the revision
cmlenz@66: # history and logs, available at http://markup.edgewall.org/log/.
cmlenz@1:
cmlenz@1: import doctest
cmlenz@1: import unittest
cmlenz@1:
cmlenz@26: from markup.input import XML
cmlenz@111: from markup.path import Path, PathSyntaxError
cmlenz@26:
cmlenz@26:
cmlenz@26: class PathTestCase(unittest.TestCase):
cmlenz@26:
cmlenz@111: def test_error_no_absolute_path(self):
cmlenz@111: self.assertRaises(PathSyntaxError, Path, '/root')
cmlenz@111:
cmlenz@111: def test_error_unsupported_axis(self):
cmlenz@137: self.assertRaises(PathSyntaxError, Path, '..')
cmlenz@111: self.assertRaises(PathSyntaxError, Path, 'parent::ma')
cmlenz@111:
cmlenz@164: def test_error_position_predicate(self):
cmlenz@164: self.assertRaises(PathSyntaxError, Path, 'item[0]')
cmlenz@164:
cmlenz@26: def test_1step(self):
cmlenz@38: xml = XML('')
cmlenz@137:
cmlenz@137: path = Path('elem')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('child::elem')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('//elem')
cmlenz@137: self.assertEqual('',
cmlenz@137: repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('descendant::elem')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_1step_self(self):
cmlenz@106: xml = XML('')
cmlenz@137:
cmlenz@137: path = Path('.')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('self::node()')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@26: def test_1step_wildcard(self):
cmlenz@38: xml = XML('')
cmlenz@137:
cmlenz@137: path = Path('*')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('child::*')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('child::node()')
cmlenz@137: self.assertEqual('', repr(path))
cmlenz@111: self.assertEqual('', Path('child::node()').select(xml).render())
cmlenz@137:
cmlenz@137: path = Path('//*')
cmlenz@137: self.assertEqual('',
cmlenz@137: repr(path))
cmlenz@137: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@26: def test_1step_attribute(self):
cmlenz@138: path = Path('@foo')
cmlenz@138: self.assertEqual('', repr(path))
cmlenz@216:
cmlenz@216: xml = XML('')
cmlenz@216: self.assertEqual('', path.select(xml).render())
cmlenz@138:
cmlenz@111: xml = XML('')
cmlenz@138: self.assertEqual('bar', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('./@foo')
cmlenz@138: self.assertEqual('', repr(path))
cmlenz@111: self.assertEqual('bar', Path('./@foo').select(xml).render())
cmlenz@26:
cmlenz@111: def test_1step_text(self):
cmlenz@111: xml = XML('Hey')
cmlenz@138:
cmlenz@138: path = Path('text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Hey', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('./text()')
cmlenz@138: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Hey', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('//text()')
cmlenz@138: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@138: self.assertEqual('Hey', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('.//text()')
cmlenz@215: self.assertEqual('',
cmlenz@215: repr(path))
cmlenz@138: self.assertEqual('Hey', path.select(xml).render())
cmlenz@26:
cmlenz@26: def test_2step(self):
cmlenz@26: xml = XML('')
cmlenz@111: self.assertEqual('', Path('*').select(xml).render())
cmlenz@111: self.assertEqual('', Path('bar').select(xml).render())
cmlenz@111: self.assertEqual('', Path('baz').select(xml).render())
cmlenz@26:
cmlenz@145: def test_2step_attribute(self):
cmlenz@145: xml = XML('Hey Joe')
cmlenz@216: self.assertEqual('x', Path('@*').select(xml).render())
cmlenz@216: self.assertEqual('x', Path('./@*').select(xml).render())
cmlenz@216: self.assertEqual('xjoe', Path('.//@*').select(xml).render())
cmlenz@145: self.assertEqual('joe', Path('*/@*').select(xml).render())
cmlenz@145:
cmlenz@215: xml = XML('')
cmlenz@216: self.assertEqual('', Path('@*').select(xml).render())
cmlenz@216: self.assertEqual('12', Path('foo/@*').select(xml).render())
cmlenz@145:
cmlenz@26: def test_2step_complex(self):
cmlenz@26: xml = XML('')
cmlenz@138:
cmlenz@138: path = Path('foo/bar')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@138:
cmlenz@145: path = Path('./bar')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@216: self.assertEqual('', path.select(xml).render())
cmlenz@145:
cmlenz@138: path = Path('foo/*')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@26:
cmlenz@26: xml = XML('')
cmlenz@145: path = Path('./bar')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@216: self.assertEqual('', path.select(xml).render())
cmlenz@26:
cmlenz@26: def test_2step_text(self):
cmlenz@26: xml = XML('- Foo
')
cmlenz@138:
cmlenz@138: path = Path('item/text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Foo', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('*/text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Foo', path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('//text()')
cmlenz@138: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@138: self.assertEqual('Foo', path.select(xml).render())
cmlenz@138:
cmlenz@145: path = Path('./text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@216: self.assertEqual('', path.select(xml).render())
cmlenz@145:
cmlenz@26: xml = XML('- Foo
- Bar
')
cmlenz@145: path = Path('item/text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@145: self.assertEqual('FooBar', path.select(xml).render())
cmlenz@145:
cmlenz@145: xml = XML('- Foo
- Bar
')
cmlenz@145: self.assertEqual('FooBar', path.select(xml).render())
cmlenz@26:
cmlenz@26: def test_3step(self):
cmlenz@26: xml = XML('')
cmlenz@162: path = Path('foo/*')
cmlenz@162: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@26:
cmlenz@26: def test_3step_complex(self):
cmlenz@26: xml = XML('')
cmlenz@138: path = Path('*/bar')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@138:
cmlenz@26: xml = XML('')
cmlenz@138: path = Path('//bar')
cmlenz@138: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@26: self.assertEqual('',
cmlenz@138: path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_node_type_comment(self):
cmlenz@106: xml = XML('')
cmlenz@138: path = Path('comment()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_node_type_text(self):
cmlenz@106: xml = XML('Some text
in here.')
cmlenz@138: path = Path('text()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Some text in here.', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_node_type_node(self):
cmlenz@106: xml = XML('Some text
in here.')
cmlenz@138: path = Path('node()')
cmlenz@145: self.assertEqual('', repr(path))
cmlenz@138: self.assertEqual('Some text
in here.', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_node_type_processing_instruction(self):
cmlenz@106: xml = XML('')
cmlenz@138:
cmlenz@138: path = Path('processing-instruction()')
cmlenz@145: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@106: self.assertEqual('',
cmlenz@138: path.select(xml).render())
cmlenz@138:
cmlenz@138: path = Path('processing-instruction("php")')
cmlenz@145: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@138: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_simple_union(self):
cmlenz@106: xml = XML('Oh my')
cmlenz@138: path = Path('*|text()')
cmlenz@145: self.assertEqual('',
cmlenz@138: repr(path))
cmlenz@138: self.assertEqual('Oh my', path.select(xml).render())
cmlenz@26:
cmlenz@121: def test_predicate_name(self):
cmlenz@121: xml = XML('')
cmlenz@121: self.assertEqual('',
cmlenz@121: Path('*[name()="foo"]').select(xml).render())
cmlenz@121:
cmlenz@121: def test_predicate_localname(self):
cmlenz@121: xml = XML('')
cmlenz@121: self.assertEqual('',
cmlenz@121: Path('*[local-name()="foo"]').select(xml).render())
cmlenz@121:
cmlenz@121: def test_predicate_namespace(self):
cmlenz@121: xml = XML('')
cmlenz@121: self.assertEqual('',
cmlenz@121: Path('*[namespace-uri()="NS"]').select(xml).render())
cmlenz@121:
cmlenz@121: def test_predicate_not_name(self):
cmlenz@121: xml = XML('')
cmlenz@121: self.assertEqual('',
cmlenz@121: Path('*[not(name()="foo")]').select(xml).render())
cmlenz@121:
cmlenz@26: def test_predicate_attr(self):
cmlenz@26: xml = XML(' ')
cmlenz@26: self.assertEqual(' ',
cmlenz@162: Path('item[@important]').select(xml).render())
cmlenz@26: self.assertEqual(' ',
cmlenz@162: Path('item[@important="very"]').select(xml).render())
cmlenz@26:
cmlenz@106: def test_predicate_attr_equality(self):
cmlenz@26: xml = XML(' ')
cmlenz@26: self.assertEqual('',
cmlenz@162: Path('item[@important="very"]').select(xml).render())
cmlenz@26: self.assertEqual(' ',
cmlenz@162: Path('item[@important!="very"]').select(xml).render())
cmlenz@162:
cmlenz@162: def test_predicate_attr_greater_than(self):
cmlenz@162: xml = XML(' ')
cmlenz@162: self.assertEqual('',
cmlenz@162: Path('item[@priority>3]').select(xml).render())
cmlenz@162: self.assertEqual(' ',
cmlenz@162: Path('item[@priority>2]').select(xml).render())
cmlenz@162:
cmlenz@162: def test_predicate_attr_less_than(self):
cmlenz@162: xml = XML(' ')
cmlenz@162: self.assertEqual('',
cmlenz@162: Path('item[@priority<3]').select(xml).render())
cmlenz@162: self.assertEqual(' ',
cmlenz@162: Path('item[@priority<4]').select(xml).render())
cmlenz@1:
cmlenz@106: def test_predicate_attr_and(self):
cmlenz@106: xml = XML(' ')
cmlenz@162: path = Path('item[@important and @important="very"]')
cmlenz@106: self.assertEqual(' ', path.select(xml).render())
cmlenz@162: path = Path('item[@important and @important="notso"]')
cmlenz@106: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@106: def test_predicate_attr_or(self):
cmlenz@106: xml = XML(' ')
cmlenz@162: path = Path('item[@urgent or @important]')
cmlenz@106: self.assertEqual(' ', path.select(xml).render())
cmlenz@162: path = Path('item[@urgent or @notso]')
cmlenz@106: self.assertEqual('', path.select(xml).render())
cmlenz@106:
cmlenz@155: def test_predicate_boolean_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[boolean("")]')
cmlenz@155: self.assertEqual('', path.select(xml).render())
cmlenz@155: path = Path('*[boolean("yo")]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155: path = Path('*[boolean(0)]')
cmlenz@155: self.assertEqual('', path.select(xml).render())
cmlenz@155: path = Path('*[boolean(42)]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155: path = Path('*[boolean(false())]')
cmlenz@155: self.assertEqual('', path.select(xml).render())
cmlenz@155: path = Path('*[boolean(true())]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_ceil_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[ceiling("4.5")=5]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_concat_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[name()=concat("f", "oo")]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_contains_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[contains(name(), "oo")]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_false_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[false()]')
cmlenz@155: self.assertEqual('', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_floor_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[floor("4.5")=4]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_normalize_space_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[normalize-space(" foo bar ")="foo bar"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_number_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[number("3.0")=3]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@163: path = Path('*[number("3.0")=3.0]')
cmlenz@163: self.assertEqual('bar', path.select(xml).render())
cmlenz@163: path = Path('*[number("0.1")=.1]')
cmlenz@163: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@162: def test_predicate_round_function(self):
cmlenz@162: xml = XML('bar')
cmlenz@162: path = Path('*[round("4.4")=4]')
cmlenz@162: self.assertEqual('bar', path.select(xml).render())
cmlenz@162: path = Path('*[round("4.6")=5]')
cmlenz@162: self.assertEqual('bar', path.select(xml).render())
cmlenz@162:
cmlenz@155: def test_predicate_starts_with_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[starts-with(name(), "f")]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_string_length_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[string-length(name())=3]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_substring_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[substring(name(), 1)="oo"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155: path = Path('*[substring(name(), 1, 1)="o"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_substring_after_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[substring-after(name(), "f")="oo"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_substring_before_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[substring-before(name(), "oo")="f"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_translate_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[translate(name(), "fo", "ba")="baa"]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@155: def test_predicate_true_function(self):
cmlenz@155: xml = XML('bar')
cmlenz@155: path = Path('*[true()]')
cmlenz@155: self.assertEqual('bar', path.select(xml).render())
cmlenz@155:
cmlenz@179: def test_predicate_variable(self):
cmlenz@179: xml = XML('bar')
cmlenz@179: path = Path('*[name()=$bar]')
cmlenz@179: variables = {'bar': 'foo'}
cmlenz@179: self.assertEqual('bar', path.select(xml, variables).render())
cmlenz@179:
cmlenz@1:
cmlenz@1: def suite():
cmlenz@1: suite = unittest.TestSuite()
cmlenz@111: suite.addTest(doctest.DocTestSuite(Path.__module__))
cmlenz@26: suite.addTest(unittest.makeSuite(PathTestCase, 'test'))
cmlenz@1: return suite
cmlenz@1:
cmlenz@1: if __name__ == '__main__':
cmlenz@1: unittest.main(defaultTest='suite')