def test_render_index_filter(self): test_cases = [ RenderCase( description="array of strings", template=r"{{ handles | index: 'foo' }}", expect="0", globals={"handles": ["foo", "bar"]}, partials={}, ), RenderCase( description="array of strings item does not exist", template=r"{{ handles | index: 'baz' }}", expect="", globals={"handles": ["foo", "bar"]}, partials={}, ), ] for case in test_cases: env = Environment() env.add_filter("index", index) env.loader = DictLoader(case.partials) template = env.from_string(case.template, globals=case.globals) with self.subTest(msg=case.description): result = template.render() self.assertEqual(result, case.expect)
def test_filter_value_error(self): """Test unexpected filter values.""" env = Environment() env.add_tag(InlineIfStatement) template = env.from_string(r"{{ 123 | first }}") self.assertEqual(template.render(), "") # and render async async def coro(template: BoundTemplate): return await template.render_async() self.assertEqual(asyncio.run(coro(template)), "")
def test_filter_argument_error(self): """Test unexpected filter arguments.""" env = Environment() env.add_tag(InlineIfStatement) template = env.from_string(r"{{ 123 | divided_by: 0 }}") with self.assertRaises(FilterArgumentError): template.render() # and render async async def coro(template: BoundTemplate): return await template.render_async() with self.assertRaises(FilterArgumentError): asyncio.run(coro(template))
def test_render_script_tag_with_autoescape(self): test_cases = [ RenderCase( description="relative url", template=r"{{ url | script_tag }}", expect=( '<script src="assets/assets/app.js" ' 'type="text/javascript"></script>' ), globals={"url": "assets/assets/app.js"}, partials={}, ), RenderCase( description="unsafe url from context", template=r"{{ url | script_tag }}", expect=( '<script src="<b>assets/assets/app.js</b>" ' 'type="text/javascript"></script>' ), globals={"url": "<b>assets/assets/app.js</b>"}, partials={}, ), RenderCase( description="safe url from context", template=r"{{ url | script_tag }}", expect=( '<script src="<b>assets/assets/app.js</b>" ' 'type="text/javascript"></script>' ), globals={"url": Markup("<b>assets/assets/app.js</b>")}, partials={}, ), ] env = Environment(autoescape=True) env.add_filter("script_tag", script_tag) for case in test_cases: template = env.from_string(case.template, globals=case.globals) with self.subTest(msg=case.description): result = template.render() self.assertEqual(result, case.expect)
def test_render_stylesheet_tag_with_autoescape(self): test_cases = [ RenderCase( description="relative url", template=r"{{ url | stylesheet_tag }}", expect=( '<link href="assets/style.css" rel="stylesheet" ' 'type="text/css" media="all" />' ), globals={"url": "assets/style.css"}, partials={}, ), RenderCase( description="unsafe url from context", template=r"{{ url | stylesheet_tag }}", expect=( '<link href="<b>assets/style.css</b>" rel="stylesheet" ' 'type="text/css" media="all" />' ), globals={"url": "<b>assets/style.css</b>"}, partials={}, ), RenderCase( description="safe url from context", template=r"{{ url | stylesheet_tag }}", expect=( '<link href="<b>assets/style.css</b>" rel="stylesheet" ' 'type="text/css" media="all" />' ), globals={"url": Markup("<b>assets/style.css</b>")}, partials={}, ), ] env = Environment(autoescape=True) env.add_filter("stylesheet_tag", stylesheet_tag) for case in test_cases: template = env.from_string(case.template, globals=case.globals) with self.subTest(msg=case.description): result = template.render() self.assertEqual(result, case.expect)
def test_assign_expression_syntax_error(self): """Test that we handle syntax errors in `assign` expressions using inline `if`.""" env = Environment() env.add_tag(InlineIfAssignTag) with self.assertRaises(LiquidSyntaxError): env.from_string(r"{% assign foo.bar = 'hello' %}")
def test_render_with_tag(self): """Test that we can render a `with` tag.""" test_cases = [ Case( description="block scoped variable", template=r"{{ x }}{% with x: 'foo' %}{{ x }}{% endwith %}{{ x }}", expect="foo", ), Case( description="block scoped alias", template=( r"{% with p: collection.products.first %}" r"{{ p.title }}" r"{% endwith %}" r"{{ p.title }}" r"{{ collection.products.first.title }}" ), expect="A ShoeA Shoe", globals={"collection": {"products": [{"title": "A Shoe"}]}}, ), Case( description="multiple block scoped variables", template=( r"{% with a: 1, b: 3.4 %}" r"{{ a }} + {{ b }} = {{ a | plus: b }}" r"{% endwith %}" ), expect="1 + 3.4 = 4.4", ), ] env = Environment() env.add_tag(WithTag) for case in test_cases: with self.subTest(msg=case.description): template = env.from_string(case.template, globals=case.globals) self.assertEqual(template.render(), case.expect)
def test_render_stylesheet_tag_filter(self): test_cases = [ RenderCase( description="from context variable", template=r"{{ url | stylesheet_tag }}", expect=( '<link href="assets/style.css" rel="stylesheet" ' 'type="text/css" media="all" />' ), globals={"url": "assets/style.css"}, partials={}, ), ] for case in test_cases: env = Environment() env.add_filter("stylesheet_tag", stylesheet_tag) env.loader = DictLoader(case.partials) template = env.from_string(case.template, globals=case.globals) with self.subTest(msg=case.description): result = template.render() self.assertEqual(result, case.expect)
def test_render_script_tag_filter(self): test_cases = [ RenderCase( description="url from context", template=r"{{ url | script_tag }}", expect=( '<script src="assets/assets/app.js" ' 'type="text/javascript"></script>' ), globals={"url": "assets/assets/app.js"}, partials={}, ), ] # Test new style filter implementation for case in test_cases: env = Environment() env.add_filter("script_tag", script_tag) env.loader = DictLoader(case.partials) template = env.from_string(case.template, globals=case.globals) with self.subTest(msg=case.description): result = template.render() self.assertEqual(result, case.expect)
def __call__( self, key: object, *, context: Context, environment: Environment, **kwargs: Any, ) -> str: locale = context.resolve("locale", default="default") translations: Mapping[str, object] = self.locales.get(locale, {}) key = str(key) path = key.split(".") val = get_item(translations, *path, default=key) # type: ignore return environment.from_string(val).render(**kwargs)
def test_unexpected_filter_exception(self): """Test unexpected filter exception.""" env = Environment() env.add_tag(InlineIfStatement) def func(): raise Exception(":(") env.add_filter("func", func) template = env.from_string(r"{{ 123 | func }}") with self.assertRaises(Error): template.render() # and render async async def coro(template: BoundTemplate): return await template.render_async() with self.assertRaises(Error): asyncio.run(coro(template))
def test_unknown_filter(self): """Test that unknown filters are handled properly.""" env = Environment(strict_filters=True) env.add_tag(InlineIfStatement) template = env.from_string(r"{{ 'hello' | nosuchthing }}") with self.assertRaises(NoSuchFilterFunc): template.render() # and render async async def coro(template: BoundTemplate): return await template.render_async() with self.assertRaises(NoSuchFilterFunc): asyncio.run(coro(template)) env.strict_filters = False self.assertEqual(template.render(), "hello") self.assertEqual(asyncio.run(coro(template)), "hello")
def test_render_echo_inline_if_expression(self): """Test that we correctly render echo expressions that use inline `if`.""" test_cases = [ RenderCase( description="string literal", template=r"{% echo 'hello' %}", expect="hello", globals={}, partials={}, ), RenderCase( description="string literal with true condition", template=r"{% echo 'hello' if true %}", expect="hello", globals={}, partials={}, ), RenderCase( description="default to undefined", template=r"{% echo 'hello' if false %}", expect="", globals={}, partials={}, ), RenderCase( description="early filter", template=r"{% echo 'hello' | upcase if true %}", expect="HELLO", globals={}, partials={}, ), RenderCase( description="string literal with false condition and alternative", template=r"{% echo 'hello' if false else 'goodbye' %}", expect="goodbye", globals={}, partials={}, ), RenderCase( description="object and condition from context with tail filter", template=(r"{% echo greeting if settings.foo else 'bar' | upcase %}"), expect="HELLO", globals={"settings": {"foo": True}, "greeting": "hello"}, partials={}, ), ] for case in test_cases: env = Environment(loader=DictLoader(case.partials)) env.add_tag(InlineIfEchoTag) with self.subTest(msg=case.description): template = env.from_string(case.template, globals=case.globals) result = template.render() self.assertEqual(result, case.expect) # Same again using async path. async def coro(template): return await template.render_async() for case in test_cases: env = Environment(loader=DictLoader(case.partials)) env.add_tag(InlineIfEchoTag) with self.subTest(msg=case.description): template = env.from_string(case.template, globals=case.globals) result = asyncio.run(coro(template)) self.assertEqual(result, case.expect)
def test_evaluate_inline_if_expression(self): """Test that we correctly evaluate inline `if` expressions.""" env = Environment() test_cases = [ EvalCase( description="string literal", context={}, expression="'foo'", expect="foo", ), EvalCase( description="string literal with true condition", context={}, expression="'foo' if true", expect="foo", ), EvalCase( description="string literal with false condition", context={}, expression="'foo' if false", expect=env.undefined(""), ), EvalCase( description="string literal with false condition and alternative", context={}, expression="'foo' if false else 'bar'", expect="bar", ), EvalCase( description="object and condition from context", context={"settings": {"foo": True}, "greeting": "hello"}, expression="greeting if settings.foo else 'bar'", expect="hello", ), EvalCase( description="object and condition from context with tail filter", context={"settings": {"foo": True}, "greeting": "hello"}, expression="greeting if settings.foo else 'bar' | upcase", expect="HELLO", ), EvalCase( description="object filter with true condition", context={}, expression="'foo' | upcase if true else 'bar'", expect="FOO", ), EvalCase( description="object filter with false condition", context={}, expression="'foo' | upcase if false else 'bar'", expect="bar", ), ] for case in test_cases: context = Context(env, case.context) with self.subTest(msg=case.description): tokens = TokenStream(tokenize_if_expression(case.expression)) expr = parser.parse_filtered_if_expression(tokens) res = expr.evaluate(context) self.assertEqual(res, case.expect)