~divmod-dev/divmod.org/trunk

« back to all changes in this revision

Viewing changes to Nevow/nevow/test/test_loaders.py

  • Committer: Jean-Paul Calderone
  • Date: 2014-06-29 20:33:04 UTC
  • mfrom: (2749.1.1 remove-epsilon-1325289)
  • Revision ID: exarkun@twistedmatrix.com-20140629203304-gdkmbwl1suei4m97
mergeĀ lp:~exarkun/divmod.org/remove-epsilon-1325289

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (c) 2004-2009 Divmod.
2
 
# See LICENSE for details.
3
 
 
4
 
import os
5
 
 
6
 
from twisted.trial import unittest, util
7
 
 
8
 
from nevow import context
9
 
from nevow import flat
10
 
from nevow.flat.flatstan import _PrecompiledSlot
11
 
from nevow import loaders
12
 
from nevow import tags as t
13
 
 
14
 
class TestDocFactories(unittest.TestCase):
15
 
 
16
 
    def _preprocessorTest(self, docFactory):
17
 
        def preprocessor(uncompiled):
18
 
            self.assertEquals(len(uncompiled), 1)
19
 
            uncompiled = uncompiled[0]
20
 
            self.assertEquals(uncompiled.tagName, 'div')
21
 
            self.assertEquals(len(uncompiled.children), 2)
22
 
            self.assertEquals(uncompiled.children[0].tagName, 'span')
23
 
            self.assertEquals(uncompiled.children[0].children, ['Hello'])
24
 
            self.assertEquals(uncompiled.children[1].tagName, 'span')
25
 
            self.assertEquals(uncompiled.children[1].children, ['world'])
26
 
            return t.div['goodbye.']
27
 
        doc = docFactory.load(preprocessors=[preprocessor])
28
 
        self.assertEquals(doc, ['<div>goodbye.</div>'])
29
 
 
30
 
 
31
 
    def test_stanPreprocessors(self):
32
 
        """
33
 
        Test that the stan loader properly passes uncompiled documents to
34
 
        preprocessors it is given.
35
 
        """
36
 
        factory = loaders.stan(
37
 
            t.div[t.span['Hello'], t.span['world']])
38
 
        return self._preprocessorTest(factory)
39
 
 
40
 
 
41
 
    def test_stan(self):
42
 
        doc = t.ul(id='nav')[t.li['one'], t.li['two'], t.li['three']]
43
 
        df = loaders.stan(doc)
44
 
        self.assertEquals(df.load()[0], '<ul id="nav"><li>one</li><li>two</li><li>three</li></ul>')
45
 
 
46
 
 
47
 
    def test_stanPrecompiled(self):
48
 
        """
49
 
        Test that a stan loader works with precompiled documents.
50
 
 
51
 
        (This behavior will probably be deprecated soon, but we need to test
52
 
        that it works right until we remove it.)
53
 
        """
54
 
        doc = flat.precompile(t.ul(id='nav')[t.li['one'], t.li['two'], t.slot('three')])
55
 
        df = loaders.stan(doc)
56
 
        loaded = df.load()
57
 
        self.assertEqual(loaded[0], '<ul id="nav"><li>one</li><li>two</li>')
58
 
        self.failUnless(isinstance(loaded[1], _PrecompiledSlot))
59
 
        self.assertEqual(loaded[1].name, 'three')
60
 
        self.assertEqual(loaded[2], '</ul>')
61
 
 
62
 
 
63
 
    def test_htmlstr(self):
64
 
        doc = '<ul id="nav"><li>a</li><li>b</li><li>c</li></ul>'
65
 
        df = loaders.htmlstr(doc)
66
 
        self.assertEquals(df.load()[0], doc)
67
 
    test_htmlstr.suppress = [
68
 
        util.suppress(message=
69
 
                      r"\[v0.8\] htmlstr is deprecated because it's buggy. "
70
 
                      "Please start using xmlfile and/or xmlstr.")]
71
 
 
72
 
 
73
 
    def test_htmlfile(self):
74
 
        doc = '<ul id="nav"><li>a</li><li>b</li><li>c</li></ul>'
75
 
        temp = self.mktemp()
76
 
        f = file(temp, 'w')
77
 
        f.write(doc)
78
 
        f.close()
79
 
        df = loaders.htmlfile(temp)
80
 
        self.assertEquals(df.load()[0], doc)
81
 
    test_htmlfile.suppress = [
82
 
        util.suppress(message=
83
 
                      r"\[v0.8\] htmlfile is deprecated because it's buggy. "
84
 
                      "Please start using xmlfile and/or xmlstr.")]
85
 
 
86
 
 
87
 
    def test_htmlfile_slots(self):
88
 
        doc = '<nevow:slot name="foo">Hi there</nevow:slot>'
