pyrtan / sourcev0.14.0 · main

pyrtan / tests / test_extract.py

2,234 bytes · last changed 2026-10-25 in Initial public release

1import pytest
2
3from pyrtan.extract import ExtractError, extract, validate
4from pyrtan.template import MISSING
5
6HTML = '<ul><li class="s"><a href="/a">A</a><span>1</span></li><li class="s"><a href="/b">B</a><span>2</span></li></ul>'
7SOURCE = {"status": 200, "body": HTML, "json": {"items": [{"t": "x"}], "price": "$12.50"}}
8
9
10def test_json_path():
11 assert extract({"into": "t", "json": "json.items[0].t"}, SOURCE) == "x"
12 assert extract({"into": "t", "json": "json.items[9].t"}, SOURCE) is MISSING
13
14
15def test_regex():
16 assert extract({"into": "p", "regex": r"\$([0-9.]+)", "from": "json.price"}, SOURCE) == "12.50"
17 assert extract({"into": "p", "regex": r"href=\"(/\w)\"", "all": True}, SOURCE) == ["/a", "/b"]
18 assert extract({"into": "p", "regex": "zzz"}, SOURCE) is MISSING
19 assert extract({"into": "p", "regex": "<li", "group": 0}, SOURCE) == "<li"
20
21
22def test_css_text_attr_all_fields():
23 assert extract({"into": "x", "css": "li a"}, SOURCE) == "A"
24 assert extract({"into": "x", "css": "li a", "attr": "href", "all": True}, SOURCE) == ["/a", "/b"]
25 rows = extract({"into": "x", "css": "li.s", "all": True, "fields": {"name": "a", "n": "span", "href": {"css": "a", "attr": "href"}}}, SOURCE)
26 assert rows == [{"name": "A", "n": "1", "href": "/a"}, {"name": "B", "n": "2", "href": "/b"}]
27 assert extract({"into": "x", "css": "h1"}, SOURCE) is MISSING
28 assert extract({"into": "x", "css": "h1", "all": True}, SOURCE) == []
29
30
31def test_css_caches_parsed_document():
32 cache = {}
33 extract({"into": "x", "css": "li a"}, SOURCE, cache)
34 extract({"into": "y", "css": "span"}, SOURCE, cache)
35 assert len(cache) == 1
36
37
38def test_validate():
39 validate({"into": "a", "json": "x"})
40 with pytest.raises(ExtractError):
41 validate({"into": "a"})
42 with pytest.raises(ExtractError):
43 validate({"into": "a", "json": "x", "css": "y"})
44 with pytest.raises(ExtractError):
45 validate({"into": "a", "regex": "("})
46 with pytest.raises(ExtractError):
47 validate({"into": "a", "css": "a ~ b"})
48 with pytest.raises(ExtractError):
49 validate({"into": "a", "css": "li", "fields": {"x": "a ~ b"}})
50 with pytest.raises(ExtractError):
51 validate({"json": "x"})