OILS / doctools / ul_table_test.py View on Github | oils.pub

412 lines, 97 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 - <cell-attrs class="foo" /> name
17 - <cell-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 - <cell-attrs class=unquoted /> name
32 - <cell-attrs class=quoted /> age
33 - role
34- tr
35 - <cell-attrs class="cool" /> alice
36 - 30
37 - parent
38- tr
39 - bob
40 - 42
41 - <cell-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
68TRAILING_ATTRS = """\
69<table>
70
71- thead
72 - OSH
73 - YSH
74- tr
75 - ```
76 echo osh
77 ```
78 <cell-attrs class=osh-code />
79 - ```
80 echo ysh
81 ```
82 <cell-attrs class=ysh-code />
83
84</table>
85"""
86
87TRAILING_ATTRS_HTML = """\
88<table>
89<thead>
90<tr>
91 <th>OSH</th>
92 <th>YSH</th>
93</tr>
94</thead>
95<tr>
96 <td class="osh-code">
97<pre><code>echo osh
98</code></pre>
99
100</td>
101 <td class="ysh-code">
102<pre><code>echo ysh
103</code></pre>
104
105</td>
106</tr>
107</table>
108"""
109
110TR_ATTRS = """\
111<table>
112
113- thead
114 - <cell-attrs class=unquoted /> name
115 - <cell-attrs class=quoted /> age
116 - role
117- tr <row-attrs class=totals />
118 - alice
119 - 30
120 - parent
121- tr
122 - bob
123 - 42
124 - <cell-attrs class=child /> child
125
126</table>
127"""
128
129TR_ATTRS_HTML = """\
130<table>
131<thead>
132<tr>
133 <th> name</th>
134 <th> age</th>
135 <th>role</th>
136</tr>
137</thead>
138<tr class="totals">
139 <td class="unquoted">alice</td>
140 <td class="quoted">30</td>
141 <td>parent</td>
142</tr>
143<tr>
144 <td class="unquoted">bob</td>
145 <td class="quoted">42</td>
146 <td class="child"> child</td>
147</tr>
148</table>
149"""
150
151# Note CSS Grid can express colspan
152# https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column
153
154COLSPAN = """\
155<table>
156
157- thead
158 - <cell-attrs class=foo /> name
159 - age
160- tr
161 - alice
162 - 30
163- tr
164 - <cell-attrs colspan=2 /> ... more ...
165- tr
166 - bob
167 - 42
168
169</table>
170"""
171
172COLSPAN_HTML = """\
173<table>
174<thead>
175<tr>
176 <th> name</th>
177 <th>age</th>
178</tr>
179</thead>
180<tr>
181 <td class="foo">alice</td>
182 <td>30</td>
183</tr>
184<tr>
185 <td class="foo" colspan="2"> ... more ...</td>
186</tr>
187<tr>
188 <td class="foo">bob</td>
189 <td>42</td>
190</tr>
191</table>
192"""
193
194# UNUSED - not worth it now
195MIXED_TR = """\
196<table>
197
198- thead
199 - name
200 - age
201- tr
202 - 30
203 - parent
204
205<tr>
206 <td colspan=2> - </td>
207</tr>
208
209- tr
210 - bob
211 - 42
212 - <cell-attrs class=child /> child
213
214</table>
215"""
216
217
218def MarkdownToTable(md):
219 # markdown -> HTML
220
221 h = cmark.md2html(md)
222 # Markdown adds a newline
223 if h.endswith('\n'):
224 print('ENDS WITH NEWLINE %r' % h[-10:])
225
226 if 1:
227 print('---')
228 print('ORIGINAL')
229 print(h)
230 print('')
231
232 h2 = ul_table.ReplaceTables(h)
233
234 if 1:
235 print('---')
236 print('REPLACED')
237 print(h2)
238 print('')
239
240 return h2
241
242
243class UlTableTest(unittest.TestCase):
244
245 def testOne(self):
246 h = MarkdownToTable('hi\n' + TEST1 + '\n\n bye \n')
247
248 def testNoHeader(self):
249 # HTML looks like:
250 #
251 # <table>
252 # <ul> # problem: we need to lookahead SPACE <li> (tr or thead)
253 # <li>tr
254 # <ul>
255 # <li>one</li>
256 # </ul>
257 # </li>
258 # </ul>
259 # </table>
260
261 h = MarkdownToTable('''\
262<table>
263
264- tr
265 - one
266 - two
267
268</table>
269''')
270 print(h)
271
272 def testSimple(self):
273 h = MarkdownToTable("""\
274<table>
275
276- thead
277 - *name*
278 - *age*
279- tr
280 - alice
281 - 30
282- tr
283 - bob
284 - 40
285
286<table>
287""")
288 self.assertMultiLineEqual(
289 """\
290<table>
291<thead>
292<tr>
293 <th><em>name</em></th>
294 <th><em>age</em></th>
295</tr>
296</thead>
297<tr>
298 <td>alice</td>
299 <td>30</td>
300</tr>
301<tr>
302 <td>bob</td>
303 <td>40</td>
304</tr>
305<table>
306""", h)
307
308 def testMultipleTables(self):
309 # They can be right next to each other
310 html_one = MarkdownToTable(TEST1)
311
312 self.assert_(not TEST1.endswith('\n'))
313 # CommonMark added a newline
314 self.assert_(html_one.endswith('\n'))
315 html_one = html_one[:-1]
316
317 html_two = MarkdownToTable(TEST1 + TEST1)
318
319 # The output is just concatenated
320 self.assertMultiLineEqual(html_one + html_one + '\n', html_two)
321
322 def testMultipleTablesWithSpace(self):
323 h = MarkdownToTable(TEST1 + '\n\n hi \n' + TEST1)
324
325 def testTdAttrs(self):
326 h = MarkdownToTable(TD_ATTRS)
327 self.assertMultiLineEqual(TD_ATTRS_HTML, h)
328
329 def testTdAttrsTrailing(self):
330 self.maxDiff = 2000
331 h = MarkdownToTable(TRAILING_ATTRS)
332 if 1:
333 print('expect', repr(TRAILING_ATTRS_HTML))
334 print('actual', repr(h))
335 self.assertMultiLineEqual(TRAILING_ATTRS_HTML, h)
336
337 def testColspan(self):
338 h = MarkdownToTable(COLSPAN)
339 self.assertMultiLineEqual(COLSPAN_HTML, h)
340
341 def testTrAttrs(self):
342 h = MarkdownToTable(TR_ATTRS)
343 self.assertMultiLineEqual(TR_ATTRS_HTML, h)
344
345 def testMixedTr(self):
346 # Not worth it
347 return
348 h = MarkdownToTable(MIXED_TR)
349 #self.assertMultiLineEqual(MIXED_TR, h)
350
351 def testSyntaxErrors(self):
352 # Once we get <table><ul>, then we TAKE OVER, and start being STRICT
353
354 try:
355 h = MarkdownToTable("""
356<table>
357
358- should be thead
359 - one
360 - two
361""")
362 except html.ParseError as e:
363 print(e)
364 else:
365 self.fail('Expected parse error')
366
367 try:
368 h = MarkdownToTable("""
369<table>
370
371- thead
372 - one
373 - two
374- tr <bad-attrs />
375 - 1
376 - 2
377""")
378 except html.ParseError as e:
379 print(e)
380 else:
381 self.fail('Expected parse error')
382
383 def testColumnCheck(self):
384 # Disabled because of colspan
385 return
386
387 try:
388 h = MarkdownToTable("""
389<table>
390
391- thead
392 - one
393 - two
394- tr
395 - 1
396 - 2
397- tr
398 - wrong number of cells
399- tr
400 - 3
401 - 4
402
403</table>
404""")
405 except html.ParseError as e:
406 print(e)
407 else:
408 self.fail('Expected parse error')
409
410
411if __name__ == '__main__':
412 unittest.main()