89
 
        temp = self.mktemp()
90
 
        f = file(temp, 'w')
91
 
        f.write(doc)
92
 
        f.close()
93
 
        df = loaders.htmlfile(temp)
94
 
        self.assertEquals(df.load()[0].children, ['Hi there'])
95
 
    test_htmlfile_slots.suppress = [
96
 
        util.suppress(message=
97
 
                      r"\[v0.8\] htmlfile is deprecated because it's buggy. "
98
 
                      "Please start using xmlfile and/or xmlstr.")]
99
 
 
100
 
 
101
 
    def test_xmlstr(self):
102
 
        doc = '<ul id="nav"><li>a</li><li>b</li><li>c</li></ul>'
103
 
        df = loaders.xmlstr(doc)
104
 
        self.assertEquals(df.load()[0], doc)
105
 
 
106
 
 
107
 
    def test_xmlstrPreprocessors(self):
108
 
        """
109
 
        Test that the xmlstr loader properly passes uncompiled documents to
110
 
        preprocessors it is given.
111
 
        """
112
 
        factory = loaders.xmlstr(
113
 
            '<div><span>Hello</span><span>world</span></div>')
114
 
        return self._preprocessorTest(factory)
115
 
 
116
 
 
117
 
    def test_xmlfile(self):
118
 
        doc = '<ul id="nav"><li>a</li><li>b</li><li>c</li></ul>'
119
 
        temp = self.mktemp()
120
 
        f = file(temp, 'w')
121
 
        f.write(doc)
122
 
        f.close()
123
 
        df = loaders.xmlfile(temp)
124
 
        self.assertEquals(df.load()[0], doc)
125
 
 
126
 
 
127
 
    def test_xmlfilePreprocessors(self):
128
 
        """
129
 
        Test that the xmlstr loader properly passes uncompiled documents to
130
 
        preprocessors it is given.
131
 
        """
132
 
        xmlFile = self.mktemp()
133
 
        f = file(xmlFile, 'w')
134
 
        f.write('<div><span>Hello</span><span>world</span></div>')
135
 
        f.close()
136
 
        factory = loaders.xmlfile(xmlFile)
137
 
        return self._preprocessorTest(factory)
138
 
 
139
 
 
140
 
    def test_patterned(self):
141
 
        """Test fetching a specific part (a pattern) of the document.
142
 
        """
143
 
        doc = t.div[t.p[t.span(pattern='inner')['something']]]
144
 
        df = loaders.stan(doc, pattern='inner')
145
 
        self.assertEquals(df.load()[0].tagName, 'span')
146
 
        self.assertEquals(df.load()[0].children[0], 'something')
147
 
 
148
 
 
149
 
    def test_ignoreDocType(self):
150
 
        doc = '''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n<html><body><p>Hello.</p></body></html>'''
151
 
        df = loaders.xmlstr(doc, ignoreDocType=True)
152
 
        self.assertEquals(flat.flatten(df), '<html><body><p>Hello.</p></body></html>')
153
 
 
154
 
    def test_ignoreComment(self):
155
 
        doc = '<!-- skip this --><p>Hello.</p>'
156
 
        df = loaders.xmlstr(doc, ignoreComment=True)
157
 
        self.assertEquals(flat.flatten(df), '<p>Hello.</p>')
158
 
 
159
 
 
160
 
class TestDocFactoriesCache(unittest.TestCase):
161
 
 
162
 
    doc = '''
163
 
    <div>
164
 
    <p nevow:pattern="1">one</p>
165
 
    <p nevow:pattern="2">two</p>
166
 
    </div>
167
 
    '''
168
 
 
169
 
    nsdoc = '''
170
 
    <div xmlns:nevow="http://nevow.com/ns/nevow/0.1">
171
 
    <p nevow:pattern="1">one</p>
172
 
    <p nevow:pattern="2">two</p>
173
 
    </div>
174
 
    '''
175
 
 
176
 
    stan = t.div[t.p(pattern='1')['one'],t.p(pattern='2')['two']]
177
 
 
178
 
    def test_stan(self):
179
 
 
180
 
        loader = loaders.stan(self.stan)
181
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
182
 
 
183
 
        loader = loaders.stan(self.stan, pattern='1')
184
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
185
 
 
186
 
        l1 = loaders.stan(self.stan, pattern='1')
187
 
        l2 = loaders.stan(self.stan, pattern='1')
188
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
189
 
 
190
 
        l1 = loaders.stan(self.stan, pattern='1')
191
 
        l2 = loaders.stan(self.stan, pattern='2')
192
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
193
 
 
194
 
 
195
 
    def test_htmlstr(self):
196
 
        loader = loaders.htmlstr(self.doc)
