-
Notifications
You must be signed in to change notification settings - Fork 36
/
Copy pathtest_html_render.py
366 lines (270 loc) · 10.1 KB
/
test_html_render.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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
"""
test code for html_render.py
This is just a start -- you will need more tests!
"""
import io
import pytest
# import * is often bad form, but makes it easier to test everything in a module.
from html_render import *
# utility function for testing render methods
# needs to be used in multiple tests, so we write it once here.
def render_result(element, ind=""):
"""
calls the element's render method, and returns what got rendered as a
string
"""
# the StringIO object is a "file-like" object -- something that
# provides the methods of a file, but keeps everything in memory
# so it can be used to test code that writes to a file, without
# having to actually write to disk.
outfile = io.StringIO()
# this so the tests will work before we tackle indentation
if ind:
element.render(outfile, ind)
else:
element.render(outfile)
return outfile.getvalue()
########
# Step 1
########
def test_init():
"""
This only tests that it can be initialized with and without
some content -- but it's a start
"""
e = Element()
e = Element("this is some text")
def test_append():
"""
This tests that you can append text
It doesn't test if it works --
that will be covered by the render test later
"""
e = Element("this is some text")
e.append("some more text")
def test_render_element():
"""
Tests whether the Element can render two pieces of text
So it is also testing that the append method works correctly.
It is not testing whether indentation or line feeds are correct.
"""
e = Element("this is some text")
e.append("and this is some more text")
# This uses the render_results utility above
file_contents = render_result(e).strip()
# making sure the content got in there.
assert("this is some text") in file_contents
assert("and this is some more text") in file_contents
# make sure it's in the right order
assert file_contents.index("this is") < file_contents.index("and this")
# making sure the opening and closing tags are right.
assert file_contents.startswith("<html>")
assert file_contents.endswith("</html>")
# Uncomment this one after you get the one above to pass
# Does it pass right away?
def test_render_element2():
"""
Tests whether the Element can render two pieces of text
So it is also testing that the append method works correctly.
It is not testing whether indentation or line feeds are correct.
"""
e = Element()
e.append("this is some text")
e.append("and this is some more text")
# This uses the render_results utility above
file_contents = render_result(e).strip()
# making sure the content got in there.
assert("this is some text") in file_contents
assert("and this is some more text") in file_contents
# make sure it's in the right order
assert file_contents.index("this is") < file_contents.index("and this")
# making sure the opening and closing tags are right.
assert file_contents.startswith("<html>")
assert file_contents.endswith("</html>")
# ########
# # Step 2
# ########
# tests for the new tags
def test_html():
e = Html("this is some text")
e.append("and this is some more text")
file_contents = render_result(e).strip()
assert("this is some text") in file_contents
assert("and this is some more text") in file_contents
print(file_contents)
assert file_contents.endswith("</html>")
def test_body():
e = Body("this is some text")
e.append("and this is some more text")
file_contents = render_result(e).strip()
assert("this is some text") in file_contents
assert("and this is some more text") in file_contents
assert file_contents.startswith("<body>")
assert file_contents.endswith("</body>")
def test_p():
e = P("this is some text")
e.append("and this is some more text")
file_contents = render_result(e).strip()
assert("this is some text") in file_contents
assert("and this is some more text") in file_contents
assert file_contents.startswith("<p>")
assert file_contents.endswith("</p>")
def test_sub_element():
"""
tests that you can add another element and still render properly
"""
page = Html()
page.append("some plain text.")
page.append(P("A simple paragraph of text"))
page.append("Some more plain text.")
file_contents = render_result(page)
print(file_contents) # so we can see it if the test fails
# note: The previous tests should make sure that the tags are getting
# properly rendered, so we don't need to test that here.
assert "some plain text" in file_contents
assert "A simple paragraph of text" in file_contents
assert "Some more plain text." in file_contents
assert "some plain text" in file_contents
# but make sure the embedded element's tags get rendered!
assert "<p>" in file_contents
assert "</p>" in file_contents
########
# Step 3
########
def test_head():
e = Head("this is some new text")
e.append("and this is some more new text")
file_contents = render_result(e).strip()
assert("this is some new text") in file_contents
assert("and this is some more new text") in file_contents
assert file_contents.startswith("<head>")
assert file_contents.endswith("</head>")
def test_title():
e = Title("This is a Title")
file_contents = render_result(e).strip()
assert("This is a Title") in file_contents
print(file_contents)
assert file_contents.startswith("<title>")
assert file_contents.endswith("</title>")
assert "\n" not in file_contents
def test_one_line_tag_append():
"""
You should not be able to append content to a OneLineTag
"""
e = OneLineTag("the initial content")
with pytest.raises(NotImplementedError):
e.append("some more content")
def test_attributes():
e = P("A paragraph of text", style="text-align: center", id="intro")
file_contents = render_result(e).strip()
print(file_contents) # so we can see it if the test fails
# note: The previous tests should make sure that the tags are getting
# properly rendered, so we don't need to test that here.
# so using only a "P" tag is fine
assert "A paragraph of text" in file_contents
# but make sure the embedded element's tags get rendered!
# first test the end tag is there -- same as always:
assert file_contents.endswith("</p>")
# but now the opening tag is far more complex
# but it starts the same:
assert file_contents.startswith("<p")
tag_attributes = render_result(e).strip()
assert 'style="text-align: center"' in tag_attributes
assert 'id="intro"' in tag_attributes
def test_hr():
"""a simple horizontal rule with no attributes"""
hr = Hr()
file_contents = render_result(hr)
print(file_contents)
assert file_contents == '<hr />\n'
def test_hr_attr():
"""a horizontal rule with an attribute"""
hr = Hr(width=400)
file_contents = render_result(hr)
print(file_contents)
assert file_contents == '<hr width="400" />\n'
def test_br():
br = Br()
file_contents = render_result(br)
print(file_contents)
assert file_contents == "<br />\n"
def test_content_in_br():
with pytest.raises(TypeError):
br = Br("some content")
def test_append_content_in_br():
with pytest.raises(TypeError):
br = Br()
br.append("some content")
def test_anchor():
a = A("http://google.com", "link to google")
file_contents = render_result(a)
print(file_contents)
assert file_contents.startswith('<a ')
def test_header():
"""a header"""
"""a horizontal rule with an attribute"""
h2 = H(2, "This is a header!")
file_contents = render_result(h2)
print(file_contents)
assert file_contents == '<h2>This is a header!</h2>'
# #####################
# # indentation testing
# # Uncomment for Step 9 -- adding indentation
# #####################
# def test_indent():
# """
# Tests that the indentation gets passed through to the renderer
# """
# html = Html("some content")
# file_contents = render_result(html, ind=" ").rstrip() #remove the end newline
# print(file_contents)
# lines = file_contents.split("\n")
# assert lines[0].startswith(" <")
# print(repr(lines[-1]))
# assert lines[-1].startswith(" <")
# def test_indent_contents():
# """
# The contents in a element should be indented more than the tag
# by the amount in the indent class attribute
# """
# html = Element("some content")
# file_contents = render_result(html, ind="")
# print(file_contents)
# lines = file_contents.split("\n")
# assert lines[1].startswith(Element.indent)
# def test_multiple_indent():
# """
# make sure multiple levels get indented fully
# """
# body = Body()
# body.append(P("some text"))
# html = Html(body)
# file_contents = render_result(html)
# print(file_contents)
# lines = file_contents.split("\n")
# for i in range(3): # this needed to be adapted to the <DOCTYPE> tag
# assert lines[i + 1].startswith(i * Element.indent + "<")
# assert lines[4].startswith(3 * Element.indent + "some")
# def test_element_indent1():
# """
# Tests whether the Element indents at least simple content
# we are expecting to to look like this:
# <html>
# this is some text
# <\html>
# More complex indentation should be tested later.
# """
# e = Element("this is some text")
# # This uses the render_results utility above
# file_contents = render_result(e).strip()
# # making sure the content got in there.
# assert("this is some text") in file_contents
# # break into lines to check indentation
# lines = file_contents.split('\n')
# # making sure the opening and closing tags are right.
# assert lines[0] == "<html>"
# # this line should be indented by the amount specified
# # by the class attribute: "indent"
# assert lines[1].startswith(Element.indent + "thi")
# assert lines[2] == "</html>"
# assert file_contents.endswith("</html>")