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

378 lines, 95 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
68TR_ATTRS = """\
69<table>
70
71- thead
72 - <cell-attrs class=unquoted /> name
73 - <cell-attrs class=quoted /> age
74 - role
75- tr <row-attrs class=totals />
76 - alice
77 - 30
78 - parent
79- tr
80 - bob
81 - 42
82 - <cell-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 - <cell-attrs class=foo /> name
117 - age
118- tr
119 - alice
120 - 30
121- tr
122 - <cell-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# UNUSED - not worth it now
153MIXED_TR = """\
154<table>
155
156- thead
157 - name
158 - age
159- tr
160 - 30
161 - parent
162
163<tr>
164 <td colspan=2> - </td>
165</tr>
166
167- tr
168 - bob
169 - 42
170 - <cell-attrs class=child /> child
171
172</table>
173"""
174
175
176def MarkdownToTable(md):
177 # markdown -> HTML
178
179 h = cmark.md2html(md)
180 # Markdown adds a newline
181 if h.endswith('\n'):
182 print('ENDS WITH NEWLINE %r' % h[-10:])
183
184 if 1:
185 print('---')
186 print('ORIGINAL')
187 print(h)
188 print('')
189
190 h2 = ul_table.ReplaceTables(h)
191
192 if 1:
193 print('---')
194 print('REPLACED')
195 print(h2)
196 print('')
197
198 return h2
199
200
201class UlTableTest(unittest.TestCase):
202
203 def testOne(self):
204 h = MarkdownToTable('hi\n' + TEST1 + '\n\n bye \n')
205
206 def testNoHeader(self):
207 # HTML looks like:
208 #
209 # <table>
210 # <ul> # problem: we need to lookahead SPACE <li> (tr or thead)
211 # <li>tr
212 # <ul>
213 # <li>one</li>
214 # </ul>
215 # </li>
216 # </ul>
217 # </table>
218
219 h = MarkdownToTable('''\
220<table>
221
222- tr
223 - one
224 - two
225
226</table>
227''')
228 print(h)
229
230 def testSimple(self):
231 h = MarkdownToTable("""\
232<table>
233
234- thead
235 - *name*
236 - *age*
237- tr
238 - alice
239 - 30
240- tr
241 - bob
242 - 40
243
244<table>
245""")
246 self.assertMultiLineEqual(
247 """\
248<table>
249<thead>
250<tr>
251 <th><em>name</em></th>
252 <th><em>age</em></th>
253</tr>
254</thead>
255<tr>
256 <td>alice</td>
257 <td>30</td>
258</tr>
259<tr>
260 <td>bob</td>
261 <td>40</td>
262</tr>
263<table>
264""", h)
265
266 def testMultipleTables(self):
267 # They can be right next to each other
268 html_one = MarkdownToTable(TEST1)
269
270 self.assert_(not TEST1.endswith('\n'))
271 # CommonMark added a newline
272 self.assert_(html_one.endswith('\n'))
273 html_one = html_one[:-1]
274
275 html_two = MarkdownToTable(TEST1 + TEST1)
276
277 # The output is just concatenated
278 self.assertMultiLineEqual(html_one + html_one + '\n', html_two)
279
280 def testMultipleTablesWithSpace(self):
281 h = MarkdownToTable(TEST1 + '\n\n hi \n' + TEST1)
282
283 def testTdAttrs(self):
284 h = MarkdownToTable(TD_ATTRS)
285 self.assertMultiLineEqual(TD_ATTRS_HTML, h)
286
287 def testColspan(self):
288 h = MarkdownToTable(COLSPAN)
289 self.assertMultiLineEqual(COLSPAN_HTML, h)
290
291 def testTrAttrs(self):
292 h = MarkdownToTable(TR_ATTRS)
293 self.assertMultiLineEqual(TR_ATTRS_HTML, h)
294
295 def testMixedTr(self):
296 # Not worth it
297 return
298 h = MarkdownToTable(MIXED_TR)
299 #self.assertMultiLineEqual(MIXED_TR, h)
300
301 def testSyntaxErrors(self):
302 # Once we get <table><ul>, then we TAKE OVER, and start being STRICT
303
304 try:
305 h = MarkdownToTable("""
306<table>
307
308- should be thead
309 - one
310 - two
311""")
312 except html.ParseError as e:
313 print(e)
314 else:
315 self.fail('Expected parse error')
316
317 try:
318 h = MarkdownToTable("""
319<table>
320
321- thead
322 - <span /> Not allowed
323 - two
324- tr
325 - 1
326 - 2
327""")
328 except html.ParseError as e:
329 print(e)
330 else:
331 self.fail('Expected parse error')
332
333 try:
334 h = MarkdownToTable("""
335<table>
336
337- thead
338 - one
339 - two
340- tr <bad-attrs />
341 - 1
342 - 2
343""")
344 except html.ParseError as e:
345 print(e)
346 else:
347 self.fail('Expected parse error')
348
349 def testColumnCheck(self):
350 # Disabled because of colspan
351 return
352
353 try:
354 h = MarkdownToTable("""
355<table>
356
357- thead
358 - one
359 - two
360- tr
361 - 1
362 - 2
363- tr
364 - wrong number of cells
365- tr
366 - 3
367 - 4
368
369</table>
370""")
371 except html.ParseError as e:
372 print(e)
373 else:
374 self.fail('Expected parse error')
375
376
377if __name__ == '__main__':
378 unittest.main()