197
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
198
 
 
199
 
        loader = loaders.htmlstr(self.doc, pattern='1')
200
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
201
 
 
202
 
        l1 = loaders.htmlstr(self.doc, pattern='1')
203
 
        l2 = loaders.htmlstr(self.doc, pattern='1')
204
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
205
 
 
206
 
        l1 = loaders.htmlstr(self.doc, pattern='1')
207
 
        l2 = loaders.htmlstr(self.doc, pattern='2')
208
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
209
 
    test_htmlstr.suppress = [
210
 
        util.suppress(message=
211
 
                      r"\[v0.8\] htmlstr is deprecated because it's buggy. "
212
 
                      "Please start using xmlfile and/or xmlstr.")]
213
 
 
214
 
 
215
 
    def test_htmlfile(self):
216
 
        temp = self.mktemp()
217
 
        f = file(temp, 'w')
218
 
        f.write(self.doc)
219
 
        f.close()
220
 
 
221
 
        loader = loaders.htmlfile(temp)
222
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
223
 
 
224
 
        l1 = loaders.htmlfile(temp, pattern='1')
225
 
        l2 = loaders.htmlfile(temp, pattern='1')
226
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
227
 
 
228
 
        l1 = loaders.htmlfile(temp, pattern='1')
229
 
        l2 = loaders.htmlfile(temp, pattern='2')
230
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
231
 
    test_htmlfile.suppress = [
232
 
        util.suppress(message=
233
 
                      r"\[v0.8\] htmlfile is deprecated because it's buggy. "
234
 
                      "Please start using xmlfile and/or xmlstr.")]
235
 
 
236
 
 
237
 
    def test_htmlfileReload(self):
238
 
        temp = self.mktemp()
239
 
        f = file(temp, 'w')
240
 
        f.write(self.doc)
241
 
        f.close()
242
 
 
243
 
        loader = loaders.htmlfile(temp)
244
 
        r = loader.load()
245
 
        self.assertEquals(id(r), id(loader.load()))
246
 
        os.utime(temp, (os.path.getatime(temp), os.path.getmtime(temp)+5))
247
 
        self.assertNotEqual(id(r), id(loader.load()))
248
 
    test_htmlfileReload.suppress = [
249
 
        util.suppress(message=
250
 
                      r"\[v0.8\] htmlfile is deprecated because it's buggy. "
251
 
                      "Please start using xmlfile and/or xmlstr.")]
252
 
 
253
 
 
254
 
 
255
 
    def test_xmlstr(self):
256
 
 
257
 
        loader = loaders.xmlstr(self.nsdoc)
258
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
259
 
 
260
 
        loader = loaders.xmlstr(self.nsdoc, pattern='1')
261
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
262
 
 
263
 
        l1 = loaders.xmlstr(self.nsdoc, pattern='1')
264
 
        l2 = loaders.xmlstr(self.nsdoc, pattern='1')
265
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
266
 
 
267
 
        l1 = loaders.xmlstr(self.nsdoc, pattern='1')
268
 
        l2 = loaders.xmlstr(self.nsdoc, pattern='2')
269
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
270
 
 
271
 
 
272
 
    def test_xmlSlotDefault(self):
273
 
        """
274
 
        An I{nevow:slot} tag in an XML template may have a I{default}
275
 
        attribute specifying a value for the slot if it is not otherwise
276
 
        given one.
277
 
        """
278
 
        slotsdoc = '''
279
 
        <div xmlns:nevow="http://nevow.com/ns/nevow/0.1">
280
 
        <nevow:slot name="1" />
281
 
        <nevow:slot name="2" default="3" />
282
 
        </div>
283
 
        '''
284
 
        loader = loaders.xmlstr(slotsdoc)
285
 
        loaded = loader.load()
286
 
        self.assertEquals(loaded[1].default, None)
287
 
        self.assertEquals(loaded[3].default, "3")
288
 
 
289
 
 
290
 
    def test_xmlfile(self):
291
 
 
292
 
        temp = self.mktemp()
293
 
        f = file(temp, 'w')
294
 
        f.write(self.nsdoc)
295
 
        f.close()
296
 
 
297
 
        loader = loaders.xmlfile(temp)
298
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
299
 
 
300
 
        loader = loaders.xmlfile(temp, pattern='1')
301
 
        self.assertEquals( id(loader.load()), id(loader.load()) )
302
 
 
303
 
        l1 = loaders.xmlfile(temp, pattern='1')
304
 
        l2 = loaders.xmlfile(temp, pattern='1')
305
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
306
 
 
307
 
        l1 = loaders.xmlfile(temp, pattern='1')
308
 
        l2 = loaders.xmlfile(temp, pattern='2')
309
 
        self.assertNotEqual( id(l1.load()), id(l2.load()) )
