File: test_xpathfuncs.py

package info (click to toggle)
python-parsel 1.10.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 472 kB
  • sloc: python: 2,613; makefile: 159; xml: 15
file content (138 lines) | stat: -rw-r--r-- 3,919 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import unittest
from typing import Any

from parsel import Selector
from parsel.xpathfuncs import set_xpathfunc


class XPathFuncsTestCase(unittest.TestCase):
    def test_has_class_simple(self) -> None:
        body = """
        <p class="foo bar-baz">First</p>
        <p class="foo">Second</p>
        <p class="bar">Third</p>
        <p>Fourth</p>
        """
        sel = Selector(text=body)
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo")]/text()')],
            ["First", "Second"],
        )
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("bar")]/text()')],
            ["Third"],
        )
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo","bar")]/text()')],
            [],
        )
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo","bar-baz")]/text()')],
            ["First"],
        )

    def test_has_class_error_no_args(self) -> None:
        body = """
        <p CLASS="foo">First</p>
        """
        sel = Selector(text=body)
        self.assertRaisesRegex(
            ValueError,
            "has-class must have at least 1 argument",
            sel.xpath,
            "has-class()",
        )

    def test_has_class_error_invalid_arg_type(self) -> None:
        body = """
        <p CLASS="foo">First</p>
        """
        sel = Selector(text=body)
        self.assertRaisesRegex(
            ValueError,
            "has-class arguments must be strings",
            sel.xpath,
            "has-class(.)",
        )

    def test_has_class_error_invalid_unicode(self) -> None:
        body = """
        <p CLASS="foo">First</p>
        """
        sel = Selector(text=body)
        self.assertRaisesRegex(
            ValueError,
            "All strings must be XML compatible",
            sel.xpath,
            'has-class("héllö")'.encode(),
        )

    def test_has_class_unicode(self) -> None:
        body = """
        <p CLASS="fóó">First</p>
        """
        sel = Selector(text=body)
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("fóó")]/text()')],
            ["First"],
        )

    def test_has_class_uppercase(self) -> None:
        body = """
        <p CLASS="foo">First</p>
        """
        sel = Selector(text=body)
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo")]/text()')],
            ["First"],
        )

    def test_has_class_newline(self) -> None:
        body = """
        <p CLASS="foo
        bar">First</p>
        """
        sel = Selector(text=body)
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo")]/text()')],
            ["First"],
        )

    def test_has_class_tab(self) -> None:
        body = """
        <p CLASS="foo\tbar">First</p>
        """
        sel = Selector(text=body)
        self.assertEqual(
            [x.extract() for x in sel.xpath('//p[has-class("foo")]/text()')],
            ["First"],
        )

    def test_set_xpathfunc(self) -> None:
        def myfunc(ctx: Any) -> None:
            myfunc.call_count += 1  # type: ignore[attr-defined]

        myfunc.call_count = 0  # type: ignore[attr-defined]

        body = """
        <p CLASS="foo">First</p>
        """
        sel = Selector(text=body)
        self.assertRaisesRegex(
            ValueError,
            "Unregistered function in myfunc",
            sel.xpath,
            "myfunc()",
        )

        set_xpathfunc("myfunc", myfunc)
        sel.xpath("myfunc()")
        self.assertEqual(myfunc.call_count, 1)  # type: ignore[attr-defined]

        set_xpathfunc("myfunc", None)
        self.assertRaisesRegex(
            ValueError,
            "Unregistered function in myfunc",
            sel.xpath,
            "myfunc()",
        )