summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2014-04-28 17:03:37 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2014-04-28 17:03:37 -0400
commit70981099103828afbe33eb4d1f668dc20894b399 (patch)
tree4b9c0a98829b4d409211a8d536ca4e94e7450c8d
parentd1f6d7f3e7e698eff2c7774b63531f151d908209 (diff)
downloadmako-70981099103828afbe33eb4d1f668dc20894b399.tar.gz
- switch to argparse for cmdline template runner
- write a test suite for cmdline - start using context manager helpers in tests. intrinsic here is that we're going to go 1.0 and drop at least 2.4 and probably 2.5 - update .gitignore
-rwxr-xr-x.gitignore2
-rwxr-xr-xmako/cmd.py82
-rw-r--r--setup.py7
-rw-r--r--test/__init__.py28
-rw-r--r--test/templates/cmd_good.mako1
-rw-r--r--test/templates/cmd_runtime.mako1
-rw-r--r--test/templates/cmd_syntax.mako1
-rw-r--r--test/test_cmd.py73
8 files changed, 140 insertions, 55 deletions
diff --git a/.gitignore b/.gitignore
index 267bfc2..c5771df 100755
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
/build
+/dist
+/.coverage
/doc/build/output
*.pyc
*.orig
diff --git a/mako/cmd.py b/mako/cmd.py
index 15c2737..acccbc3 100755
--- a/mako/cmd.py
+++ b/mako/cmd.py
@@ -3,64 +3,60 @@
#
# This module is part of Mako and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php
-
-def render(data, kw, lookup_dirs):
- from mako.template import Template
- from mako.lookup import TemplateLookup
-
- lookup = TemplateLookup(lookup_dirs)
- return Template(data, lookup=lookup).render(**kw)
+from argparse import ArgumentParser
+from os.path import isfile, dirname
+import sys
+from mako.template import Template
+from mako.lookup import TemplateLookup
+from mako import exceptions
def varsplit(var):
if "=" not in var:
return (var, "")
return var.split("=", 1)
-def cmdline(argv=None):
- import pdb; pdb.set_trace()
-
- from os.path import isfile, dirname
- from sys import stdin
-
- if argv is None:
- import sys
- argv = sys.argv
+def _exit():
+ sys.stderr.write(exceptions.text_error_template().render())
+ sys.exit(1)
- from optparse import OptionParser
+def cmdline(argv=None):
- parser = OptionParser("usage: %prog [FILENAME]")
- parser.add_option("--var", default=[], action="append",
+ parser = ArgumentParser("usage: %prog [FILENAME]")
+ parser.add_argument("--var", default=[], action="append",
help="variable (can be used multiple times, use name=value)")
- parser.add_option("--template-dir", default=[], action="append",
+ parser.add_argument("--template-dir", default=[], action="append",
help="Directory to use for template lookup (multiple "
- "directories may be provided). If not given then if the "
- "template is read from stdin, the value defaults to be "
- "the current directory, otherwise it defaults to be the "
- "parent directory of the file provided.")
-
- opts, args = parser.parse_args(argv[1:])
- if len(args) not in (0, 1):
- parser.error("wrong number of arguments") # Will exit
-
- if (len(args) == 0) or (args[0] == "-"):
- fo = stdin
- lookup_dirs = opts.template_dir or ["."]
+ "directories may be provided). If not given then if the "
+ "template is read from stdin, the value defaults to be "
+ "the current directory, otherwise it defaults to be the "
+ "parent directory of the file provided.")
+ parser.add_argument('input', nargs='?', default='-')
+
+ options = parser.parse_args(argv)
+ if options.input == '-':
+ lookup_dirs = options.template_dir or ["."]
+ lookup = TemplateLookup(lookup_dirs)
+ try:
+ template = Template(sys.stdin.read(), lookup=lookup)
+ except:
+ _exit()
else:
- filename = args[0]
+ filename = options.input
if not isfile(filename):
raise SystemExit("error: can't find %s" % filename)
- fo = open(filename)
- lookup_dirs = opts.template_dir or [dirname(filename)]
-
- kw = dict([varsplit(var) for var in opts.var])
- data = fo.read()
-
+ lookup_dirs = options.template_dir or [dirname(filename)]
+ lookup = TemplateLookup(lookup_dirs)
+ try:
+ template = Template(filename=filename, lookup=lookup)
+ except:
+ _exit()
+
+ kw = dict([varsplit(var) for var in options.var])
try:
- print(render(data, kw, lookup_dirs=lookup_dirs))
+ print(template.render(**kw))
except:
- from mako import exceptions
- print(exceptions.text_error_template().render(), file=sys.stderr)
- sys.exit(1)
+ _exit()
+
if __name__ == "__main__":
cmdline()
diff --git a/setup.py b/setup.py
index 55cf1c9..91b5769 100644
--- a/setup.py
+++ b/setup.py
@@ -18,6 +18,11 @@ if markupsafe_installs:
else:
install_requires = []
+try:
+ import argparse
+except ImportError:
+ install_requires.append('argparse')
+
setup(name='Mako',
version=VERSION,
description="A super-fast templating language that borrows the \
@@ -39,7 +44,7 @@ setup(name='Mako',
url='http://www.makotemplates.org/',
license='MIT',
packages=find_packages('.', exclude=['examples*', 'test*']),
- tests_require=['nose >= 0.11'],
+ tests_require=['nose >= 0.11', 'mock'],
test_suite="nose.collector",
zip_safe=False,
install_requires=install_requires,
diff --git a/test/__init__.py b/test/__init__.py
index 64dde8e..91ff54e 100644
--- a/test/__init__.py
+++ b/test/__init__.py
@@ -2,11 +2,12 @@ from mako.template import Template
import unittest
import os
from mako.compat import py3k, py26, py25
+from mako import compat
from mako.util import update_wrapper
import re
from mako.cache import CacheImpl, register_plugin
from nose import SkipTest
-import sys
+import contextlib
template_base = os.path.join(os.path.dirname(__file__), 'templates')
module_base = os.path.join(template_base, 'modules')
@@ -61,24 +62,29 @@ def teardown():
import shutil
shutil.rmtree(module_base, True)
-def assert_raises(except_cls, callable_, *args, **kw):
+@contextlib.contextmanager
+def raises(except_cls, message=None):
try:
- callable_(*args, **kw)
+ yield
success = False
- except except_cls:
+ except except_cls as e:
+ if message:
+ assert re.search(message, compat.text_type(e), re.UNICODE), \
+ "%r !~ %s" % (message, e)
+ print(compat.text_type(e).encode('utf-8'))
success = True
# assert outside the block so it works for AssertionError too !
assert success, "Callable did not raise an exception"
+
+def assert_raises(except_cls, callable_, *args, **kw):
+ with raises(except_cls):
+ return callable_(*args, **kw)
+
def assert_raises_message(except_cls, msg, callable_, *args, **kwargs):
- try:
- callable_(*args, **kwargs)
- assert False, "Callable did not raise an exception"
- except except_cls:
- e = sys.exc_info()[1]
- assert re.search(msg, str(e)), "%r !~ %s" % (msg, e)
- print(str(e))
+ with raises(except_cls, msg):
+ return callable_(*args, **kwargs)
def skip_if(predicate, reason=None):
"""Skip a test if predicate is true."""
diff --git a/test/templates/cmd_good.mako b/test/templates/cmd_good.mako
new file mode 100644
index 0000000..68ebec4
--- /dev/null
+++ b/test/templates/cmd_good.mako
@@ -0,0 +1 @@
+hello world ${x} \ No newline at end of file
diff --git a/test/templates/cmd_runtime.mako b/test/templates/cmd_runtime.mako
new file mode 100644
index 0000000..6c2675b
--- /dev/null
+++ b/test/templates/cmd_runtime.mako
@@ -0,0 +1 @@
+${q} \ No newline at end of file
diff --git a/test/templates/cmd_syntax.mako b/test/templates/cmd_syntax.mako
new file mode 100644
index 0000000..d2117db
--- /dev/null
+++ b/test/templates/cmd_syntax.mako
@@ -0,0 +1 @@
+${x \ No newline at end of file
diff --git a/test/test_cmd.py b/test/test_cmd.py
new file mode 100644
index 0000000..d7e07ae
--- /dev/null
+++ b/test/test_cmd.py
@@ -0,0 +1,73 @@
+from __future__ import with_statement
+from contextlib import contextmanager
+from test import TemplateTest, eq_, raises, template_base
+import os
+import mock
+from mako.cmd import cmdline
+
+class CmdTest(TemplateTest):
+ @contextmanager
+ def _capture_output_fixture(self, stream="stdout"):
+ with mock.patch("sys.%s" % stream) as stdout:
+ yield stdout
+
+ def test_stdin_success(self):
+ with self._capture_output_fixture() as stdout:
+ with mock.patch("sys.stdin", mock.Mock(
+ read=mock.Mock(return_value="hello world ${x}"))):
+ cmdline(["--var", "x=5", "-"])
+
+ eq_(stdout.write.mock_calls[0][1][0], "hello world 5")
+
+ def test_stdin_syntax_err(self):
+ with mock.patch("sys.stdin", mock.Mock(
+ read=mock.Mock(return_value="${x"))):
+ with self._capture_output_fixture("stderr") as stderr:
+ with raises(SystemExit):
+ cmdline(["--var", "x=5", "-"])
+
+ assert "SyntaxException: Expected" in \
+ stderr.write.mock_calls[0][1][0]
+ assert "Traceback" in stderr.write.mock_calls[0][1][0]
+
+
+ def test_stdin_rt_err(self):
+ with mock.patch("sys.stdin", mock.Mock(
+ read=mock.Mock(return_value="${q}"))):
+ with self._capture_output_fixture("stderr") as stderr:
+ with raises(SystemExit):
+ cmdline(["--var", "x=5", "-"])
+
+ assert "NameError: Undefined" in stderr.write.mock_calls[0][1][0]
+ assert "Traceback" in stderr.write.mock_calls[0][1][0]
+
+ def test_file_success(self):
+ with self._capture_output_fixture() as stdout:
+ cmdline(["--var", "x=5",
+ os.path.join(template_base, "cmd_good.mako")])
+
+ eq_(stdout.write.mock_calls[0][1][0], "hello world 5")
+
+ def test_file_syntax_err(self):
+ with self._capture_output_fixture("stderr") as stderr:
+ with raises(SystemExit):
+ cmdline(["--var", "x=5",
+ os.path.join(template_base, "cmd_syntax.mako")])
+
+ assert "SyntaxException: Expected" in stderr.write.mock_calls[0][1][0]
+ assert "Traceback" in stderr.write.mock_calls[0][1][0]
+
+ def test_file_rt_err(self):
+ with self._capture_output_fixture("stderr") as stderr:
+ with raises(SystemExit):
+ cmdline(["--var", "x=5",
+ os.path.join(template_base, "cmd_runtime.mako")])
+
+ assert "NameError: Undefined" in stderr.write.mock_calls[0][1][0]
+ assert "Traceback" in stderr.write.mock_calls[0][1][0]
+
+
+ def test_file_notfound(self):
+ with raises(SystemExit, "error: can't find fake.lalala"):
+ cmdline(["--var", "x=5", "fake.lalala"])
+