310
 
 
311
 
    def test_xmlfileReload(self):
312
 
 
313
 
        temp = self.mktemp()
314
 
        f = file(temp, 'w')
315
 
        f.write(self.nsdoc)
316
 
        f.close()
317
 
 
318
 
        loader = loaders.xmlfile(temp)
319
 
        r = loader.load()
320
 
        self.assertEquals(id(r), id(loader.load()))
321
 
        os.utime(temp, (os.path.getatime(temp), os.path.getmtime(temp)+5))
322
 
        self.assertNotEqual(id(r), id(loader.load()))
323
 
 
324
 
    def test_reloadAfterPrecompile(self):
325
 
        """
326
 
        """
327
 
        # Get a filename
328
 
        temp = self.mktemp()
329
 
 
330
 
        # Write some content
331
 
        f = file(temp, 'w')
332
 
        f.write('<p>foo</p>')
333
 
        f.close()
334
 
 
335
 
        # Precompile the doc
336
 
        ctx = context.WovenContext()
337
 
        doc = loaders.htmlfile(temp)
338
 
        pc = flat.precompile(flat.flatten(doc), ctx)
339
 
 
340
 
        before = ''.join(flat.serialize(pc, ctx))
341
 
 
342
 
 
343
 
        # Write the file with different content and make sure the
344
 
        # timestamp changes
345
 
        f = file(temp, 'w')
346
 
        f.write('<p>bar</p>')
347
 
        f.close()
348
 
        os.utime(temp, (os.path.getatime(temp), os.path.getmtime(temp)+5))
349
 
 
350
 
        after = ''.join(flat.serialize(pc, ctx))
351
 
 
352
 
        self.assertIn('foo', before)
353
 
        self.assertIn('bar', after)
354
 
        self.failIfEqual(before, after)
355
 
    test_reloadAfterPrecompile.todo = \
356
 
        'Fix so that disk templates are reloaded even after a precompile. ' \
357
 
        'Probably just a matter of making the DocSerializer really lazy'
358
 
 
359
 
 
360
 
class TestContext(unittest.TestCase):
361
 
    """Check that each of the standard loaders supports load with and without a
362
 
    context.
363
 
    """
364
 
 
365
 
    def test_stan(self):
366
 
        doc = t.p['hello']
367
 
        self._withAndWithout(loaders.stan(doc))
368
 
 
369
 
    def test_xmlstr(self):
370
 
        doc = '<p>hello</p>'
371
 
        self._withAndWithout(loaders.xmlstr(doc))
372
 
 
373
 
    def test_xmlfile(self):
374
 
        temp = self.mktemp()
375
 
        f = file(temp, 'w')
376
 
        f.write('<p>hello</p>')
377
 
        f.close()
378
 
        self._withAndWithout(loaders.xmlfile(temp))
379
 
 
380
 
    def test_htmlstr(self):
381
 
        doc = '<p>hello</p>'
382
 
        self._withAndWithout(loaders.htmlstr(doc))
383
 
    test_htmlstr.suppress = [
384
 
        util.suppress(message=
385
 
                      r"\[v0.8\] htmlstr is deprecated because it's buggy. "
386
 
                      "Please start using xmlfile and/or xmlstr.")]
387
 
 
388
 
    def test_htmlfile(self):
389
 
        temp = self.mktemp()
390
 
        f = file(temp, 'w')
391
 
        f.write('<p>hello</p>')
392
 
        f.close()
393
 
        self._withAndWithout(loaders.htmlfile(temp))
394
 
    test_htmlfile.suppress = [
395
 
        util.suppress(message=
396
 
                      r"\[v0.8\] htmlfile is deprecated because it's buggy. "
397
 
                      "Please start using xmlfile and/or xmlstr.")]
398
 
 
399
 
    def _withAndWithout(self, loader):
400
 
        ctx = context.WovenContext()
401
 
        self.assertEquals(loader.load(), ['<p>hello</p>'])
402
 
        self.assertEquals(loader.load(ctx), ['<p>hello</p>'])
403
 
 
404
 
 
405
 
class TestParsing(unittest.TestCase):
406
 
 
407
 
    def test_missingSpace(self):
408
 
        doc = '<p xmlns:nevow="http://nevow.com/ns/nevow/0.1"><nevow:slot name="foo"/> <nevow:slot name="foo"/></p>'
409
 
        ## This used to say htmlstr, and this test failed because microdom ignores whitespace;
410
 
        ## This test passes fine using xmlstr. I am not going to fix this because microdom is too
411
 
        ## hard to fix. If you need this, switch to xmlstr.
412
 
        result = loaders.xmlstr(doc).load()
413
 
        # There should be a space between the two slots
414
 
        self.assertEquals(result[2], ' ')