forked from getnikola/nikola
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_shortcodes.py
200 lines (177 loc) · 6.87 KB
/
test_shortcodes.py
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
"""Test shortcodes."""
import pytest
import nikola.utils
from nikola import shortcodes
@pytest.mark.parametrize(
"template, expected_result",
[
("test({{% noargs %}})", "test(noargs success!)"),
(
"test({{% noargs %}}\\hello world/{{% /noargs %}})",
"test(noargs \\hello world/ success!)",
),
],
)
def test_noargs(site, template, expected_result):
applied_shortcode = shortcodes.apply_shortcodes(template, site.shortcode_registry)[0]
assert applied_shortcode == expected_result
@pytest.mark.parametrize(
"template, expected_result",
[
("test({{% arg 1 %}})", "test(arg ('1',)/[]/)"),
("test({{% arg 1 2aa %}})", "test(arg ('1', '2aa')/[]/)"),
('test({{% arg "hello world" %}})', "test(arg ('hello world',)/[]/)"),
("test({{% arg back\\ slash arg2 %}})", "test(arg ('back slash', 'arg2')/[]/)"),
('test({{% arg "%}}" %}})', "test(arg ('%}}',)/[]/)"),
],
)
def test_positional_arguments(site, template, expected_result):
applied_shortcode = shortcodes.apply_shortcodes(template, site.shortcode_registry)[0]
assert applied_shortcode == expected_result
@pytest.mark.parametrize(
"template, expected_result",
[
("test({{% arg 1a=2b %}})", "test(arg ()/[('1a', '2b')]/)"),
(
'test({{% arg 1a="2b 3c" 4d=5f %}})',
"test(arg ()/[('1a', '2b 3c'), ('4d', '5f')]/)",
),
(
'test({{% arg 1a="2b 3c" 4d=5f back=slash\\ slash %}})',
"test(arg ()/[('1a', '2b 3c'), ('4d', '5f'), ('back', 'slash slash')]/)",
),
],
)
def test_arg_keyword(site, template, expected_result):
applied_shortcode = shortcodes.apply_shortcodes(template, site.shortcode_registry)[0]
assert applied_shortcode == expected_result
@pytest.mark.parametrize(
"template, expected_result",
[
("test({{% arg 123 %}}Hello!{{% /arg %}})", "test(arg ('123',)/[]/Hello!)"),
(
"test({{% arg 123 456 foo=bar %}}Hello world!{{% /arg %}})",
"test(arg ('123', '456')/[('foo', 'bar')]/Hello world!)",
),
(
'test({{% arg 123 456 foo=bar baz="quotes rock." %}}Hello test suite!{{% /arg %}})',
"test(arg ('123', '456')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!)",
),
(
'test({{% arg "123 foo" foobar foo=bar baz="quotes rock." %}}Hello test suite!!{{% /arg %}})',
"test(arg ('123 foo', 'foobar')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!!)",
),
],
)
def test_data(site, template, expected_result):
applied_shortcode = shortcodes.apply_shortcodes(template, site.shortcode_registry)[0]
assert applied_shortcode == expected_result
@pytest.mark.parametrize(
"template, expected_error_pattern",
[
(
"{{% start",
"^Shortcode 'start' starting at .* is not terminated correctly with '%}}'!",
),
(
"{{% wrong ending %%}",
"^Syntax error in shortcode 'wrong' at .*: expecting whitespace!",
),
(
"{{% start %}} {{% /end %}}",
"^Found shortcode ending '{{% /end %}}' which isn't closing a started shortcode",
),
('{{% start "asdf %}}', "^Unexpected end of unquoted string"),
("{{% start =b %}}", "^String starting at .* must be non-empty!"),
('{{% start "a\\', "^Unexpected end of data while escaping"),
("{{% start a\\", "^Unexpected end of data while escaping"),
('{{% start a"b" %}}', "^Unexpected quotation mark in unquoted string"),
(
'{{% start "a"b %}}',
"^Syntax error in shortcode 'start' at .*: expecting whitespace!",
),
("{{% %}}", "^Syntax error: '{{%' must be followed by shortcode name"),
("{{%", "^Syntax error: '{{%' must be followed by shortcode name"),
("{{% ", "^Syntax error: '{{%' must be followed by shortcode name"),
(
"{{% / %}}",
"^Found shortcode ending '{{% / %}}' which isn't closing a started shortcode",
),
("{{% / a %}}", "^Syntax error: '{{% /' must be followed by ' %}}'"),
(
"==> {{% <==",
"^Shortcode '<==' starting at .* is not terminated correctly with '%}}'!",
),
],
)
def test_errors(site, template, expected_error_pattern):
with pytest.raises(shortcodes.ParsingError, match=expected_error_pattern):
shortcodes.apply_shortcodes(
template, site.shortcode_registry, raise_exceptions=True
)
@pytest.mark.parametrize(
"input, expected",
[
("{{% foo %}}", (u"SC1", {u"SC1": u"{{% foo %}}"})),
(
"{{% foo %}} bar {{% /foo %}}",
(u"SC1", {u"SC1": u"{{% foo %}} bar {{% /foo %}}"}),
),
(
"AAA{{% foo %}} bar {{% /foo %}}BBB",
(u"AAASC1BBB", {u"SC1": u"{{% foo %}} bar {{% /foo %}}"}),
),
(
"AAA{{% foo %}} {{% bar %}} {{% /foo %}}BBB",
(u"AAASC1BBB", {u"SC1": u"{{% foo %}} {{% bar %}} {{% /foo %}}"}),
),
(
"AAA{{% foo %}} {{% /bar %}} {{% /foo %}}BBB",
(u"AAASC1BBB", {u"SC1": u"{{% foo %}} {{% /bar %}} {{% /foo %}}"}),
),
(
"AAA{{% foo %}} {{% bar %}} quux {{% /bar %}} {{% /foo %}}BBB",
(
u"AAASC1BBB",
{u"SC1": u"{{% foo %}} {{% bar %}} quux {{% /bar %}} {{% /foo %}}"},
),
),
(
"AAA{{% foo %}} BBB {{% bar %}} quux {{% /bar %}} CCC",
(
u"AAASC1 BBB SC2 CCC",
{u"SC1": u"{{% foo %}}", u"SC2": u"{{% bar %}} quux {{% /bar %}}"},
),
),
],
)
def test_extract_shortcodes(input, expected, monkeypatch):
i = iter("SC%d" % i for i in range(1, 100))
monkeypatch.setattr(shortcodes, "_new_sc_id", i.__next__)
extracted = shortcodes.extract_shortcodes(input)
assert extracted == expected
@pytest.fixture(scope="module")
def site():
s = FakeSiteWithShortcodeRegistry()
s.register_shortcode("noargs", noargs)
s.register_shortcode("arg", arg)
return s
class FakeSiteWithShortcodeRegistry:
def __init__(self):
self.shortcode_registry = {}
self.debug = True
# this code duplicated in nikola/nikola.py
def register_shortcode(self, name, f):
"""Register function f to handle shortcode "name"."""
if name in self.shortcode_registry:
nikola.utils.LOGGER.warn("Shortcode name conflict: %s", name)
return
self.shortcode_registry[name] = f
def noargs(site, data="", lang=""):
return "noargs {0} success!".format(data)
def arg(*args, **kwargs):
# don’t clutter the kwargs dict
kwargs.pop("site")
data = kwargs.pop("data")
kwargs.pop("lang")
return "arg {0}/{1}/{2}".format(args, sorted(kwargs.items()), data)