PageRenderTime 52ms CodeModel.GetById 17ms app.highlight 31ms RepoModel.GetById 1ms app.codeStats 0ms

/hyde/tests/test_plugin.py

http://github.com/hyde/hyde
Python | 370 lines | 293 code | 71 blank | 6 comment | 7 complexity | 4e11ba91863d82ce0cab25d73c99886f MD5 | raw file
  1# -*- coding: utf-8 -*-
  2"""
  3Use nose
  4`$ pip install nose`
  5`$ nosetests`
  6"""
  7
  8from hyde.generator import Generator
  9from hyde.plugin import Plugin
 10from hyde.site import Site
 11from hyde.model import Expando
 12
 13from mock import patch, Mock
 14
 15from fswrap import File, Folder
 16
 17TEST_SITE = File(__file__).parent.child_folder('_test')
 18
 19class PluginLoaderStub(Plugin):
 20    pass
 21
 22class NoReturnPlugin(Plugin):
 23
 24    def begin_text_resource(self, resource, text):
 25        print "NoReturnPlugin"
 26        return None
 27
 28class ConstantReturnPlugin(Plugin):
 29
 30    def begin_text_resource(self, resource, text):
 31        print "ConstantReturnPlugin"
 32        return "Jam"
 33
 34
 35class TestPlugins(object):
 36
 37    @classmethod
 38    def setup_class(cls):
 39        TEST_SITE.make()
 40        TEST_SITE.parent.child_folder('sites/test_jinja').copy_contents_to(TEST_SITE)
 41        folders = []
 42        text_files = []
 43        binary_files = []
 44
 45        with TEST_SITE.child_folder('content').walker as walker:
 46            @walker.folder_visitor
 47            def visit_folder(folder):
 48                folders.append(folder.path)
 49
 50            @walker.file_visitor
 51            def visit_file(afile):
 52                if not afile.is_text:
 53                    binary_files.append(afile.path)
 54                else:
 55                    text_files.append(afile.path)
 56
 57        cls.content_nodes = sorted(folders)
 58        cls.content_text_resources = sorted(text_files)
 59        cls.content_binary_resources = sorted(binary_files)
 60
 61
 62    @classmethod
 63    def teardown_class(cls):
 64        TEST_SITE.delete()
 65
 66    def setUp(self):
 67         self.site = Site(TEST_SITE)
 68         self.site.config.plugins = ['hyde.tests.test_plugin.PluginLoaderStub']
 69
 70    def test_can_load_plugin_modules(self):
 71        assert not len(self.site.plugins)
 72        Plugin.load_all(self.site)
 73
 74        assert len(self.site.plugins) == 1
 75        assert self.site.plugins[0].__class__.__name__ == 'PluginLoaderStub'
 76
 77
 78    def test_generator_loads_plugins(self):
 79        gen = Generator(self.site)
 80        assert len(self.site.plugins) == 1
 81
 82    def test_generator_template_registered_called(self):
 83        with patch.object(PluginLoaderStub, 'template_loaded') as template_loaded_stub:
 84            gen = Generator(self.site)
 85            gen.generate_all()
 86            assert template_loaded_stub.call_count == 1
 87
 88    def test_generator_template_begin_generation_called(self):
 89        with patch.object(PluginLoaderStub, 'begin_generation') as begin_generation_stub:
 90            gen = Generator(self.site)
 91            gen.generate_all()
 92            assert begin_generation_stub.call_count == 1
 93
 94    def test_generator_template_begin_generation_called_for_single_resource(self):
 95        with patch.object(PluginLoaderStub, 'begin_generation') as begin_generation_stub:
 96            gen = Generator(self.site)
 97            path = self.site.content.source_folder.child('about.html')
 98            gen.generate_resource_at_path(path)
 99
