diff --git a/hamlpy/hamlpy.py b/hamlpy/hamlpy.py index 4aa5037..e8ce661 100755 --- a/hamlpy/hamlpy.py +++ b/hamlpy/hamlpy.py @@ -49,7 +49,6 @@ def process_lines(self, haml_lines): return root.render() def convert_files(): - import sys import codecs parser = OptionParser() diff --git a/hamlpy/template/loaders.py b/hamlpy/template/loaders.py index 4d80c09..5835b11 100644 --- a/hamlpy/template/loaders.py +++ b/hamlpy/template/loaders.py @@ -3,6 +3,7 @@ try: from django.template import TemplateDoesNotExist from django.template.loaders import filesystem, app_directories + _django_available = True except ImportError, e: class TemplateDoesNotExist(Exception): @@ -13,26 +14,43 @@ class TemplateDoesNotExist(Exception): from hamlpy import hamlpy from hamlpy.template.utils import get_django_template_loaders - # Get options from Django settings options_dict = {} if _django_available: from django.conf import settings + if hasattr(settings, 'HAMLPY_ATTR_WRAPPER'): options_dict.update(attr_wrapper=settings.HAMLPY_ATTR_WRAPPER) def get_haml_loader(loader): if hasattr(loader, 'Loader'): - baseclass = loader.Loader + BaseClass = loader.Loader else: - class baseclass(object): + class BaseClass(object): def load_template_source(self, *args, **kwargs): return loader.load_template_source(*args, **kwargs) - class Loader(baseclass): + def get_contents(self, origin): + return loader.get_contents(origin) + + class Loader(BaseClass): + def get_contents(self, origin): + # Django>=1.9 + contents = super(Loader, self).get_contents(origin) + name, _extension = os.path.splitext(origin.template_name) + # os.path.splitext always returns a period at the start of extension + extension = _extension.lstrip('.') + + if extension in hamlpy.VALID_EXTENSIONS: + compiler = hamlpy.Compiler(options_dict=options_dict) + return compiler.process(contents) + + return contents + def load_template_source(self, template_name, *args, **kwargs): + # Django<1.9 name, _extension = os.path.splitext(template_name) # os.path.splitext always returns a period at the start of extension extension = _extension.lstrip('.') @@ -61,7 +79,7 @@ def _generate_template_name(self, name, extension="hamlpy"): haml_loaders = dict((name, get_haml_loader(loader)) - for (name, loader) in get_django_template_loaders()) + for (name, loader) in get_django_template_loaders()) if _django_available: HamlPyFilesystemLoader = get_haml_loader(filesystem) diff --git a/hamlpy/test/codecoverage.sh b/hamlpy/test/codecoverage.sh deleted file mode 100644 index 7bd87df..0000000 --- a/hamlpy/test/codecoverage.sh +++ /dev/null @@ -1 +0,0 @@ -nosetests *.py --with-coverage --cover-html --cover-inclusive --cover-package=hamlpy.* diff --git a/hamlpy/test/loader_test.py b/hamlpy/test/loader_test.py index 27643aa..3b06886 100644 --- a/hamlpy/test/loader_test.py +++ b/hamlpy/test/loader_test.py @@ -1,74 +1,118 @@ import unittest -import sys +import mock +from hamlpy.hamlpy import Compiler try: - from django.conf import settings - - settings.configure(DEBUG=True, TEMPLATE_DEBUG=True) + from django.conf import settings + settings.configure(DEBUG=True, TEMPLATE_DEBUG=True) except ImportError, e: - pass + pass from hamlpy.template.loaders import get_haml_loader, TemplateDoesNotExist + class DummyLoader(object): """ A dummy template loader that only loads templates from self.templates """ templates = { - "in_dict.txt" : "in_dict content", - "loader_test.hamlpy" : "loader_test content", + "in_dict.txt": "Original txt contents", + "loader_test.hamlpy": "Original hamlpy content", } + def __init__(self, *args, **kwargs): self.Loader = self.__class__ - + + def get_contents(self, origin): + if origin.template_name not in self.templates: + raise TemplateDoesNotExist(origin.template_name) + return self.templates[origin.template_name] + def load_template_source(self, template_name, *args, **kwargs): - try: - return (self.templates[template_name], "test:%s" % template_name) - except KeyError: + if template_name not in self.templates: raise TemplateDoesNotExist(template_name) + return self.templates[template_name], 'Original content' + + class LoaderTest(unittest.TestCase): - """ - Tests for the django template loader. - - A dummy template loader is used that loads only from a dictionary of templates. - """ - - def setUp(self): + def setUp(self): dummy_loader = DummyLoader() - hamlpy_loader_class = get_haml_loader(dummy_loader) self.hamlpy_loader = hamlpy_loader_class() - + + patch_compiler_class = mock.patch('hamlpy.hamlpy.Compiler') + self.compiler_class = patch_compiler_class.start() + self.mock_compiler = mock.Mock(spec=Compiler) + self.compiler_class.return_value = self.mock_compiler + self.addCleanup(patch_compiler_class.stop) + + +class DummyOrigin(object): + def __init__(self, name, template_name=None, loader=None): + self.name = name + self.template_name = template_name + self.loader = loader + + +class LoadTemplateSourceTest(LoaderTest): + """ + Tests for the django template loader. A dummy template loader is + used that loads only from a dictionary of templates. + """ + def _test_assert_exception(self, template_name): - try: + with self.assertRaises(TemplateDoesNotExist): self.hamlpy_loader.load_template_source(template_name) - except TemplateDoesNotExist: - self.assertTrue(True) - else: - self.assertTrue(False, '\'%s\' should not be loaded by the hamlpy tempalte loader.' % template_name) - + def test_file_not_in_dict(self): # not_in_dict.txt doesn't exit, so we're expecting an exception self._test_assert_exception('not_in_dict.hamlpy') - + def test_file_in_dict(self): # in_dict.txt in in dict, but with an extension not supported by # the loader, so we expect an exception self._test_assert_exception('in_dict.txt') - + def test_file_should_load(self): # loader_test.hamlpy is in the dict, so it should load fine - try: - self.hamlpy_loader.load_template_source('loader_test.hamlpy') - except TemplateDoesNotExist: - self.assertTrue(False, '\'loader_test.hamlpy\' should be loaded by the hamlpy tempalte loader, but it was not.') - else: - self.assertTrue(True) - + self.hamlpy_loader.load_template_source('loader_test.hamlpy') + self.mock_compiler.process.assert_called_with('Original hamlpy content') + def test_file_different_extension(self): # loader_test.hamlpy is in dict, but we're going to try # to load loader_test.txt # we expect an exception since the extension is not supported by # the loader self._test_assert_exception('loader_test.txt') + + +class GetContentsTest(LoaderTest): + def setUp(self): + super(GetContentsTest, self).setUp() + + def _get_origin(self, template_name): + return DummyOrigin(name='path/to/{}'.format(template_name), template_name=template_name) + + def test_it_raises_template_does_not_exist_with_invalid_template(self): + origin = self._get_origin('not_in_dict.hamlpy') + with self.assertRaises(TemplateDoesNotExist): + self.hamlpy_loader.get_contents(origin) + + def test_it_does_parse_file_with_valid_extension(self): + origin = self._get_origin(template_name='loader_test.hamlpy') + self.hamlpy_loader.get_contents(origin) + self.mock_compiler.process.assert_called_with('Original hamlpy content') + + def test_it_does_not_parse_file_with_invalid_extension(self): + origin = self._get_origin(template_name='in_dict.txt') + self.hamlpy_loader.get_contents(origin) + self.assertIs(False, self.mock_compiler.process.called) + + def test_it_returns_the_parsed_content(self): + origin = self._get_origin(template_name='loader_test.hamlpy') + self.mock_compiler.process.return_value = 'Parsed content' + + parsed_content = self.hamlpy_loader.get_contents(origin) + + self.assertEqual('Parsed content', parsed_content) diff --git a/hamlpy/test/template_compare_test.py b/hamlpy/test/template_compare_test.py index 3d20485..a7c3826 100644 --- a/hamlpy/test/template_compare_test.py +++ b/hamlpy/test/template_compare_test.py @@ -107,8 +107,10 @@ def _print_diff(self, s1, s2): print "No Difference Found" def _compare_test_files(self, name): - haml_lines = codecs.open('templates/' + name + '.hamlpy', encoding = 'utf-8').readlines() - html = open('templates/' + name + '.html').read() + import os + dir = os.path.dirname(__file__) + haml_lines = codecs.open(dir + '/templates/' + name + '.hamlpy', encoding = 'utf-8').readlines() + html = open(dir + '/templates/' + name + '.html').read() haml_compiler = hamlpy.Compiler() parsed = haml_compiler.process_lines(haml_lines) diff --git a/readme.md b/readme.md index f3b3664..61d7ba2 100644 --- a/readme.md +++ b/readme.md @@ -157,6 +157,6 @@ HamlPy currently: ## Contributing -Very happy to have contributions to this project. Please write tests for any new features and always ensure the current tests pass. You can run the tests from the **hamlpy/test** folder using nosetests by typing +Very happy to have contributions to this project. Please write tests for any new features and always ensure the current tests pass. You can run the tests from the base direcotry by running - nosetests *.py + python setup.py nosetests diff --git a/setup.py b/setup.py index 58de695..47cad58 100644 --- a/setup.py +++ b/setup.py @@ -1,20 +1,23 @@ from setuptools import setup # Note to Jesse - only push sdist to PyPi, bdist seems to always break pip installer -setup(name='hamlpy', - version = '0.82.2', - download_url = 'git@github.com:jessemiller/HamlPy.git', - packages = ['hamlpy', 'hamlpy.template'], - author = 'Jesse Miller', - author_email = 'millerjesse@gmail.com', - description = 'HAML like syntax for Django templates', - keywords = 'haml django converter', - url = 'http://github.com/jessemiller/HamlPy', - license = 'MIT', - install_requires = [ - ], - entry_points = { - 'console_scripts' : ['hamlpy = hamlpy.hamlpy:convert_files', - 'hamlpy-watcher = hamlpy.hamlpy_watcher:watch_folder'] - } - ) +setup( + name='hamlpy', + version='0.82.2', + download_url='git@github.com:jessemiller/HamlPy.git', + packages=['hamlpy', 'hamlpy.template'], + author='Jesse Miller', + author_email='millerjesse@gmail.com', + description='HAML like syntax for Django templates', + keywords='haml django converter', + url='http://github.com/jessemiller/HamlPy', + license='MIT', + test_suite='hamlpy.test', + install_requires=[], + setup_requires=['mock'], + entry_points={ + 'console_scripts': + ['hamlpy = hamlpy.hamlpy:convert_files', + 'hamlpy-watcher = hamlpy.hamlpy_watcher:watch_folder'] + } +)