123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316 |
- from django.conf import settings
- from django.template.base import Context, TemplateSyntaxError
- from django.template.loader import get_template
- from django.test import SimpleTestCase
- from .utils import render, setup, SilentGetItemClass, SilentAttrClass, SomeClass
- basic_templates = {
- 'basic-syntax01': 'something cool',
- 'basic-syntax02': '{{ headline }}',
- 'basic-syntax03': '{{ first }} --- {{ second }}',
- }
- class BasicSyntaxTests(SimpleTestCase):
- @setup(basic_templates)
- def test_basic_syntax01(self):
- """
- Plain text should go through the template parser untouched.
- """
- output = render('basic-syntax01')
- self.assertEqual(output, "something cool")
- @setup(basic_templates)
- def test_basic_syntax02(self):
- """
- Variables should be replaced with their value in the current
- context
- """
- output = render('basic-syntax02', {'headline': 'Success'})
- self.assertEqual(output, 'Success')
- @setup(basic_templates)
- def test_basic_syntax03(self):
- """
- More than one replacement variable is allowed in a template
- """
- output = render('basic-syntax03', {"first": 1, "second": 2})
- self.assertEqual(output, '1 --- 2')
- @setup({'basic-syntax04': 'as{{ missing }}df'})
- def test_basic_syntax04(self):
- """
- Fail silently when a variable is not found in the current context
- """
- output = render('basic-syntax04')
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'asINVALIDdf')
- else:
- self.assertEqual(output, 'asdf')
- @setup({'basic-syntax06': '{{ multi word variable }}'})
- def test_basic_syntax06(self):
- """
- A variable may not contain more than one word
- """
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax06')
- @setup({'basic-syntax07': '{{ }}'})
- def test_basic_syntax07(self):
- """
- Raise TemplateSyntaxError for empty variable tags.
- """
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax07')
- @setup({'basic-syntax08': '{{ }}'})
- def test_basic_syntax08(self):
- """
- Raise TemplateSyntaxError for empty variable tags.
- """
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax08')
- @setup({'basic-syntax09': '{{ var.method }}'})
- def test_basic_syntax09(self):
- """
- Attribute syntax allows a template to call an object's attribute
- """
- output = render('basic-syntax09', {'var': SomeClass()})
- self.assertEqual(output, 'SomeClass.method')
- @setup({'basic-syntax10': '{{ var.otherclass.method }}'})
- def test_basic_syntax10(self):
- """
- Multiple levels of attribute access are allowed.
- """
- output = render('basic-syntax10', {'var': SomeClass()})
- self.assertEqual(output, 'OtherClass.method')
- @setup({'basic-syntax11': '{{ var.blech }}'})
- def test_basic_syntax11(self):
- """
- Fail silently when a variable's attribute isn't found.
- """
- output = render('basic-syntax11', {'var': SomeClass()})
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'INVALID')
- else:
- self.assertEqual(output, '')
- @setup({'basic-syntax12': '{{ var.__dict__ }}'})
- def test_basic_syntax12(self):
- """
- Raise TemplateSyntaxError when trying to access a variable
- beginning with an underscore.
- """
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax12')
-
-
- @setup({'basic-syntax13': "{{ va>r }}"})
- def test_basic_syntax13(self):
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax13')
- @setup({'basic-syntax14': "{{ (var.r) }}"})
- def test_basic_syntax14(self):
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax14')
- @setup({'basic-syntax15': "{{ sp%am }}"})
- def test_basic_syntax15(self):
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax15')
- @setup({'basic-syntax16': "{{ eggs! }}"})
- def test_basic_syntax16(self):
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax16')
- @setup({'basic-syntax17': "{{ moo? }}"})
- def test_basic_syntax17(self):
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax17')
- @setup({'basic-syntax18': "{{ foo.bar }}"})
- def test_basic_syntax18(self):
- """
- Attribute syntax allows a template to call a dictionary key's
- value.
- """
- output = render('basic-syntax18', {"foo": {"bar": "baz"}})
- self.assertEqual(output, "baz")
- @setup({'basic-syntax19': "{{ foo.spam }}"})
- def test_basic_syntax19(self):
- """
- Fail silently when a variable's dictionary key isn't found.
- """
- output = render('basic-syntax19', {"foo": {"bar": "baz"}})
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'INVALID')
- else:
- self.assertEqual(output, '')
- @setup({'basic-syntax20': "{{ var.method2 }}"})
- def test_basic_syntax20(self):
- """
- Fail silently when accessing a non-simple method
- """
- output = render('basic-syntax20', {'var': SomeClass()})
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'INVALID')
- else:
- self.assertEqual(output, '')
- @setup({'basic-syntax20b': "{{ var.method5 }}"})
- def test_basic_syntax20b(self):
- """
- Don't silence a TypeError if it was raised inside a callable.
- """
- template = get_template('basic-syntax20b')
- with self.assertRaises(TypeError):
- template.render(Context({'var': SomeClass()}))
-
-
- @setup({'basic-syntax21': "a {{ moo %} b"})
- def test_basic_syntax21(self):
- output = render('basic-syntax21')
- self.assertEqual(output, "a {{ moo %} b")
- @setup({'basic-syntax22': "{{ moo #}"})
- def test_basic_syntax22(self):
- output = render('basic-syntax22')
- self.assertEqual(output, "{{ moo #}")
- @setup({'basic-syntax23': "{{ moo #} {{ cow }}"})
- def test_basic_syntax23(self):
- """
- Treat "moo #} {{ cow" as the variable. Not ideal, but costly to work
- around, so this triggers an error.
- """
- with self.assertRaises(TemplateSyntaxError):
- get_template('basic-syntax23')
- @setup({'basic-syntax24': "{{ moo\n }}"})
- def test_basic_syntax24(self):
- """
- Embedded newlines make it not-a-tag.
- """
- output = render('basic-syntax24')
- self.assertEqual(output, "{{ moo\n }}")
-
-
- @setup({'basic-syntax25': '{{ "fred" }}'})
- def test_basic_syntax25(self):
- output = render('basic-syntax25')
- self.assertEqual(output, "fred")
- @setup({'basic-syntax26': r'{{ "\"fred\"" }}'})
- def test_basic_syntax26(self):
- output = render('basic-syntax26')
- self.assertEqual(output, "\"fred\"")
- @setup({'basic-syntax27': r'{{ _("\"fred\"") }}'})
- def test_basic_syntax27(self):
- output = render('basic-syntax27')
- self.assertEqual(output, "\"fred\"")
-
-
- @setup({'basic-syntax28': "{{ a.b }}"})
- def test_basic_syntax28(self):
- output = render('basic-syntax28', {'a': SilentGetItemClass()})
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'INVALID')
- else:
- self.assertEqual(output, '')
- @setup({'basic-syntax29': "{{ a.b }}"})
- def test_basic_syntax29(self):
- output = render('basic-syntax29', {'a': SilentAttrClass()})
- if settings.TEMPLATE_STRING_IF_INVALID:
- self.assertEqual(output, 'INVALID')
- else:
- self.assertEqual(output, '')
-
-
- @setup({'basic-syntax30': "{{ 1.2.3 }}"})
- def test_basic_syntax30(self):
- output = render(
- 'basic-syntax30',
- {"1": {"2": {"3": "d"}}}
- )
- self.assertEqual(output, 'd')
- @setup({'basic-syntax31': "{{ 1.2.3 }}"})
- def test_basic_syntax31(self):
- output = render(
- 'basic-syntax31',
- {"1": {"2": ("a", "b", "c", "d")}},
- )
- self.assertEqual(output, 'd')
- @setup({'basic-syntax32': "{{ 1.2.3 }}"})
- def test_basic_syntax32(self):
- output = render(
- 'basic-syntax32',
- {"1": (("x", "x", "x", "x"), ("y", "y", "y", "y"), ("a", "b", "c", "d"))},
- )
- self.assertEqual(output, 'd')
- @setup({'basic-syntax33': "{{ 1.2.3 }}"})
- def test_basic_syntax33(self):
- output = render(
- 'basic-syntax33',
- {"1": ("xxxx", "yyyy", "abcd")},
- )
- self.assertEqual(output, 'd')
- @setup({'basic-syntax34': "{{ 1.2.3 }}"})
- def test_basic_syntax34(self):
- output = render(
- 'basic-syntax34',
- {"1": ({"x": "x"}, {"y": "y"}, {"z": "z", "3": "d"})}
- )
- self.assertEqual(output, 'd')
-
- @setup({'basic-syntax35': "{{ 1 }}"})
- def test_basic_syntax35(self):
- output = render('basic-syntax35', {"1": "abc"})
- self.assertEqual(output, '1')
- @setup({'basic-syntax36': "{{ 1.2 }}"})
- def test_basic_syntax36(self):
- output = render('basic-syntax36', {"1": "abc"})
- self.assertEqual(output, '1.2')
- @setup({'basic-syntax37': '{{ callable }}'})
- def test_basic_syntax37(self):
- """
- Call methods in the top level of the context.
- """
- output = render('basic-syntax37', {"callable": lambda: "foo bar"})
- self.assertEqual(output, 'foo bar')
- @setup({'basic-syntax38': '{{ var.callable }}'})
- def test_basic_syntax38(self):
- """
- Call methods returned from dictionary lookups.
- """
- output = render('basic-syntax38', {"var": {"callable": lambda: "foo bar"}})
- self.assertEqual(output, 'foo bar')
|