100            assert begin_generation_stub.call_count == 1
101
102    def test_generator_template_begin_generation_called_for_single_node(self):
103        with patch.object(PluginLoaderStub, 'begin_generation') as begin_generation_stub:
104            gen = Generator(self.site)
105            path = self.site.content.source_folder
106            gen.generate_node_at_path(path)
107            assert begin_generation_stub.call_count == 1
108
109
110    def test_generator_template_generation_complete_called(self):
111        with patch.object(PluginLoaderStub, 'generation_complete') as generation_complete_stub:
112            gen = Generator(self.site)
113            gen.generate_all()
114            assert generation_complete_stub.call_count == 1
115
116    def test_generator_template_generation_complete_called_for_single_resource(self):
117        with patch.object(PluginLoaderStub, 'generation_complete') as generation_complete_stub:
118            gen = Generator(self.site)
119            path = self.site.content.source_folder.child('about.html')
120            gen.generate_resource_at_path(path)
121
122            assert generation_complete_stub.call_count == 1
123
124    def test_generator_template_generation_complete_called_for_single_node(self):
125        with patch.object(PluginLoaderStub, 'generation_complete') as generation_complete_stub:
126            gen = Generator(self.site)
127            path = self.site.content.source_folder
128            gen.generate_node_at_path(path)
129            assert generation_complete_stub.call_count == 1
130
131    def test_generator_template_begin_site_called(self):
132        with patch.object(PluginLoaderStub, 'begin_site') as begin_site_stub:
133            gen = Generator(self.site)
134            gen.generate_all()
135            assert begin_site_stub.call_count == 1
136
137    def test_generator_template_begin_site_called_for_single_resource(self):
138        with patch.object(PluginLoaderStub, 'begin_site') as begin_site_stub:
139            gen = Generator(self.site)
140            path = self.site.content.source_folder.child('about.html')
141            gen.generate_resource_at_path(path)
142            assert begin_site_stub.call_count == 1
143
144    def test_generator_template_begin_site_not_called_for_single_resource_second_time(self):
145        with patch.object(PluginLoaderStub, 'begin_site') as begin_site_stub:
146            gen = Generator(self.site)
147            gen.generate_all()
148            assert begin_site_stub.call_count == 1
149            path = self.site.content.source_folder.child('about.html')
150            gen.generate_resource_at_path(path)
151            assert begin_site_stub.call_count == 1
152
153    def test_generator_template_begin_site_called_for_single_node(self):
154        with patch.object(PluginLoaderStub, 'begin_site') as begin_site_stub:
155            gen = Generator(self.site)
156            path = self.site.content.source_folder
157            gen.generate_node_at_path(path)
158
159            assert begin_site_stub.call_count == 1
160
161    def test_generator_template_begin_site_not_called_for_single_node_second_time(self):
162        with patch.object(PluginLoaderStub, 'begin_site') as begin_site_stub:
163            gen = Generator(self.site)
164            gen.generate_all()
165            assert begin_site_stub.call_count == 1
166            path = self.site.content.source_folder
167            gen.generate_node_at_path(path)
168
169            assert begin_site_stub.call_count == 1
170
171    def test_generator_template_site_complete_called(self):
172        with patch.object(PluginLoaderStub, 'site_complete') as site_complete_stub:
173            gen = Generator(self.site)
174            gen.generate_all()
175            assert site_complete_stub.call_count == 1
176
177
178    def test_generator_template_site_complete_called_for_single_resource(self):
179
180        with patch.object(PluginLoaderStub, 'site_complete') as site_complete_stub:
181            gen = Generator(self.site)
182            path = self.site.content.source_folder.child('about.html')
183            gen.generate_resource_at_path(path)
184
185            assert site_complete_stub.call_count == 1
186
187    def test_generator_template_site_complete_not_called_for_single_resource_second_time(self):
188
189        with patch.object(PluginLoaderStub, 'site_complete') as site_complete_stub:
190            gen = Generator(self.site)
191            gen.generate_all()
192            assert site_complete_stub.call_count == 1
193            path = self.site.content.source_folder.child('about.html')
194            gen.generate_resource_at_path(path)
195
196            assert site_complete_stub.call_count == 1
197
198    def test_generator_template_site_complete_called_for_single_node(self):
199
200        with patch.object(PluginLoaderStub, 'site_complete') as site_complete_stub:
201            gen = Generator(self.site)
202            path = self.site.content.source_folder
203            gen.generate_node_at_path(path)
204
205            assert site_complete_stub.call_count == 1
206
207    def test_generator_template_site_complete_not_called_for_single_node_second_time(self):
208
209        with patch.object(PluginLoaderStub, 'site_complete') as site_complete_stub:
210            gen = Generator(self.site)
211            gen.generate_all()
212            path = self.site.content.source_folder
213            gen.generate_node_at_path(path)
214
215            assert site_complete_stub.call_count == 1
216
217    def test_generator_template_begin_node_called(self):
218
219        with patch.object(PluginLoaderStub, 'begin_node') as begin_node_stub:
220            gen = Generator(self.site)
221            gen.generate_all()
222
223            assert begin_node_stub.call_count == len(self.content_nodes)
224            called_with_nodes = sorted([arg[0][0].path for arg in begin_node_stub.call_args_list])
225            assert called_with_nodes == self.content_nodes
226
227    def test_generator_template_begin_node_called_for_single_resource(self):
228
229        with patch.object(PluginLoaderStub, 'begin_node') as begin_node_stub:
230            gen = Generator(self.site)
231            gen.generate_resource_at_path(self.site.content.source_folder.child('about.html'))
232            assert begin_node_stub.call_count == len(self.content_nodes)
233
234
235    def test_generator_template_begin_node_not_called_for_single_resource_second_time(self):
236
237        with patch.object(PluginLoaderStub, 'begin_node') as begin_node_stub:
238            gen = Generator(self.site)
239            gen.generate_all()
240            assert begin_node_stub.call_count == len(self.content_nodes)
241            gen.generate_resource_at_path(self.site.content.source_folder.child('about.html'))
242            assert begin_node_stub.call_count == len(self.content_nodes) # No extra calls
243
244
245    def test_generator_template_node_complete_called(self):
246
247        with patch.object(PluginLoaderStub, 'node_complete') as node_complete_stub:
248            gen = Generator(self.site)
249            gen.generate_all()
250
251            assert node_complete_stub.call_count == len(self.content_nodes)
252            called_with_nodes = sorted([arg[0][0].path for arg in node_complete_stub.call_args_list])
253            assert called_with_nodes == self.content_nodes
254
255    def test_generator_template_node_complete_called_for_single_resource(self):
256
257        with patch.object(PluginLoaderStub, 'node_complete') as node_complete_stub:
258            gen = Generator(self.site)
259            gen.generate_resource_at_path(self.site.content.source_folder.child('about.html'))
260            assert node_complete_stub.call_count == len(self.content_nodes)
261
262    def test_generator_template_node_complete_not_called_for_single_resource_second_time(self):
263
264        with patch.object(PluginLoaderStub, 'node_complete') as node_complete_stub:
265            gen = Generator(self.site)
266            gen.generate_all()
267            assert node_complete_stub.call_count == len(self.content_nodes)
268            gen.generate_resource_at_path(self.site.content.source_folder.child('about.html'))
269            assert node_complete_stub.call_count == len(self.content_nodes) # No extra calls
270
271    def test_generator_template_begin_text_resource_called(self):
272
273        with patch.object(PluginLoaderStub, 'begin_text_resource') as begin_text_resource_stub:
274            begin_text_resource_stub.reset_mock()
275            begin_text_resource_stub.return_value = ''
276            gen = Generator(self.site)
277            gen.generate_all()
278
279            called_with_resources = sorted([arg[0][0].path for arg in begin_text_resource_stub.call_args_list])
280            assert set(called_with_resources) == set(self.content_text_resources)
281
282    def test_generator_template_begin_text_resource_called_for_single_resource(self):
283
284        with patch.object(PluginLoaderStub, 'begin_text_resource') as begin_text_resource_stub:
285            begin_text_resource_stub.return_value = ''
286            gen = Generator(self.site)
287            gen.generate_all()
288            begin_text_resource_stub.reset_mock()
289            path = self.site.content.source_folder.child('about.html')
290            gen = Generator(self.site)
291            gen.generate_resource_at_path(path, incremental=True)
292
293            called_with_resources = sorted([arg[0][0].path for arg in begin_text_resource_stub.call_args_list])
294            assert begin_text_resource_stub.call_count == 1
295            assert called_with_resources[0] == path
296
297    def test_generator_template_begin_binary_resource_called(self):
298
299        with patch.object(PluginLoaderStub, 'begin_binary_resource') as begin_binary_resource_stub:
300            gen = Generator(self.site)
301            gen.generate_all()
302
303            called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list])
304            assert begin_binary_resource_stub.call_count == len(self.content_binary_resources)
305            assert called_with_resources == self.content_binary_resources
306
307    def test_generator_template_begin_binary_resource_called_for_single_resource(self):
308
309        with patch.object(PluginLoaderStub, 'begin_binary_resource') as begin_binary_resource_stub:
310            gen = Generator(self.site)
311            gen.generate_all()
312            begin_binary_resource_stub.reset_mock()
313            path = self.site.content.source_folder.child('favicon.ico')
314            gen.generate_resource_at_path(path)
315
316            called_with_resources = sorted([arg[0][0].path for arg in begin_binary_resource_stub.call_args_list])
317            assert begin_binary_resource_stub.call_count == 1
318            assert called_with_resources[0] == path
319
320    def test_plugin_chaining(self):
321         self.site.config.plugins = [
322            'hyde.tests.test_plugin.ConstantReturnPlugin',
323            'hyde.tests.test_plugin.NoReturnPlugin'
324         ]
325         path = self.site.content.source_folder.child('about.html')
326         gen = Generator(self.site)
327         gen.generate_resource_at_path(path)
328         about = File(Folder(
329                    self.site.config.deploy_root_path).child('about.html'))
330         assert about.read_all() == "Jam"
331
332    def test_plugin_filters_begin_text_resource(self):
333        def empty_return(self, resource, text=''):
334            return text
335        with patch.object(ConstantReturnPlugin, 'begin_text_resource', new=Mock(wraps=empty_return)) as mock1:
336            with patch.object(NoReturnPlugin, 'begin_text_resource', new=Mock(wraps=empty_return)) as mock2:
337                self.site.config.plugins = [
338                    'hyde.tests.test_plugin.ConstantReturnPlugin',
339                    'hyde.tests.test_plugin.NoReturnPlugin'
340                 ]
341                self.site.config.constantreturn = Expando(dict(include_file_pattern="*.css"))
342                self.site.config.noreturn = Expando(dict(include_file_pattern=["*.html", "*.txt"]))
343                gen = Generator(self.site)
344                gen.generate_all()
345                mock1_args = sorted(set([arg[0][0].name for arg in mock1.call_args_list]))
346                mock2_args = sorted(set([arg[0][0].name for arg in mock2.call_args_list]))
347                assert len(mock1_args) == 1
348                assert len(mock2_args) == 4
349                assert mock1_args == ["site.css"]
350                assert mock2_args == ["404.html", "about.html", "merry-christmas.html", "robots.txt"]
351
352    def test_plugin_node_filters_begin_text_resource(self):
353        def empty_return(*args, **kwargs):
354            return None
355        with patch.object(ConstantReturnPlugin, 'begin_text_resource', new=Mock(wraps=empty_return)) as mock1:
356            with patch.object(NoReturnPlugin, 'begin_text_resource', new=Mock(wraps=empty_return)) as mock2:
357                self.site.config.plugins = [
358                    'hyde.tests.test_plugin.ConstantReturnPlugin',
359                    'hyde.tests.test_plugin.NoReturnPlugin'
360                 ]
361                self.site.config.constantreturn = Expando(dict(include_paths="media"))
362                self.site.config.noreturn = Expando(dict(include_file_pattern="*.html", include_paths=["blog"]))
363                gen = Generator(self.site)
364                gen.generate_all()
365                mock1_args = sorted(set([arg[0][0].name for arg in mock1.call_args_list]))
366                mock2_args = sorted(set([arg[0][0].name for arg in mock2.call_args_list]))
367                assert len(mock1_args) == 1
368                assert len(mock2_args) == 1
369                assert mock1_args == ["site.css"]
370                assert mock2_args == ["merry-christmas.html"]