diff options
author | Michael Bourke <michael@iter8ve.com> | 2022-01-09 16:38:12 +1100 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2022-01-14 09:57:14 -0500 |
commit | 7e52b60b7dac75a3c7177e69244123c0dad9e9d9 (patch) | |
tree | 2df96da5716169b2351f442c272a39ed6940332f /test | |
parent | 3c3196754b55b48c044e59a5beacb9a13bc25114 (diff) | |
download | mako-7e52b60b7dac75a3c7177e69244123c0dad9e9d9.tar.gz |
Refactor test.util into mako.testing
Fixes: #349
Change-Id: I202c252a913fb72cc328a6e7f0f33174802487d3
Diffstat (limited to 'test')
31 files changed, 436 insertions, 651 deletions
diff --git a/test/ext/test_babelplugin.py b/test/ext/test_babelplugin.py index be3c37a..de3e461 100644 --- a/test/ext/test_babelplugin.py +++ b/test/ext/test_babelplugin.py @@ -1,39 +1,25 @@ import io import os -import unittest -from ..util.exclusions import skip_if -from ..util.fixtures import template_base -from ..util.fixtures import TemplateTest +from mako.ext.babelplugin import extract +from mako.testing.assertions import eq_ +from mako.testing.config import config +from mako.testing.exclusions import requires_babel +from mako.testing.fixtures import TemplateTest -try: - import babel.messages.extract as babel - from mako.ext.babelplugin import extract -except ImportError: - babel = None - - -def skip(): - return skip_if( - lambda: not babel, "babel not installed: skipping babelplugin test" - ) - - -class Test_extract(unittest.TestCase): - @skip() +@requires_babel +class PluginExtractTest: def test_parse_python_expression(self): input_ = io.BytesIO(b'<p>${_("Message")}</p>') messages = list(extract(input_, ["_"], [], {})) - self.assertEqual(messages, [(1, "_", ("Message"), [])]) + eq_(messages, [(1, "_", ("Message"), [])]) - @skip() def test_python_gettext_call(self): input_ = io.BytesIO(b'<p>${_("Message")}</p>') messages = list(extract(input_, ["_"], [], {})) - self.assertEqual(messages, [(1, "_", ("Message"), [])]) + eq_(messages, [(1, "_", ("Message"), [])]) - @skip() def test_translator_comment(self): input_ = io.BytesIO( b""" @@ -43,7 +29,7 @@ class Test_extract(unittest.TestCase): </p>""" ) messages = list(extract(input_, ["_"], ["TRANSLATORS:"], {})) - self.assertEqual( + eq_( messages, [ ( @@ -56,65 +42,62 @@ class Test_extract(unittest.TestCase): ) -class ExtractMakoTestCase(TemplateTest): - @skip() +@requires_babel +class MakoExtractTest(TemplateTest): def test_extract(self): - mako_tmpl = open(os.path.join(template_base, "gettext.mako")) - self.addCleanup(mako_tmpl.close) - messages = list( - extract( - mako_tmpl, - {"_": None, "gettext": None, "ungettext": (1, 2)}, - ["TRANSLATOR:"], - {}, + with open( + os.path.join(config.template_base, "gettext.mako") + ) as mako_tmpl: + messages = list( + extract( + mako_tmpl, + {"_": None, "gettext": None, "ungettext": (1, 2)}, + ["TRANSLATOR:"], + {}, + ) ) - ) - expected = [ - (1, "_", "Page arg 1", []), - (1, "_", "Page arg 2", []), - (10, "gettext", "Begin", []), - (14, "_", "Hi there!", ["TRANSLATOR: Hi there!"]), - (19, "_", "Hello", []), - (22, "_", "Welcome", []), - (25, "_", "Yo", []), - (36, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]), - (36, "ungettext", ("bunny", "bunnies", None), []), - (41, "_", "Goodbye", ["TRANSLATOR: Good bye"]), - (44, "_", "Babel", []), - (45, "ungettext", ("hella", "hellas", None), []), - (62, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]), - (62, "ungettext", ("bunny", "bunnies", None), []), - (68, "_", "Goodbye, really!", ["TRANSLATOR: HTML comment"]), - (71, "_", "P.S. byebye", []), - (77, "_", "Top", []), - (83, "_", "foo", []), - (83, "_", "hoho", []), - (85, "_", "bar", []), - (92, "_", "Inside a p tag", ["TRANSLATOR: <p> tag is ok?"]), - (95, "_", "Later in a p tag", ["TRANSLATOR: also this"]), - (99, "_", "No action at a distance.", []), - ] - self.assertEqual(expected, messages) + expected = [ + (1, "_", "Page arg 1", []), + (1, "_", "Page arg 2", []), + (10, "gettext", "Begin", []), + (14, "_", "Hi there!", ["TRANSLATOR: Hi there!"]), + (19, "_", "Hello", []), + (22, "_", "Welcome", []), + (25, "_", "Yo", []), + (36, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]), + (36, "ungettext", ("bunny", "bunnies", None), []), + (41, "_", "Goodbye", ["TRANSLATOR: Good bye"]), + (44, "_", "Babel", []), + (45, "ungettext", ("hella", "hellas", None), []), + (62, "_", "The", ["TRANSLATOR: Ensure so and", "so, thanks"]), + (62, "ungettext", ("bunny", "bunnies", None), []), + (68, "_", "Goodbye, really!", ["TRANSLATOR: HTML comment"]), + (71, "_", "P.S. byebye", []), + (77, "_", "Top", []), + (83, "_", "foo", []), + (83, "_", "hoho", []), + (85, "_", "bar", []), + (92, "_", "Inside a p tag", ["TRANSLATOR: <p> tag is ok?"]), + (95, "_", "Later in a p tag", ["TRANSLATOR: also this"]), + (99, "_", "No action at a distance.", []), + ] + eq_(expected, messages) - @skip() def test_extract_utf8(self): - mako_tmpl = open( - os.path.join(template_base, "gettext_utf8.mako"), "rb" - ) - self.addCleanup(mako_tmpl.close) - message = next( - extract(mako_tmpl, {"_", None}, [], {"encoding": "utf-8"}) - ) - assert message == (1, "_", "K\xf6ln", []) + with open( + os.path.join(config.template_base, "gettext_utf8.mako"), "rb" + ) as mako_tmpl: + message = next( + extract(mako_tmpl, {"_", None}, [], {"encoding": "utf-8"}) + ) + assert message == (1, "_", "K\xf6ln", []) - @skip() def test_extract_cp1251(self): - mako_tmpl = open( - os.path.join(template_base, "gettext_cp1251.mako"), "rb" - ) - self.addCleanup(mako_tmpl.close) - message = next( - extract(mako_tmpl, {"_", None}, [], {"encoding": "cp1251"}) - ) - # "test" in Rusian. File encoding is cp1251 (aka "windows-1251") - assert message == (1, "_", "\u0442\u0435\u0441\u0442", []) + with open( + os.path.join(config.template_base, "gettext_cp1251.mako"), "rb" + ) as mako_tmpl: + message = next( + extract(mako_tmpl, {"_", None}, [], {"encoding": "cp1251"}) + ) + # "test" in Rusian. File encoding is cp1251 (aka "windows-1251") + assert message == (1, "_", "\u0442\u0435\u0441\u0442", []) diff --git a/test/ext/test_linguaplugin.py b/test/ext/test_linguaplugin.py index fa5f76d..ae24f67 100644 --- a/test/ext/test_linguaplugin.py +++ b/test/ext/test_linguaplugin.py @@ -1,17 +1,12 @@ import os -from ..util.exclusions import skip_if -from ..util.fixtures import template_base -from ..util.fixtures import TemplateTest +import pytest -try: - import lingua -except: - lingua = None - -if lingua is not None: - from mako.ext.linguaplugin import LinguaMakoExtractor - from lingua.extractors import register_extractors +from mako.ext.linguaplugin import LinguaMakoExtractor +from mako.testing.assertions import eq_ +from mako.testing.config import config +from mako.testing.exclusions import requires_lingua +from mako.testing.fixtures import TemplateTest class MockOptions: @@ -20,22 +15,24 @@ class MockOptions: comment_tag = True -def skip(): - return skip_if( - lambda: not lingua, "lingua not installed: skipping linguaplugin test" - ) +@requires_lingua +class MakoExtractTest(TemplateTest): + @pytest.fixture(autouse=True) + def register_lingua_extractors(self): + from lingua.extractors import register_extractors + register_extractors() -class ExtractMakoTestCase(TemplateTest): - @skip() def test_extract(self): - register_extractors() plugin = LinguaMakoExtractor({"comment-tags": "TRANSLATOR"}) messages = list( - plugin(os.path.join(template_base, "gettext.mako"), MockOptions()) + plugin( + os.path.join(config.template_base, "gettext.mako"), + MockOptions(), + ) ) msgids = [(m.msgid, m.msgid_plural) for m in messages] - self.assertEqual( + eq_( msgids, [ ("Page arg 1", None), diff --git a/test/templates/foo/modtest.html.py b/test/templates/foo/modtest.html.py index 7a73e55..c35420f 100644 --- a/test/templates/foo/modtest.html.py +++ b/test/templates/foo/modtest.html.py @@ -1,4 +1,5 @@ -from mako import runtime, filters, cache +from mako import cache +from mako import runtime UNDEFINED = runtime.UNDEFINED __M_dict_builtin = dict diff --git a/test/templates/subdir/foo/modtest.html.py b/test/templates/subdir/foo/modtest.html.py index 8b3a73b..9df72e0 100644 --- a/test/templates/subdir/foo/modtest.html.py +++ b/test/templates/subdir/foo/modtest.html.py @@ -1,4 +1,5 @@ -from mako import runtime, filters, cache +from mako import cache +from mako import runtime UNDEFINED = runtime.UNDEFINED __M_dict_builtin = dict diff --git a/test/test_ast.py b/test/test_ast.py index 29a8a36..6b3a3e2 100644 --- a/test/test_ast.py +++ b/test/test_ast.py @@ -1,14 +1,13 @@ -import unittest - from mako import ast from mako import exceptions from mako import pyparser -from .util.assertions import eq_ +from mako.testing.assertions import assert_raises +from mako.testing.assertions import eq_ exception_kwargs = {"source": "", "lineno": 0, "pos": 0, "filename": ""} -class AstParseTest(unittest.TestCase): +class AstParseTest: def test_locate_identifiers(self): """test the location of identifiers in a python code string""" code = """ @@ -228,7 +227,7 @@ except (Foo, Bar) as e: from foo import * import x as bar """ - self.assertRaises( + assert_raises( exceptions.CompileException, ast.PythonCode, code, diff --git a/test/test_block.py b/test/test_block.py index a55ca89..be2fbf7 100644 --- a/test/test_block.py +++ b/test/test_block.py @@ -1,9 +1,9 @@ from mako import exceptions from mako.lookup import TemplateLookup from mako.template import Template -from .util.assertions import assert_raises_message -from .util.fixtures import TemplateTest -from .util.helpers import result_lines +from mako.testing.assertions import assert_raises_message +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import result_lines class BlockTest(TemplateTest): diff --git a/test/test_cache.py b/test/test_cache.py index 60785f2..dd415d4 100644 --- a/test/test_cache.py +++ b/test/test_cache.py @@ -1,19 +1,18 @@ import time -import unittest from mako import lookup from mako.cache import CacheImpl from mako.cache import register_plugin -from mako.ext import beaker_cache from mako.lookup import TemplateLookup from mako.template import Template -from .util.assertions import eq_ -from .util.fixtures import module_base -from .util.fixtures import TemplateTest -from .util.helpers import result_lines +from mako.testing.assertions import eq_ +from mako.testing.config import config +from mako.testing.exclusions import requires_beaker +from mako.testing.exclusions import requires_dogpile_cache +from mako.testing.helpers import result_lines -if beaker_cache.has_beaker: - import beaker + +module_base = str(config.module_base) class SimpleBackend: @@ -32,9 +31,9 @@ class SimpleBackend: def get_or_create(self, key, creation_function, **kw): if key in self.cache: return self.cache[key] - else: - self.cache[key] = value = creation_function() - return value + + self.cache[key] = value = creation_function() + return value class MockCacheImpl(CacheImpl): @@ -80,7 +79,7 @@ class MockCacheImpl(CacheImpl): register_plugin("mock", __name__, "MockCacheImpl") -class CacheTest(TemplateTest): +class CacheTest: real_backend = "simple" @@ -600,7 +599,7 @@ class CacheTest(TemplateTest): assert m.kwargs["context"].get("x") == "bar" -class RealBackendTest: +class RealBackendMixin: def test_cache_uses_current_context(self): t = Template( """ @@ -643,19 +642,17 @@ class RealBackendTest: eq_(r3, ["short term 6", "long term 5", "none 7"]) -class BeakerCacheTest(RealBackendTest, CacheTest): +@requires_beaker +class BeakerCacheTest(RealBackendMixin, CacheTest): real_backend = "beaker" - def setUp(self): - if not beaker_cache.has_beaker: - raise unittest.SkipTest("Beaker is required for these tests.") - def _install_mock_cache(self, template, implname=None): template.cache_args["manager"] = self._regions() - impl = super()._install_mock_cache(template, implname) - return impl + return super()._install_mock_cache(template, implname) def _regions(self): + import beaker + return beaker.cache.CacheManager( cache_regions={ "short": {"expire": 1, "type": "memory"}, @@ -664,22 +661,14 @@ class BeakerCacheTest(RealBackendTest, CacheTest): ) -class DogpileCacheTest(RealBackendTest, CacheTest): +@requires_dogpile_cache +class DogpileCacheTest(RealBackendMixin, CacheTest): real_backend = "dogpile.cache" - def setUp(self): - try: - import dogpile.cache # noqa - except ImportError: - raise unittest.SkipTest( - "dogpile.cache is required to run these tests" - ) - def _install_mock_cache(self, template, implname=None): template.cache_args["regions"] = self._regions() template.cache_args.setdefault("region", "short") - impl = super()._install_mock_cache(template, implname) - return impl + return super()._install_mock_cache(template, implname) def _regions(self): from dogpile.cache import make_region diff --git a/test/test_call.py b/test/test_call.py index 82d48da..4dea2b3 100644 --- a/test/test_call.py +++ b/test/test_call.py @@ -1,8 +1,8 @@ from mako.template import Template -from .util.assertions import eq_ -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result -from .util.helpers import result_lines +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines class CallTest(TemplateTest): diff --git a/test/test_cmd.py b/test/test_cmd.py index 2347452..785c652 100644 --- a/test/test_cmd.py +++ b/test/test_cmd.py @@ -3,11 +3,11 @@ import os from unittest import mock from mako.cmd import cmdline -from .util.assertions import eq_ -from .util.assertions import expect_raises -from .util.assertions import expect_raises_message -from .util.fixtures import template_base -from .util.fixtures import TemplateTest +from mako.testing.assertions import eq_ +from mako.testing.assertions import expect_raises +from mako.testing.assertions import expect_raises_message +from mako.testing.config import config +from mako.testing.fixtures import TemplateTest class CmdTest(TemplateTest): @@ -53,7 +53,11 @@ class CmdTest(TemplateTest): def test_file_success(self): with self._capture_output_fixture() as stdout: cmdline( - ["--var", "x=5", os.path.join(template_base, "cmd_good.mako")] + [ + "--var", + "x=5", + os.path.join(config.template_base, "cmd_good.mako"), + ] ) eq_(stdout.write.mock_calls[0][1][0], "hello world 5") @@ -65,7 +69,7 @@ class CmdTest(TemplateTest): [ "--var", "x=5", - os.path.join(template_base, "cmd_syntax.mako"), + os.path.join(config.template_base, "cmd_syntax.mako"), ] ) @@ -79,7 +83,7 @@ class CmdTest(TemplateTest): [ "--var", "x=5", - os.path.join(template_base, "cmd_runtime.mako"), + os.path.join(config.template_base, "cmd_runtime.mako"), ] ) diff --git a/test/test_decorators.py b/test/test_decorators.py index 6153371..68ea903 100644 --- a/test/test_decorators.py +++ b/test/test_decorators.py @@ -1,10 +1,8 @@ -import unittest - from mako.template import Template -from .util.helpers import flatten_result +from mako.testing.helpers import flatten_result -class DecoratorTest(unittest.TestCase): +class DecoratorTest: def test_toplevel(self): template = Template( """ diff --git a/test/test_def.py b/test/test_def.py index 5f99192..fd96433 100644 --- a/test/test_def.py +++ b/test/test_def.py @@ -1,10 +1,10 @@ from mako import lookup from mako.template import Template -from .util.assertions import assert_raises -from .util.assertions import eq_ -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result -from .util.helpers import result_lines +from mako.testing.assertions import assert_raises +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines class DefTest(TemplateTest): diff --git a/test/test_exceptions.py b/test/test_exceptions.py index a2b8cf9..b1930c5 100644 --- a/test/test_exceptions.py +++ b/test/test_exceptions.py @@ -3,10 +3,10 @@ import sys from mako import exceptions from mako.lookup import TemplateLookup from mako.template import Template -from .util.exclusions import requires_no_pygments_exceptions -from .util.exclusions import requires_pygments_14 -from .util.fixtures import TemplateTest -from .util.helpers import result_lines +from mako.testing.exclusions import requires_no_pygments_exceptions +from mako.testing.exclusions import requires_pygments_14 +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import result_lines class ExceptionsTest(TemplateTest): diff --git a/test/test_filters.py b/test/test_filters.py index b3b4753..726f5d7 100644 --- a/test/test_filters.py +++ b/test/test_filters.py @@ -1,10 +1,8 @@ -import unittest - from mako.template import Template -from .util.assertions import eq_ -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result -from .util.helpers import result_lines +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines class FilterTest(TemplateTest): @@ -363,7 +361,7 @@ data = {a: ${123}, b: ${"123"}}; ) -class BufferTest(unittest.TestCase): +class BufferTest: def test_buffered_def(self): t = Template( """ diff --git a/test/test_inheritance.py b/test/test_inheritance.py index 7824241..15bd54b 100644 --- a/test/test_inheritance.py +++ b/test/test_inheritance.py @@ -1,10 +1,8 @@ -import unittest - from mako import lookup -from .util.helpers import result_lines +from mako.testing.helpers import result_lines -class InheritanceTest(unittest.TestCase): +class InheritanceTest: def test_basic(self): collection = lookup.TemplateLookup() diff --git a/test/test_lexer.py b/test/test_lexer.py index 43b1e7a..255c128 100644 --- a/test/test_lexer.py +++ b/test/test_lexer.py @@ -6,10 +6,11 @@ from mako import parsetree from mako import util from mako.lexer import Lexer from mako.template import Template -from .util.assertions import assert_raises_message -from .util.assertions import eq_ -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result +from mako.testing.assertions import assert_raises +from mako.testing.assertions import assert_raises_message +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result # create fake parsetree classes which are constructed # exactly as the repr() of a real parsetree object. @@ -137,13 +138,13 @@ class LexerTest(TemplateTest): hi. """ - self.assertRaises(exceptions.SyntaxException, Lexer(template).parse) + assert_raises(exceptions.SyntaxException, Lexer(template).parse) def test_noexpr_allowed(self): template = """ <%namespace name="${foo}"/> """ - self.assertRaises(exceptions.CompileException, Lexer(template).parse) + assert_raises(exceptions.CompileException, Lexer(template).parse) def test_unmatched_tag(self): template = """ @@ -156,13 +157,13 @@ class LexerTest(TemplateTest): hi. """ - self.assertRaises(exceptions.SyntaxException, Lexer(template).parse) + assert_raises(exceptions.SyntaxException, Lexer(template).parse) def test_nonexistent_tag(self): template = """ <%lala x="5"/> """ - self.assertRaises(exceptions.CompileException, Lexer(template).parse) + assert_raises(exceptions.CompileException, Lexer(template).parse) def test_wrongcase_tag(self): template = """ @@ -170,7 +171,7 @@ class LexerTest(TemplateTest): </%def> """ - self.assertRaises(exceptions.CompileException, Lexer(template).parse) + assert_raises(exceptions.CompileException, Lexer(template).parse) def test_percent_escape(self): template = """ @@ -273,7 +274,7 @@ class LexerTest(TemplateTest): hi </%def> """ - self.assertRaises(exceptions.CompileException, Lexer(template).parse) + assert_raises(exceptions.CompileException, Lexer(template).parse) def test_def_syntax_2(self): template = """ @@ -281,7 +282,7 @@ class LexerTest(TemplateTest): hi </%def> """ - self.assertRaises(exceptions.CompileException, Lexer(template).parse) + assert_raises(exceptions.CompileException, Lexer(template).parse) def test_whitespace_equals(self): template = """ diff --git a/test/test_lookup.py b/test/test_lookup.py index eebb97b..6a797d7 100644 --- a/test/test_lookup.py +++ b/test/test_lookup.py @@ -1,24 +1,23 @@ import os import tempfile -import unittest from mako import exceptions from mako import lookup from mako import runtime from mako.template import Template +from mako.testing.assertions import assert_raises_message +from mako.testing.assertions import assert_raises_with_given_cause +from mako.testing.config import config +from mako.testing.helpers import file_with_template_code +from mako.testing.helpers import replace_file_with_dir +from mako.testing.helpers import result_lines +from mako.testing.helpers import rewind_compile_time from mako.util import FastEncodingBuffer -from .util.assertions import assert_raises_message -from .util.assertions import assert_raises_with_given_cause -from .util.fixtures import template_base -from .util.helpers import file_with_template_code -from .util.helpers import replace_file_with_dir -from .util.helpers import result_lines -from .util.helpers import rewind_compile_time -tl = lookup.TemplateLookup(directories=[template_base]) +tl = lookup.TemplateLookup(directories=[config.template_base]) -class LookupTest(unittest.TestCase): +class LookupTest: def test_basic(self): t = tl.get_template("index.html") assert result_lines(t.render()) == ["this is index"] @@ -98,7 +97,7 @@ class LookupTest(unittest.TestCase): """test the mechanics of an include where the include goes outside of the path""" tl = lookup.TemplateLookup( - directories=[os.path.join(template_base, "subdir")] + directories=[os.path.join(config.template_base, "subdir")] ) index = tl.get_template("index.html") diff --git a/test/test_loop.py b/test/test_loop.py index be7d440..19d40b5 100644 --- a/test/test_loop.py +++ b/test/test_loop.py @@ -1,5 +1,4 @@ import re -import unittest from mako import exceptions from mako.codegen import _FOR_LOOP @@ -7,12 +6,12 @@ from mako.lookup import TemplateLookup from mako.runtime import LoopContext from mako.runtime import LoopStack from mako.template import Template -from .util.assertions import assert_raises_message -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result +from mako.testing.assertions import assert_raises_message +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result -class TestLoop(unittest.TestCase): +class TestLoop: def test__FOR_LOOP(self): for statement, target_list, expression_list in ( ("for x in y:", "x", "y"), @@ -137,7 +136,7 @@ ${x} ${loop.index} <- outer loop ) -class TestLoopStack(unittest.TestCase): +class TestLoopStack: def setUp(self): self.stack = LoopStack() self.bottom = "spam" @@ -180,7 +179,7 @@ class TestLoopStack(unittest.TestCase): assert before == (after + 1), "Exiting a context pops the stack" -class TestLoopContext(unittest.TestCase): +class TestLoopContext: def setUp(self): self.iterable = [1, 2, 3] self.ctx = LoopContext(self.iterable) diff --git a/test/test_lru.py b/test/test_lru.py index 7281537..f54bd15 100644 --- a/test/test_lru.py +++ b/test/test_lru.py @@ -1,5 +1,3 @@ -import unittest - from mako.util import LRUCache @@ -11,7 +9,7 @@ class item: return "item id %d" % self.id -class LRUTest(unittest.TestCase): +class LRUTest: def testlru(self): l = LRUCache(10, threshold=0.2) diff --git a/test/test_namespace.py b/test/test_namespace.py index bdd1641..b6b0544 100644 --- a/test/test_namespace.py +++ b/test/test_namespace.py @@ -1,11 +1,12 @@ from mako import exceptions from mako import lookup from mako.template import Template -from .util.assertions import assert_raises_message_with_given_cause -from .util.assertions import eq_ -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result -from .util.helpers import result_lines +from mako.testing.assertions import assert_raises +from mako.testing.assertions import assert_raises_message_with_given_cause +from mako.testing.assertions import eq_ +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines class NamespaceTest(TemplateTest): @@ -586,7 +587,7 @@ class NamespaceTest(TemplateTest): """, ) - self.assertRaises(AttributeError, l.get_template("bar.html").render) + assert_raises(AttributeError, l.get_template("bar.html").render) def test_custom_tag_1(self): template = Template( diff --git a/test/test_pygen.py b/test/test_pygen.py index 5200e3e..8adc142 100644 --- a/test/test_pygen.py +++ b/test/test_pygen.py @@ -1,12 +1,11 @@ from io import StringIO -import unittest from mako.pygen import adjust_whitespace from mako.pygen import PythonPrinter -from .util.assertions import eq_ +from mako.testing.assertions import eq_ -class GeneratePythonTest(unittest.TestCase): +class GeneratePythonTest: def test_generate_normal(self): stream = StringIO() printer = PythonPrinter(stream) @@ -165,7 +164,7 @@ print "more indent" ) -class WhitespaceTest(unittest.TestCase): +class WhitespaceTest: def test_basic(self): text = """ for x in range(0,15): diff --git a/test/test_runtime.py b/test/test_runtime.py index 07802f9..0d6fce3 100644 --- a/test/test_runtime.py +++ b/test/test_runtime.py @@ -1,12 +1,10 @@ """Assorted runtime unit tests """ -import unittest - from mako import runtime -from .util.assertions import eq_ +from mako.testing.assertions import eq_ -class ContextTest(unittest.TestCase): +class ContextTest: def test_locals_kwargs(self): c = runtime.Context(None, foo="bar") eq_(c.kwargs, {"foo": "bar"}) diff --git a/test/test_template.py b/test/test_template.py index 238b8c6..fc1aeca 100644 --- a/test/test_template.py +++ b/test/test_template.py @@ -1,5 +1,4 @@ import os -import unittest from mako import exceptions from mako import runtime @@ -9,14 +8,13 @@ from mako.lookup import TemplateLookup from mako.template import ModuleInfo from mako.template import ModuleTemplate from mako.template import Template -from .util.assertions import assert_raises -from .util.assertions import assert_raises_message -from .util.assertions import eq_ -from .util.fixtures import module_base -from .util.fixtures import template_base -from .util.fixtures import TemplateTest -from .util.helpers import flatten_result -from .util.helpers import result_lines +from mako.testing.assertions import assert_raises +from mako.testing.assertions import assert_raises_message +from mako.testing.assertions import eq_ +from mako.testing.config import config +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import flatten_result +from mako.testing.helpers import result_lines class ctx: @@ -136,7 +134,7 @@ class EncodingTest(TemplateTest): def test_unicode_file_lookup(self): lookup = TemplateLookup( - directories=[template_base], + directories=[config.template_base], output_encoding="utf-8", default_filters=["decode.utf8"], ) @@ -165,11 +163,11 @@ class EncodingTest(TemplateTest): ), ) - self.assertRaises( + assert_raises( exceptions.CompileException, Template, filename=self._file_path("badbom.html"), - module_directory=module_base, + module_directory=config.module_base, ) def test_unicode_memory(self): @@ -399,7 +397,7 @@ quand une drôle de petite voix m’a réveillé. Elle disait: def test_read_unicode(self): lookup = TemplateLookup( - directories=[template_base], + directories=[config.template_base], filesystem_checks=True, output_encoding="utf-8", ) @@ -1228,40 +1226,47 @@ for utf8 in (True, False): class ModuleDirTest(TemplateTest): - def tearDown(self): + def teardown_method(self): import shutil - shutil.rmtree(module_base, True) + shutil.rmtree(config.module_base, True) def test_basic(self): t = self._file_template("modtest.html") t2 = self._file_template("subdir/modtest.html") - eq_(t.module.__file__, os.path.join(module_base, "modtest.html.py")) + eq_( + t.module.__file__, + os.path.join(config.module_base, "modtest.html.py"), + ) eq_( t2.module.__file__, - os.path.join(module_base, "subdir", "modtest.html.py"), + os.path.join(config.module_base, "subdir", "modtest.html.py"), ) def test_callable(self): def get_modname(filename, uri): return os.path.join( - module_base, + config.module_base, os.path.dirname(uri)[1:], "foo", os.path.basename(filename) + ".py", ) - lookup = TemplateLookup(template_base, modulename_callable=get_modname) + lookup = TemplateLookup( + config.template_base, modulename_callable=get_modname + ) t = lookup.get_template("/modtest.html") t2 = lookup.get_template("/subdir/modtest.html") eq_( t.module.__file__, - os.path.join(module_base, "foo", "modtest.html.py"), + os.path.join(config.module_base, "foo", "modtest.html.py"), ) eq_( t2.module.__file__, - os.path.join(module_base, "subdir", "foo", "modtest.html.py"), + os.path.join( + config.module_base, "subdir", "foo", "modtest.html.py" + ), ) def test_custom_writer(self): @@ -1274,17 +1279,17 @@ class ModuleDirTest(TemplateTest): f.close() lookup = TemplateLookup( - template_base, + config.template_base, module_writer=write_module, - module_directory=module_base, + module_directory=config.module_base, ) lookup.get_template("/modtest.html") lookup.get_template("/subdir/modtest.html") eq_( canary, [ - os.path.join(module_base, "modtest.html.py"), - os.path.join(module_base, "subdir", "modtest.html.py"), + os.path.join(config.module_base, "modtest.html.py"), + os.path.join(config.module_base, "subdir", "modtest.html.py"), ], ) @@ -1438,7 +1443,7 @@ class ModuleTemplateTest(TemplateTest): ] -class TestTemplateAPI(unittest.TestCase): +class TestTemplateAPI: def test_metadata(self): t = Template( """ diff --git a/test/test_tgplugin.py b/test/test_tgplugin.py index 9d5799b..38998c2 100644 --- a/test/test_tgplugin.py +++ b/test/test_tgplugin.py @@ -1,9 +1,11 @@ from mako.ext.turbogears import TGPlugin -from .util.fixtures import template_base -from .util.fixtures import TemplateTest -from .util.helpers import result_lines +from mako.testing.config import config +from mako.testing.fixtures import TemplateTest +from mako.testing.helpers import result_lines -tl = TGPlugin(options=dict(directories=[template_base]), extension="html") +tl = TGPlugin( + options=dict(directories=[config.template_base]), extension="html" +) class TestTGPlugin(TemplateTest): diff --git a/test/test_util.py b/test/test_util.py index 6aa4c47..95c1cb4 100644 --- a/test/test_util.py +++ b/test/test_util.py @@ -1,16 +1,19 @@ import os import sys -import unittest + +import pytest from mako import compat from mako import exceptions from mako import util -from .util.assertions import assert_raises_message -from .util.assertions import eq_ -from .util.exclusions import skip_if +from mako.testing.assertions import assert_raises_message +from mako.testing.assertions import eq_ +from mako.testing.assertions import in_ +from mako.testing.assertions import ne_ +from mako.testing.assertions import not_in -class UtilTest(unittest.TestCase): +class UtilTest: def test_fast_buffer_write(self): buf = util.FastEncodingBuffer() buf.write("string a ") @@ -38,16 +41,16 @@ class UtilTest(unittest.TestCase): data = util.read_file(fn, "rb") assert b"test_util" in data - @skip_if(lambda: compat.pypy, "Pypy does this differently") + @pytest.mark.skipif(compat.pypy, reason="Pypy does this differently") def test_load_module(self): path = os.path.join(os.path.dirname(__file__), "module_to_import.py") some_module = compat.load_module("test.module_to_import", path) - self.assertNotIn("test.module_to_import", sys.modules) - self.assertIn("some_function", dir(some_module)) + not_in("test.module_to_import", sys.modules) + in_("some_function", dir(some_module)) import test.module_to_import - self.assertNotEqual(some_module, test.module_to_import) + ne_(some_module, test.module_to_import) def test_load_plugin_failure(self): loader = util.PluginLoader("fakegroup") diff --git a/test/testing/dummy.cfg b/test/testing/dummy.cfg new file mode 100644 index 0000000..39644a3 --- /dev/null +++ b/test/testing/dummy.cfg @@ -0,0 +1,25 @@ +[boolean_values] +yes = yes +one = 1 +true = true +on = on +no = no +zero = 0 +false = false +off = off + +[additional_types] +decimal_value = 100001.01 +datetime_value = 2021-12-04 00:05:23.283 + +[type_mismatch] +int_value = foo + +[missing_item] +present_item = HERE + +[basic_values] +int_value = 15421 +bool_value = true +float_value = 14.01 +str_value = Ceci n'est pas une chaîne diff --git a/test/testing/test_config.py b/test/testing/test_config.py new file mode 100644 index 0000000..680d7a4 --- /dev/null +++ b/test/testing/test_config.py @@ -0,0 +1,176 @@ +import configparser +from dataclasses import dataclass +from datetime import datetime +from decimal import Decimal +from pathlib import Path + +import pytest + +from mako.testing._config import ConfigValueTypeError +from mako.testing._config import MissingConfig +from mako.testing._config import MissingConfigItem +from mako.testing._config import MissingConfigSection +from mako.testing._config import ReadsCfg +from mako.testing.assertions import assert_raises_message_with_given_cause +from mako.testing.assertions import assert_raises_with_given_cause + +PATH_TO_TEST_CONFIG = Path(__file__).parent / "dummy.cfg" + + +@dataclass +class BasicConfig(ReadsCfg): + int_value: int + bool_value: bool + float_value: float + str_value: str + + section_header = "basic_values" + + +@dataclass +class BooleanConfig(ReadsCfg): + yes: bool + one: bool + true: bool + on: bool + no: bool + zero: bool + false: bool + off: bool + + section_header = "boolean_values" + + +@dataclass +class UnsupportedTypesConfig(ReadsCfg): + decimal_value: Decimal + datetime_value: datetime + + section_header = "additional_types" + + +@dataclass +class SupportedTypesConfig(ReadsCfg): + decimal_value: Decimal + datetime_value: datetime + + section_header = "additional_types" + converters = { + Decimal: lambda v: Decimal(str(v)), + datetime: lambda v: datetime.fromisoformat(v), + } + + +@dataclass +class NonexistentSectionConfig(ReadsCfg): + some_value: str + another_value: str + + section_header = "i_dont_exist" + + +@dataclass +class TypeMismatchConfig(ReadsCfg): + int_value: int + + section_header = "type_mismatch" + + +@dataclass +class MissingItemConfig(ReadsCfg): + present_item: str + missing_item: str + + section_header = "missing_item" + + +class BasicConfigTest: + @pytest.fixture(scope="class") + def config(self): + return BasicConfig.from_cfg_file(PATH_TO_TEST_CONFIG) + + def test_coercions(self, config): + assert isinstance(config.int_value, int) + assert isinstance(config.bool_value, bool) + assert isinstance(config.float_value, float) + assert isinstance(config.str_value, str) + + def test_values(self, config): + assert config.int_value == 15421 + assert config.bool_value == True + assert config.float_value == 14.01 + assert config.str_value == "Ceci n'est pas une chaîne" + + def test_error_on_loading_from_nonexistent_file(self): + assert_raises_with_given_cause( + MissingConfig, + FileNotFoundError, + BasicConfig.from_cfg_file, + "./n/o/f/i/l/e/h.ere", + ) + + def test_error_on_loading_from_nonexistent_section(self): + assert_raises_with_given_cause( + MissingConfigSection, + configparser.NoSectionError, + NonexistentSectionConfig.from_cfg_file, + PATH_TO_TEST_CONFIG, + ) + + +class BooleanConfigTest: + @pytest.fixture(scope="class") + def config(self): + return BooleanConfig.from_cfg_file(PATH_TO_TEST_CONFIG) + + def test_values(self, config): + assert config.yes is True + assert config.one is True + assert config.true is True + assert config.on is True + assert config.no is False + assert config.zero is False + assert config.false is False + assert config.off is False + + +class UnsupportedTypesConfigTest: + @pytest.fixture(scope="class") + def config(self): + return UnsupportedTypesConfig.from_cfg_file(PATH_TO_TEST_CONFIG) + + def test_values(self, config): + assert config.decimal_value == "100001.01" + assert config.datetime_value == "2021-12-04 00:05:23.283" + + +class SupportedTypesConfigTest: + @pytest.fixture(scope="class") + def config(self): + return SupportedTypesConfig.from_cfg_file(PATH_TO_TEST_CONFIG) + + def test_values(self, config): + assert config.decimal_value == Decimal("100001.01") + assert config.datetime_value == datetime(2021, 12, 4, 0, 5, 23, 283000) + + +class TypeMismatchConfigTest: + def test_error_on_load(self): + assert_raises_message_with_given_cause( + ConfigValueTypeError, + "Wrong value type for int_value", + ValueError, + TypeMismatchConfig.from_cfg_file, + PATH_TO_TEST_CONFIG, + ) + + +class MissingItemConfigTest: + def test_error_on_load(self): + assert_raises_message_with_given_cause( + MissingConfigItem, + "No config item for missing_item", + configparser.NoOptionError, + MissingItemConfig.from_cfg_file, + PATH_TO_TEST_CONFIG, + ) diff --git a/test/util/__init__.py b/test/util/__init__.py deleted file mode 100644 index f8cb359..0000000 --- a/test/util/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from unittest import mock # noqa diff --git a/test/util/assertions.py b/test/util/assertions.py deleted file mode 100644 index 8be154c..0000000 --- a/test/util/assertions.py +++ /dev/null @@ -1,152 +0,0 @@ -import contextlib -import re -import sys - - -def eq_(a, b, msg=None): - """Assert a == b, with repr messaging on failure.""" - assert a == b, msg or "%r != %r" % (a, b) - - -def _assert_proper_exception_context(exception): - """assert that any exception we're catching does not have a __context__ - without a __cause__, and that __suppress_context__ is never set. - - Python 3 will report nested as exceptions as "during the handling of - error X, error Y occurred". That's not what we want to do. We want - these exceptions in a cause chain. - - """ - - if ( - exception.__context__ is not exception.__cause__ - and not exception.__suppress_context__ - ): - assert False, ( - "Exception %r was correctly raised but did not set a cause, " - "within context %r as its cause." - % (exception, exception.__context__) - ) - - -def _assert_proper_cause_cls(exception, cause_cls): - """assert that any exception we're catching does not have a __context__ - without a __cause__, and that __suppress_context__ is never set. - - Python 3 will report nested as exceptions as "during the handling of - error X, error Y occurred". That's not what we want to do. We want - these exceptions in a cause chain. - - """ - assert isinstance(exception.__cause__, cause_cls), ( - "Exception %r was correctly raised but has cause %r, which does not " - "have the expected cause type %r." - % (exception, exception.__cause__, cause_cls) - ) - - -def assert_raises(except_cls, callable_, *args, **kw): - return _assert_raises(except_cls, callable_, args, kw) - - -def assert_raises_with_proper_context(except_cls, callable_, *args, **kw): - return _assert_raises(except_cls, callable_, args, kw, check_context=True) - - -def assert_raises_with_given_cause( - except_cls, cause_cls, callable_, *args, **kw -): - return _assert_raises(except_cls, callable_, args, kw, cause_cls=cause_cls) - - -def assert_raises_message(except_cls, msg, callable_, *args, **kwargs): - return _assert_raises(except_cls, callable_, args, kwargs, msg=msg) - - -def assert_raises_message_with_proper_context( - except_cls, msg, callable_, *args, **kwargs -): - return _assert_raises( - except_cls, callable_, args, kwargs, msg=msg, check_context=True - ) - - -def assert_raises_message_with_given_cause( - except_cls, msg, cause_cls, callable_, *args, **kwargs -): - return _assert_raises( - except_cls, callable_, args, kwargs, msg=msg, cause_cls=cause_cls - ) - - -def _assert_raises( - except_cls, - callable_, - args, - kwargs, - msg=None, - check_context=False, - cause_cls=None, -): - - with _expect_raises(except_cls, msg, check_context, cause_cls) as ec: - callable_(*args, **kwargs) - return ec.error - - -class _ErrorContainer: - error = None - - -@contextlib.contextmanager -def _expect_raises(except_cls, msg=None, check_context=False, cause_cls=None): - ec = _ErrorContainer() - if check_context: - are_we_already_in_a_traceback = sys.exc_info()[0] - try: - yield ec - success = False - except except_cls as err: - ec.error = err - success = True - if msg is not None: - # I'm often pdbing here, and "err" above isn't - # in scope, so assign the string explicitly - error_as_string = str(err) - assert re.search(msg, error_as_string, re.UNICODE), "%r !~ %s" % ( - msg, - error_as_string, - ) - if cause_cls is not None: - _assert_proper_cause_cls(err, cause_cls) - if check_context and not are_we_already_in_a_traceback: - _assert_proper_exception_context(err) - print(str(err).encode("utf-8")) - - # it's generally a good idea to not carry traceback objects outside - # of the except: block, but in this case especially we seem to have - # hit some bug in either python 3.10.0b2 or greenlet or both which - # this seems to fix: - # https://github.com/python-greenlet/greenlet/issues/242 - del ec - - # assert outside the block so it works for AssertionError too ! - assert success, "Callable did not raise an exception" - - -def expect_raises(except_cls, check_context=False): - return _expect_raises(except_cls, check_context=check_context) - - -def expect_raises_message(except_cls, msg, check_context=False): - return _expect_raises(except_cls, msg=msg, check_context=check_context) - - -def expect_raises_with_proper_context(except_cls, check_context=True): - return _expect_raises(except_cls, check_context=check_context) - - -def expect_raises_message_with_proper_context( - except_cls, msg, check_context=True -): - return _expect_raises(except_cls, msg=msg, check_context=check_context) diff --git a/test/util/exclusions.py b/test/util/exclusions.py deleted file mode 100644 index 8eb596e..0000000 --- a/test/util/exclusions.py +++ /dev/null @@ -1,47 +0,0 @@ -import unittest - -from mako.util import update_wrapper - - -def skip_if(predicate, reason=None): - """Skip a test if predicate is true.""" - reason = reason or predicate.__name__ - - def decorate(fn): - fn_name = fn.__name__ - - def maybe(*args, **kw): - if predicate(): - msg = "'%s' skipped: %s" % (fn_name, reason) - raise unittest.SkipTest(msg) - else: - return fn(*args, **kw) - - return update_wrapper(maybe, fn) - - return decorate - - -def requires_pygments_14(fn): - try: - import pygments - - version = pygments.__version__ - except: - version = "0" - return skip_if( - lambda: version < "1.4", "Requires pygments 1.4 or greater" - )(fn) - - -def requires_no_pygments_exceptions(fn): - def go(*arg, **kw): - from mako import exceptions - - exceptions._install_fallback() - try: - return fn(*arg, **kw) - finally: - exceptions._install_highlighting() - - return update_wrapper(go, fn) diff --git a/test/util/fixtures.py b/test/util/fixtures.py deleted file mode 100644 index d4b28db..0000000 --- a/test/util/fixtures.py +++ /dev/null @@ -1,129 +0,0 @@ -import os -import unittest - -from mako.cache import CacheImpl -from mako.cache import register_plugin -from mako.template import Template -from .assertions import eq_ - - -def _ensure_environment_variable(key, fallback): - env_var = os.getenv(key) - if env_var is None: - return fallback - return env_var - - -def _get_module_base(): - return _ensure_environment_variable( - "TEST_MODULE_BASE", os.path.abspath("./test/templates/modules") - ) - - -def _get_template_base(): - return _ensure_environment_variable( - "TEST_TEMPLATE_BASE", os.path.abspath("./test/templates/") - ) - - -module_base = _get_module_base() -template_base = _get_template_base() - - -class TemplateTest(unittest.TestCase): - def _file_template(self, filename, **kw): - filepath = self._file_path(filename) - return Template( - uri=filename, filename=filepath, module_directory=module_base, **kw - ) - - def _file_path(self, filename): - name, ext = os.path.splitext(filename) - py3k_path = os.path.join(template_base, name + "_py3k" + ext) - if os.path.exists(py3k_path): - return py3k_path - - return os.path.join(template_base, filename) - - def _do_file_test( - self, - filename, - expected, - filters=None, - unicode_=True, - template_args=None, - **kw, - ): - t1 = self._file_template(filename, **kw) - self._do_test( - t1, - expected, - filters=filters, - unicode_=unicode_, - template_args=template_args, - ) - - def _do_memory_test( - self, - source, - expected, - filters=None, - unicode_=True, - template_args=None, - **kw, - ): - t1 = Template(text=source, **kw) - self._do_test( - t1, - expected, - filters=filters, - unicode_=unicode_, - template_args=template_args, - ) - - def _do_test( - self, - template, - expected, - filters=None, - template_args=None, - unicode_=True, - ): - if template_args is None: - template_args = {} - if unicode_: - output = template.render_unicode(**template_args) - else: - output = template.render(**template_args) - - if filters: - output = filters(output) - eq_(output, expected) - - -class PlainCacheImpl(CacheImpl): - """Simple memory cache impl so that tests which - use caching can run without beaker.""" - - def __init__(self, cache): - self.cache = cache - self.data = {} - - def get_or_create(self, key, creation_function, **kw): - if key in self.data: - return self.data[key] - else: - self.data[key] = data = creation_function(**kw) - return data - - def put(self, key, value, **kw): - self.data[key] = value - - def get(self, key, **kw): - return self.data[key] - - def invalidate(self, key, **kw): - del self.data[key] - - -register_plugin("plain", __name__, "PlainCacheImpl") diff --git a/test/util/helpers.py b/test/util/helpers.py deleted file mode 100644 index 86402c8..0000000 --- a/test/util/helpers.py +++ /dev/null @@ -1,60 +0,0 @@ -import contextlib -import pathlib -import re -import time -from unittest import mock - -from test.util.fixtures import module_base - - -def flatten_result(result): - return re.sub(r"[\s\r\n]+", " ", result).strip() - - -def result_lines(result): - return [ - x.strip() - for x in re.split(r"\r?\n", re.sub(r" +", " ", result)) - if x.strip() != "" - ] - - -def _unlink_path(path, missing_ok=False): - # Replicate 3.8+ functionality in 3.7 - cm = contextlib.nullcontext() - if missing_ok: - cm = contextlib.suppress(FileNotFoundError) - - with cm: - path.unlink() - - -def replace_file_with_dir(pathspec): - path = pathlib.Path(pathspec) - _unlink_path(path, missing_ok=True) - path.mkdir(exist_ok=True) - return path - - -def file_with_template_code(filespec): - with open(filespec, "w") as f: - f.write( - """ -i am an artificial template just for you -""" - ) - return filespec - - -@contextlib.contextmanager -def rewind_compile_time(hours=1): - rewound = time.time() - (hours * 3_600) - with mock.patch("mako.codegen.time") as codegen_time: - codegen_time.time.return_value = rewound - yield - - -def teardown(): - import shutil - - shutil.rmtree(module_base, True) |