Permalink
Browse files

Started work on the testsuite

  • Loading branch information...
1 parent edb9d04 commit 0d8ec9c04705e210d213643b1ffb7cd4224bf467 @mitsuhiko committed Dec 4, 2011
@@ -1,15 +1,6 @@
-import os
import sys
-import templatetk
import jsonjinja
-
-
-runtime_js = [
- os.path.join(os.path.dirname(templatetk.__file__),
- 'res', 'templatetk.runtime.js'),
- os.path.join(os.path.dirname(jsonjinja.__file__),
- 'res', 'jsonjinja.runtime.js')
-]
+from jsonjinja.utils import get_runtime_javascript
env = jsonjinja.Environment(loader=jsonjinja.DictLoader({
@@ -38,9 +29,7 @@
print '<!doctype html>'
print '<script type=text/javascript src=jquery.js></script>'
print '<script type=text/javascript>'
-for filename in runtime_js:
- with open(filename) as f:
- print f.read()
+print get_runtime_javascript()
print 'jsonjinja.addTemplates('
env.compile_javascript_templates(stream=sys.stdout)
print ');'
View
@@ -13,6 +13,9 @@ def __init__(self, environment):
def environment(self):
return self._environment()
+ def get_autoescape_default(self, name):
+ return name.endswith(('.html', '.xml'))
+
def getattr(self, obj, attribute):
try:
return obj[attribute]
@@ -0,0 +1,146 @@
+# -*- coding: utf-8 -*-
+"""
+ jsonjinja.testsuite
+ ~~~~~~~~~~~~~~~~~~~
+
+ :copyright: (c) 2011 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+
+from __future__ import with_statement
+
+import unittest
+import pkgutil
+
+
+def iter_suites(package):
+ """Yields all testsuites."""
+ path = __import__(package, None, None, ['__path__']).__path__
+ for importer, modname, ispkg in pkgutil.iter_modules(path):
+ if not ispkg:
+ mod = __import__('jsonjinja.testsuite.' + modname, None, None, ['__file__'])
+ if hasattr(mod, 'suite'):
+ yield mod.suite()
+
+
+def find_all_tests(suite):
+ """Yields all the tests and their names from a given suite."""
+ suites = [suite]
+ while suites:
+ s = suites.pop()
+ try:
+ suites.extend(s)
+ except TypeError:
+ yield s, '%s.%s.%s' % (
+ s.__class__.__module__,
+ s.__class__.__name__,
+ s._testMethodName
+ )
+
+
+class JSONJinjaTestCase(unittest.TestCase):
+ """Baseclass for all the tests that JSON Jinja uses. Use these
+ methods for testing instead of the camelcased ones in the
+ baseclass for consistency.
+ """
+
+ def setup(self):
+ pass
+
+ def teardown(self):
+ pass
+
+ def setUp(self):
+ self.setup()
+
+ def tearDown(self):
+ unittest.TestCase.tearDown(self)
+ self.teardown()
+
+ def assert_equal(self, x, y):
+ return self.assertEqual(x, y)
+
+ def assert_not_equal(self, x, y):
+ return self.assertNotEqual(x, y)
+
+ def assert_raises(self, exc_type, callable=None, *args, **kwargs):
+ catcher = _ExceptionCatcher(self, exc_type)
+ if callable is None:
+ return catcher
+ with catcher:
+ callable(*args, **kwargs)
+
+
+class _ExceptionCatcher(object):
+
+ def __init__(self, test_case, exc_type):
+ self.test_case = test_case
+ self.exc_type = exc_type
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, tb):
+ exception_name = self.exc_type.__name__
+ if exc_type is None:
+ self.test_case.fail('Expected exception of type %r' %
+ exception_name)
+ elif not issubclass(exc_type, self.exc_type):
+ raise exc_type, exc_value, tb
+ return True
+
+
+class BetterLoader(unittest.TestLoader):
+ """A nicer loader that solves two problems. First of all we are setting
+ up tests from different sources and we're doing this programmatically
+ which breaks the default loading logic so this is required anyways.
+ Secondly this loader has a nicer interpolation for test names than the
+ default one so you can just do ``run-tests.py ViewTestCase`` and it
+ will work.
+ """
+
+ def getRootSuite(self):
+ return suite()
+
+ def loadTestsFromName(self, name, module=None):
+ root = self.getRootSuite()
+ if name == 'suite':
+ return root
+
+ all_tests = []
+ for testcase, testname in find_all_tests(root):
+ if testname == name or \
+ testname.endswith('.' + name) or \
+ ('.' + name + '.') in testname or \
+ testname.startswith(name + '.'):
+ all_tests.append(testcase)
+
+ if not all_tests:
+ raise LookupError('could not find test case for "%s"' % name)
+
+ if len(all_tests) == 1:
+ return all_tests[0]
+ rv = unittest.TestSuite()
+ for test in all_tests:
+ rv.addTest(test)
+ return rv
+
+
+def suite():
+ """A testsuite that has all the Flask tests. You can use this
+ function to integrate the Flask tests into your own testsuite
+ in case you want to test that monkeypatches to Flask do not
+ break it.
+ """
+ suite = unittest.TestSuite()
+ for other_suite in iter_suites(__name__):
+ suite.addTest(other_suite)
+ return suite
+
+
+def main():
+ """Runs the testsuite as command line application."""
+ try:
+ unittest.main(testLoader=BetterLoader(), defaultTest='suite')
+ except Exception, e:
+ print 'Error: %s' % e
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+"""
+ jsonjinja.testsuite.behavior
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ Basic behavior.
+
+ :copyright: (c) 2011 by Armin Ronacher.
+ :license: BSD, see LICENSE for more details.
+"""
+import os
+import unittest
+import subprocess
+import tempfile
+
+from jsonjinja.testsuite import JSONJinjaTestCase
+from jsonjinja.environment import Environment
+from jsonjinja.loaders import FileSystemLoader
+from jsonjinja.utils import get_runtime_javascript
+from templatetk.utils import json
+
+
+template_path = os.path.join(os.path.dirname(__file__), 'behavior')
+template_exts = ('.html', '.txt')
+env = Environment(loader=FileSystemLoader([template_path]))
+
+
+class BaseTestCase(JSONJinjaTestCase):
+
+ def run_behavior_test(self, template_filename):
+ base_filename = template_filename.rsplit('.', 1)[0]
+ with open(base_filename + '.json') as f:
+ context = json.load(f)
+ with open(base_filename + '.output') as f:
+ expected_output = f.read()
+ output = self.evaluate_template(os.path.basename(template_filename),
+ context)
+ self.assert_equal(expected_output, output)
+
+
+def make_behavior_testcase():
+ class BehaviorTestCase(BaseTestCase):
+ pass
+
+ def add_test(filename):
+ method = 'test_' + os.path.basename(filename.rsplit('.', 1)[0])
+ def test_method(self):
+ self.run_behavior_test(filename)
+ setattr(BehaviorTestCase, method, test_method)
+
+ for filename in os.listdir(template_path):
+ if filename.endswith(template_exts):
+ add_test(os.path.join(template_path, filename))
+
+ return BehaviorTestCase
+BehaviorTestCase = make_behavior_testcase()
+
+
+class PythonTestCase(BehaviorTestCase):
+
+ def evaluate_template(self, load_name, context):
+ tmpl = env.get_template(load_name)
+ return tmpl.render(context)
+
+
+class JavaScriptTestCase(BehaviorTestCase):
+
+ def dump_all_javascript(self, f):
+ def filter_func(filename):
+ return filename.endswith(template_exts)
+ f.write(get_runtime_javascript())
+ f.write('jsonjinja.addTemplates(')
+ env.compile_javascript_templates(filter_func=filter_func,
+ stream=f)
+ f.write(');\n')
+
+ def evaluate_template(self, load_name, context):
+ fd, filename = tempfile.mkstemp(text=True)
+ f = os.fdopen(fd, 'w')
+ try:
+ self.dump_all_javascript(f)
+ f.write('var tmpl = jsonjinja.getTemplate(%s);\n' %
+ json.dumps(load_name))
+ f.write('process.stdout.write(tmpl.render(%s));\n' %
+ (json.dumps(context)))
+ f.close()
+ c = subprocess.Popen(['node', filename], stdout=subprocess.PIPE)
+ stdout, stderr = c.communicate()
+ finally:
+ os.remove(filename)
+ return stdout
+
+
+def suite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(PythonTestCase))
+ suite.addTest(unittest.makeSuite(JavaScriptTestCase))
+ return suite
@@ -0,0 +1 @@
+{}
@@ -0,0 +1,8 @@
+
+* 1
+
+* 2
+
+* 3
+
+* 4
@@ -0,0 +1,3 @@
+{% for item in [1, 2, 3, 4] %}
+* {{ item }}
+{% endfor %}
@@ -0,0 +1 @@
+{"seq": ["a", "b", "c"]}
@@ -0,0 +1,6 @@
+
+0|1|a
+
+1|2|b
+
+2|3|c
@@ -0,0 +1,3 @@
+{% for item in seq %}
+{{ loop.index0 }}|{{ loop.index }}|{{ item }}
+{% endfor %}
View
@@ -1,7 +1,25 @@
+import os
import errno
from jsonjinja.exceptions import NotJSONCompatibleException
+def get_runtime_javascript():
+ import templatetk
+ import jsonjinja
+ runtime_js = [
+ os.path.join(os.path.dirname(templatetk.__file__),
+ 'res', 'templatetk.runtime.js'),
+ os.path.join(os.path.dirname(jsonjinja.__file__),
+ 'res', 'jsonjinja.runtime.js')
+ ]
+
+ rv = []
+ for filename in runtime_js:
+ with open(filename) as f:
+ rv.append(f.read())
+ return ''.join(rv)
+
+
def ensure_json_compatible(obj):
if obj is None:
return True
View
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+from jsonjinja.testsuite import main
+main()

0 comments on commit 0d8ec9c

Please sign in to comment.