OILS / doctools / ul_table_test.py View on Github | oilshell.org

333 lines, 84 significant
1#!/usr/bin/env python2
2from __future__ import print_function
3
4import cmark # Oils dev dependency
5
6import unittest
7
8from lazylex import html
9from doctools import ul_table
10
11# <ulcol> is a special annotation
12TEST1 = """\
13<table id="foo">
14
15- thead
16 - <td-attrs class="foo" /> name
17 - <td-attrs class="bar" /> [age](https://example.com/)
18- tr
19 - alice *italic*
20 - 30
21- tr
22 - bob
23 - 42
24
25</table>""" # no extra
26
27TD_ATTRS = """\
28<table>
29
30- thead
31 - <td-attrs class=unquoted /> name
32 - <td-attrs class=quoted /> age
33 - role
34- tr
35 - <td-attrs class="cool" /> alice
36 - 30
37 - parent
38- tr
39 - bob
40 - 42
41 - <td-attrs class=child /> child
42
43</table>
44"""
45
46TD_ATTRS_HTML = """\
47<table>
48<thead>
49<tr>
50 <th> name</th>
51 <th> age</th>
52 <th>role</th>
53</tr>
54</thead>
55<tr>
56 <td class="unquoted cool"> alice</td>
57 <td class="quoted">30</td>
58 <td>parent</td>
59</tr>
60<tr>
61 <td class="unquoted">bob</td>
62 <td class="quoted">42</td>
63 <td class="child"> child</td>
64</tr>
65</table>
66"""
67
68TR_ATTRS = """\
69<table>
70
71- thead
72 - <td-attrs class=unquoted /> name
73 - <td-attrs class=quoted /> age
74 - role
75- tr <tr-attrs class=totals />
76 - alice
77 - 30
78 - parent
79- tr
80 - bob
81 - 42
82 - <td-attrs class=child /> child
83
84</table>
85"""
86
87TR_ATTRS_HTML = """\
88<table>
89<thead>
90<tr>
91 <th> name</th>
92 <th> age</th>
93 <th>role</th>
94</tr>
95</thead>
96<tr class="totals">
97 <td class="unquoted">alice</td>
98 <td class="quoted">30</td>
99 <td>parent</td>
100</tr>
101<tr>
102 <td class="unquoted">bob</td>
103 <td class="quoted">42</td>
104 <td class="child"> child</td>
105</tr>
106</table>
107"""
108
109# Note CSS Grid can express colspan
110# https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column
111
112COLSPAN = """\
113<table>
114
115- thead
116 - <td-attrs class=foo /> name
117 - age
118- tr
119 - alice
120 - 30
121- tr
122 - <td-attrs colspan=2 /> ... more ...
123- tr
124 - bob
125 - 42
126
127</table>
128"""
129
130COLSPAN_HTML = """\
131<table>
132<thead>
133<tr>
134 <th> name</th>
135 <th>age</th>
136</tr>
137</thead>
138<tr>
139 <td class="foo">alice</td>
140 <td>30</td>
141</tr>
142<tr>
143 <td class="foo" colspan="2"> ... more ...</td>
144</tr>
145<tr>
146 <td class="foo">bob</td>
147 <td>42</td>
148</tr>
149</table>
150"""
151
152
153def MarkdownToTable(md):
154 # markdown -> HTML
155
156 h = cmark.md2html(md)
157 # Markdown adds a newline
158 if h.endswith('\n'):
159 print('ENDS WITH NEWLINE %r' % h[-10:])
160
161 if 1:
162 print('---')
163 print('ORIGINAL')
164 print(h)
165 print('')
166
167 h2 = ul_table.ReplaceTables(h)
168
169 if 1:
170 print('---')
171 print('REPLACED')
172 print(h2)
173 print('')
174
175 return h2
176
177
178class UlTableTest(unittest.TestCase):
179
180 def testOne(self):
181 h = MarkdownToTable('hi\n' + TEST1 + '\n\n bye \n')
182
183 def testNoHeader(self):
184 # HTML looks like:
185 #
186 # <table>
187 # <ul> # problem: we need to lookahead SPACE <li> (tr or thead)
188 # <li>tr
189 # <ul>
190 # <li>one</li>
191 # </ul>
192 # </li>
193 # </ul>
194 # </table>
195
196 h = MarkdownToTable('''\
197<table>
198
199- tr
200 - one
201 - two
202
203</table>
204''')
205 print(h)
206
207 def testSimple(self):
208 h = MarkdownToTable("""\
209<table>
210
211- thead
212 - *name*
213 - *age*
214- tr
215 - alice
216 - 30
217- tr
218 - bob
219 - 40
220
221<table>
222""")
223 self.assertMultiLineEqual(
224 """\
225<table>
226<thead>
227<tr>
228 <th><em>name</em></th>
229 <th><em>age</em></th>
230</tr>
231</thead>
232<tr>
233 <td>alice</td>
234 <td>30</td>
235</tr>
236<tr>
237 <td>bob</td>
238 <td>40</td>
239</tr>
240<table>
241""", h)
242
243 def testMultipleTables(self):
244 # They can be right next to each other
245 html_one = MarkdownToTable(TEST1)
246
247 self.assert_(not TEST1.endswith('\n'))
248 # CommonMark added a newline
249 self.assert_(html_one.endswith('\n'))
250 html_one = html_one[:-1]
251
252 html_two = MarkdownToTable(TEST1 + TEST1)
253
254 # The output is just concatenated
255 self.assertMultiLineEqual(html_one + html_one + '\n', html_two)
256
257 def testMultipleTablesWithSpace(self):
258 h = MarkdownToTable(TEST1 + '\n\n hi \n' + TEST1)
259
260 def testTdAttrs(self):
261 h = MarkdownToTable(TD_ATTRS)
262 self.assertMultiLineEqual(TD_ATTRS_HTML, h)
263
264 def testColspan(self):
265 h = MarkdownToTable(COLSPAN)
266 self.assertMultiLineEqual(COLSPAN_HTML, h)
267
268 def testTrAttrs(self):
269 h = MarkdownToTable(TR_ATTRS)
270 self.assertMultiLineEqual(TR_ATTRS_HTML, h)
271
272 def testSyntaxErrors(self):
273 # Once we get <table><ul>, then we TAKE OVER, and start being STRICT
274
275 try:
276 h = MarkdownToTable("""
277<table>
278
279- should be thead
280 - one
281 - two
282""")
283 except html.ParseError as e:
284 print(e)
285 else:
286 self.fail('Expected parse error')
287
288 try:
289 h = MarkdownToTable("""
290<table>
291
292- thead
293 - <span /> Not allowed
294 - two
295- tr
296 - 1
297 - 2
298""")
299 except html.ParseError as e:
300 print(e)
301 else:
302 self.fail('Expected parse error')
303
304 def testColumnCheck(self):
305 # Disabled because of colspan
306 return
307
308 try:
309 h = MarkdownToTable("""
310<table>
311
312- thead
313 - one
314 - two
315- tr
316 - 1
317 - 2
318- tr
319 - wrong number of cells
320- tr
321 - 3
322 - 4
323
324</table>
325""")
326 except html.ParseError as e:
327 print(e)
328 else:
329 self.fail('Expected parse error')
330
331
332if __name__ == '__main__':
333 unittest.main()