Commit 9202ce23 by Chris Jerdonek

Added locator.Locator.find_path_by_object().

Also, more progress on view.Locator.get_template_path().
parent a8464737
...@@ -97,30 +97,44 @@ class Locator(object): ...@@ -97,30 +97,44 @@ class Locator(object):
return re.sub('[A-Z]', repl, template_name)[1:] return re.sub('[A-Z]', repl, template_name)[1:]
def find_path(self, search_dirs, template_name): def _find_path_by_file_name(self, search_dirs, file_name):
""" """
Return the path to a template with the given name. Return the path to a template with the given file name.
""" """
file_name = self.make_file_name(template_name)
path = self._find_path(file_name, search_dirs) path = self._find_path(file_name, search_dirs)
if path is None: if path is None:
# TODO: we should probably raise an exception of our own type. # TODO: we should probably raise an exception of our own type.
raise IOError('Template %s not found in directories: %s' % raise IOError('Template file %s not found in directories: %s' %
(repr(template_name), repr(search_dirs))) (repr(file_name), repr(search_dirs)))
return path return path
def find_path_by_object(self, search_dirs, template_name, obj): def find_path_by_name(self, search_dirs, template_name):
"""
Return the path to a template with the given name.
"""
file_name = self.make_file_name(template_name)
return self._find_path_by_file_name(search_dirs, file_name)
def find_path_by_object(self, search_dirs, obj, file_name=None):
""" """
Return the path to a template associated with the given object. Return the path to a template associated with the given object.
""" """
if file_name is None:
# TODO: should we define a make_file_name() method?
template_name = self.make_template_name(obj)
file_name = self.make_file_name(template_name)
dir_path = self.get_object_directory(obj) dir_path = self.get_object_directory(obj)
if dir_path is not None: if dir_path is not None:
search_dirs = [dir_path] + search_dirs search_dirs = [dir_path] + search_dirs
return self.find_path(search_dirs, template_name) path = self._find_path_by_file_name(search_dirs, file_name)
return path
...@@ -190,7 +190,8 @@ class Renderer(object): ...@@ -190,7 +190,8 @@ class Renderer(object):
locator = self.make_locator() locator = self.make_locator()
def load_template(template_name): def load_template(template_name):
template_path = locator.find_path(self.search_dirs, template_name) template_path = locator.find_path_by_name(self.search_dirs, template_name)
return reader.read(template_path) return reader.read(template_path)
return load_template return load_template
...@@ -264,10 +265,7 @@ class Renderer(object): ...@@ -264,10 +265,7 @@ class Renderer(object):
""" """
locator = self.make_locator() locator = self.make_locator()
template_path = locator.find_path_by_object(self.search_dirs, obj)
template_name = locator.make_template_name(obj)
template_path = locator.find_path_by_object(self.search_dirs, template_name, obj)
return self.read(template_path) return self.read(template_path)
......
...@@ -12,6 +12,7 @@ from .locator import Locator as TemplateLocator ...@@ -12,6 +12,7 @@ from .locator import Locator as TemplateLocator
from .renderer import Renderer from .renderer import Renderer
# TODO: rename this class to something else (e.g. ITemplateInfo)
class View(object): class View(object):
template_name = None template_name = None
...@@ -114,8 +115,9 @@ class Locator(object): ...@@ -114,8 +115,9 @@ class Locator(object):
""" """
def __init__(self, reader, template_locator): def __init__(self, reader, search_dirs, template_locator):
self.reader = reader self.reader = reader
self.search_dirs = search_dirs
self.template_locator = template_locator self.template_locator = template_locator
# TODO: unit test # TODO: unit test
...@@ -127,10 +129,10 @@ class Locator(object): ...@@ -127,10 +129,10 @@ class Locator(object):
if view.template_path is not None: if view.template_path is not None:
return os.path.split(view.template_path) return os.path.split(view.template_path)
# TODO: finish this # TODO: finish this
return None return (None, None)
# TODO: unit test
def get_template_path(self, view): def get_template_path(self, view):
""" """
Return the path to the view's associated template. Return the path to the view's associated template.
...@@ -139,13 +141,13 @@ class Locator(object): ...@@ -139,13 +141,13 @@ class Locator(object):
dir_path, file_name = self.get_relative_template_location(view) dir_path, file_name = self.get_relative_template_location(view)
if dir_path is None: if dir_path is None:
path = self.template_locator.find_path(search_dirs, file_name, obj=view) # Then we need to search for the path.
path = self.template_locator.find_path_by_object(self.search_dirs, view, file_name=file_name)
if view.template_path is not None: else:
return os.path.split(view.template_path) obj_dir = self.template_locator.get_object_directory(view)
path = os.path.join(obj_dir, dir_path, file_name)
# TODO: finish this return path
return None
def get_template(self, view): def get_template(self, view):
if view.template is not None: if view.template is not None:
......
Sample view...
\ No newline at end of file
# coding: utf-8 # coding: utf-8
from pystache.view import View
class SayHello(object): class SayHello(object):
def to(self): def to(self):
return "World" return "World"
class SampleView(View):
pass
...@@ -14,7 +14,8 @@ from pystache.locator import Locator ...@@ -14,7 +14,8 @@ from pystache.locator import Locator
from pystache.reader import Reader from pystache.reader import Reader
from .common import DATA_DIR from .common import DATA_DIR
from data.templates import SayHello from data.views import SayHello
class LocatorTests(unittest.TestCase): class LocatorTests(unittest.TestCase):
...@@ -62,21 +63,21 @@ class LocatorTests(unittest.TestCase): ...@@ -62,21 +63,21 @@ class LocatorTests(unittest.TestCase):
locator.template_extension = '' locator.template_extension = ''
self.assertEquals(locator.make_file_name('foo'), 'foo.') self.assertEquals(locator.make_file_name('foo'), 'foo.')
def test_find_path(self): def test_find_path_by_name(self):
locator = Locator() locator = Locator()
path = locator.find_path(search_dirs=['examples'], template_name='simple') path = locator.find_path_by_name(search_dirs=['examples'], template_name='simple')
self.assertEquals(os.path.basename(path), 'simple.mustache') self.assertEquals(os.path.basename(path), 'simple.mustache')
def test_find_path__using_list_of_paths(self): def test_find_path_by_name__using_list_of_paths(self):
locator = Locator() locator = Locator()
path = locator.find_path(search_dirs=['doesnt_exist', 'examples'], template_name='simple') path = locator.find_path_by_name(search_dirs=['doesnt_exist', 'examples'], template_name='simple')
self.assertTrue(path) self.assertTrue(path)
def test_find_path__precedence(self): def test_find_path_by_name__precedence(self):
""" """
Test the order in which find_path() searches directories. Test the order in which find_path_by_name() searches directories.
""" """
locator = Locator() locator = Locator()
...@@ -84,26 +85,36 @@ class LocatorTests(unittest.TestCase): ...@@ -84,26 +85,36 @@ class LocatorTests(unittest.TestCase):
dir1 = DATA_DIR dir1 = DATA_DIR
dir2 = os.path.join(DATA_DIR, 'locator') dir2 = os.path.join(DATA_DIR, 'locator')
self.assertTrue(locator.find_path(search_dirs=[dir1], template_name='duplicate')) self.assertTrue(locator.find_path_by_name(search_dirs=[dir1], template_name='duplicate'))
self.assertTrue(locator.find_path(search_dirs=[dir2], template_name='duplicate')) self.assertTrue(locator.find_path_by_name(search_dirs=[dir2], template_name='duplicate'))
path = locator.find_path(search_dirs=[dir2, dir1], template_name='duplicate') path = locator.find_path_by_name(search_dirs=[dir2, dir1], template_name='duplicate')
dirpath = os.path.dirname(path) dirpath = os.path.dirname(path)
dirname = os.path.split(dirpath)[-1] dirname = os.path.split(dirpath)[-1]
self.assertEquals(dirname, 'locator') self.assertEquals(dirname, 'locator')
def test_find_path__non_existent_template_fails(self): def test_find_path_by_name__non_existent_template_fails(self):
locator = Locator() locator = Locator()
self.assertRaises(IOError, locator.find_path, search_dirs=[], template_name='doesnt_exist') self.assertRaises(IOError, locator.find_path_by_name, search_dirs=[], template_name='doesnt_exist')
def test_find_path_by_object(self): def test_find_path_by_object(self):
locator = Locator() locator = Locator()
obj = SayHello() obj = SayHello()
actual = locator.find_path_by_object(search_dirs=[], template_name='say_hello', obj=obj) actual = locator.find_path_by_object(search_dirs=[], obj=obj, file_name='sample_view.mustache')
expected = os.path.abspath(os.path.join(DATA_DIR, 'sample_view.mustache'))
self.assertEquals(actual, expected)
def test_find_path_by_object__none_file_name(self):
locator = Locator()
obj = SayHello()
actual = locator.find_path_by_object(search_dirs=[], obj=obj)
expected = os.path.abspath(os.path.join(DATA_DIR, 'say_hello.mustache')) expected = os.path.abspath(os.path.join(DATA_DIR, 'say_hello.mustache'))
self.assertEquals(actual, expected) self.assertEquals(actual, expected)
...@@ -114,7 +125,7 @@ class LocatorTests(unittest.TestCase): ...@@ -114,7 +125,7 @@ class LocatorTests(unittest.TestCase):
obj = None obj = None
self.assertEquals(None, locator.get_object_directory(obj)) self.assertEquals(None, locator.get_object_directory(obj))
actual = locator.find_path_by_object(search_dirs=[DATA_DIR], template_name='say_hello', obj=obj) actual = locator.find_path_by_object(search_dirs=[DATA_DIR], obj=obj, file_name='say_hello.mustache')
expected = os.path.join(DATA_DIR, 'say_hello.mustache') expected = os.path.join(DATA_DIR, 'say_hello.mustache')
self.assertEquals(actual, expected) self.assertEquals(actual, expected)
......
...@@ -16,7 +16,7 @@ from pystache.renderer import Renderer ...@@ -16,7 +16,7 @@ from pystache.renderer import Renderer
from pystache.locator import Locator from pystache.locator import Locator
from .common import get_data_path from .common import get_data_path
from .data.templates import SayHello from .data.views import SayHello
class RendererInitTestCase(unittest.TestCase): class RendererInitTestCase(unittest.TestCase):
......
import os.path
import unittest import unittest
import pystache
from examples.simple import Simple from examples.simple import Simple
from examples.complex_view import ComplexView from examples.complex_view import ComplexView
from examples.lambdas import Lambdas from examples.lambdas import Lambdas
from examples.inverted import Inverted, InvertedLists from examples.inverted import Inverted, InvertedLists
from pystache.locator import Locator as TemplateLocator
from pystache.view import View from pystache.view import View
from pystache.view import Locator from pystache.view import Locator as ViewLocator
from tests.common import AssertIsMixin from .common import AssertIsMixin
from .common import DATA_DIR
from .data.views import SampleView
class Thing(object): class Thing(object):
...@@ -179,13 +182,14 @@ class LocatorTests(unittest.TestCase, AssertIsMixin): ...@@ -179,13 +182,14 @@ class LocatorTests(unittest.TestCase, AssertIsMixin):
return "read: %s" % repr(path) return "read: %s" % repr(path)
reader = MockReader() reader = MockReader()
# TODO: include a locator? template_locator = TemplateLocator()
locator = Locator(reader=reader, template_locator=None) locator = ViewLocator(reader=reader, search_dirs=[DATA_DIR], template_locator=template_locator)
return locator return locator
# TODO: fully test constructor.
def test_init__reader(self): def test_init__reader(self):
reader = "reader" # in practice, this is a reader instance. reader = "reader" # in practice, this is a reader instance.
locator = Locator(reader, template_locator=None) locator = ViewLocator(reader, search_dirs=None, template_locator=None)
self.assertIs(locator.reader, reader) self.assertIs(locator.reader, reader)
...@@ -205,6 +209,37 @@ class LocatorTests(unittest.TestCase, AssertIsMixin): ...@@ -205,6 +209,37 @@ class LocatorTests(unittest.TestCase, AssertIsMixin):
view.template_path = 'foo.txt' view.template_path = 'foo.txt'
self.assertEquals(locator.get_relative_template_location(view), ('', 'foo.txt')) self.assertEquals(locator.get_relative_template_location(view), ('', 'foo.txt'))
def test_get_template_path__with_directory(self):
"""
Test get_template_path() with a view that has a directory specified.
"""
locator = self._make_locator()
view = SampleView()
view.template_path = 'foo/bar.txt'
self.assertTrue(locator.get_relative_template_location(view)[0] is not None)
actual = locator.get_template_path(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'foo/bar.txt'))
self.assertEquals(actual, expected)
def test_get_template_path__without_directory(self):
"""
Test get_template_path() with a view that doesn't have a directory specified.
"""
locator = self._make_locator()
view = SampleView()
self.assertTrue(locator.get_relative_template_location(view)[0] is None)
actual = locator.get_template_path(view)
expected = os.path.abspath(os.path.join(DATA_DIR, 'sample_view.mustache'))
self.assertEquals(actual, expected)
def test_get_template__template_attribute_set(self): def test_get_template__template_attribute_set(self):
""" """
Test get_template() with view.template set to a non-None value. Test get_template() with view.template set to a non-None value.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment