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

334 lines, 85 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 return
185 # HTML looks like:
186 #
187 # <table>
188 # <ul> # problem: we need to lookahead SPACE <li> (tr or thead)
189 # <li>tr
190 # <ul>
191 # <li>one</li>
192 # </ul>
193 # </li>
194 # </ul>
195 # </table>
196
197 h = MarkdownToTable('''\
198<table>
199
200- tr
201 - one
202 - two
203
204</table>
205''')
206 print(h)
207
208 def testSimple(self):
209 h = MarkdownToTable("""\
210<table>
211
212- thead
213 - *name*
214 - *age*
215- tr
216 - alice
217 - 30
218- tr
219 - bob
220 - 40
221
222<table>
223""")
224 self.assertMultiLineEqual(
225 """\
226<table>
227<thead>
228<tr>
229 <th><em>name</em></th>
230 <th><em>age</em></th>
231</tr>
232</thead>
233<tr>
234 <td>alice</td>
235 <td>30</td>
236</tr>
237<tr>
238 <td>bob</td>
239 <td>40</td>
240</tr>
241<table>
242""", h)
243
244 def testMultipleTables(self):
245 # They can be right next to each other
246 html_one = MarkdownToTable(TEST1)
247
248 self.assert_(not TEST1.endswith('\n'))
249 # CommonMark added a newline
250 self.assert_(html_one.endswith('\n'))
251 html_one = html_one[:-1]
252
253 html_two = MarkdownToTable(TEST1 + TEST1)
254
255 # The output is just concatenated
256 self.assertMultiLineEqual(html_one + html_one + '\n', html_two)
257
258 def testMultipleTablesWithSpace(self):
259 h = MarkdownToTable(TEST1 + '\n\n hi \n' + TEST1)
260
261 def testTdAttrs(self):
262 h = MarkdownToTable(TD_ATTRS)
263 self.assertMultiLineEqual(TD_ATTRS_HTML, h)
264
265 def testColspan(self):
266 h = MarkdownToTable(COLSPAN)
267 self.assertMultiLineEqual(COLSPAN_HTML, h)
268
269 def testTrAttrs(self):
270 h = MarkdownToTable(TR_ATTRS)
271 self.assertMultiLineEqual(TR_ATTRS_HTML, h)
272
273 def testSyntaxErrors(self):
274 # Once we get <table><ul>, then we TAKE OVER, and start being STRICT
275
276 try:
277 h = MarkdownToTable("""
278<table>
279
280- should be thead
281 - one
282 - two
283""")
284 except html.ParseError as e:
285 print(e)
286 else:
287 self.fail('Expected parse error')
288
289 try:
290 h = MarkdownToTable("""
291<table>
292
293- thead
294 - <span /> Not allowed
295 - two
296- tr
297 - 1
298 - 2
299""")
300 except html.ParseError as e:
301 print(e)
302 else:
303 self.fail('Expected parse error')
304
305 def testColumnCheck(self):
306 # Disabled because of colspan
307 return
308
309 try:
310 h = MarkdownToTable("""
311<table>
312
313- thead
314 - one
315 - two
316- tr
317 - 1
318 - 2
319- tr
320 - wrong number of cells
321- tr
322 - 3
323 - 4
324
325</table>
326""")
327 except html.ParseError as e:
328 print(e)
329 else:
330 self.fail('Expected parse error')
331
332
333if __name__ == '__main__':
334 unittest.main()