/hyde/tests/test_plugin.py
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"]