2006-12-05 19:48:46 +00:00
# -*- coding: utf-8 -*-
2013-07-29 17:19:04 +00:00
from __future__ import unicode_literals
2011-09-16 01:16:25 +00:00
2013-07-25 22:17:40 +00:00
from datetime import date , datetime
2007-07-23 04:45:01 +00:00
import os
2009-03-31 07:23:50 +00:00
import sys
2009-03-29 23:33:01 +00:00
import traceback
2013-07-01 12:22:27 +00:00
import unittest
2013-02-24 09:28:05 +00:00
import warnings
2007-07-23 04:45:01 +00:00
2006-08-27 13:59:47 +00:00
from django import template
2014-03-02 13:55:37 +00:00
from django . conf import settings
2008-08-05 14:16:13 +00:00
from django . core import urlresolvers
2013-02-23 16:45:05 +00:00
from django . template import ( base as template_base , loader , Context ,
RequestContext , Template , TemplateSyntaxError )
2009-12-14 12:08:23 +00:00
from django . template . loaders import app_directories , filesystem , cached
2012-11-24 21:03:12 +00:00
from django . test import RequestFactory , TestCase
2012-04-26 18:06:17 +00:00
from django . test . utils import ( setup_test_template_loader ,
2014-01-26 13:29:04 +00:00
restore_template_loaders , override_settings , extend_sys_path )
2014-03-27 20:24:19 +00:00
from django . utils . deprecation import RemovedInDjango19Warning , RemovedInDjango20Warning
2012-08-18 08:18:24 +00:00
from django . utils . encoding import python_2_unicode_compatible
2011-05-07 16:58:45 +00:00
from django . utils . formats import date_format
2012-12-08 10:13:52 +00:00
from django . utils . _os import upath
2007-11-14 12:58:53 +00:00
from django . utils . safestring import mark_safe
2012-07-20 19:14:27 +00:00
from django . utils import six
2013-09-05 19:38:59 +00:00
from django . utils . six . moves . urllib . parse import urljoin
2014-01-26 13:29:04 +00:00
from django . utils import translation
2007-07-23 04:45:01 +00:00
2013-02-15 07:29:15 +00:00
# NumPy installed?
try :
import numpy
except ImportError :
numpy = False
2011-10-13 21:34:56 +00:00
from . import filters
2006-08-27 13:59:47 +00:00
#################################
# Custom template tag for tests #
#################################
register = template . Library ( )
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
class EchoNode ( template . Node ) :
def __init__ ( self , contents ) :
self . contents = contents
def render ( self , context ) :
return " " . join ( self . contents )
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
def do_echo ( parser , token ) :
return EchoNode ( token . contents . split ( ) [ 1 : ] )
2013-11-02 21:34:05 +00:00
2010-11-20 06:22:28 +00:00
def do_upper ( value ) :
return value . upper ( )
2006-08-27 13:59:47 +00:00
register . tag ( " echo " , do_echo )
2010-11-20 06:22:28 +00:00
register . tag ( " other_echo " , do_echo )
register . filter ( " upper " , do_upper )
2006-08-27 13:59:47 +00:00
2010-01-26 01:38:50 +00:00
template . libraries [ ' testtags ' ] = register
2006-08-27 13:59:47 +00:00
#####################################
# Helper objects for template tests #
#####################################
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
class SomeException ( Exception ) :
silent_variable_failure = True
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
class SomeOtherException ( Exception ) :
pass
2009-06-18 15:03:17 +00:00
2013-11-02 21:34:05 +00:00
2009-04-07 22:02:34 +00:00
class ContextStackException ( Exception ) :
pass
2006-08-27 13:59:47 +00:00
2013-11-02 21:34:05 +00:00
2011-09-09 17:54:04 +00:00
class ShouldNotExecuteException ( Exception ) :
pass
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
class SomeClass :
def __init__ ( self ) :
self . otherclass = OtherClass ( )
def method ( self ) :
return " SomeClass.method "
def method2 ( self , o ) :
return o
def method3 ( self ) :
raise SomeException
def method4 ( self ) :
raise SomeOtherException
2013-09-08 13:07:12 +00:00
def method5 ( self ) :
raise TypeError
2010-12-19 23:47:24 +00:00
def __getitem__ ( self , key ) :
if key == ' silent_fail_key ' :
raise SomeException
elif key == ' noisy_fail_key ' :
raise SomeOtherException
raise KeyError
def silent_fail_attribute ( self ) :
raise SomeException
silent_fail_attribute = property ( silent_fail_attribute )
def noisy_fail_attribute ( self ) :
raise SomeOtherException
noisy_fail_attribute = property ( noisy_fail_attribute )
2013-11-02 21:34:05 +00:00
2006-08-27 13:59:47 +00:00
class OtherClass :
def method ( self ) :
return " OtherClass.method "
2013-11-02 21:34:05 +00:00
2010-04-19 14:18:14 +00:00
class TestObj ( object ) :
def is_true ( self ) :
return True
def is_false ( self ) :
return False
def is_bad ( self ) :
2011-09-09 17:54:04 +00:00
raise ShouldNotExecuteException ( )
2010-04-19 14:18:14 +00:00
2013-11-02 21:34:05 +00:00
2010-03-20 20:27:57 +00:00
class SilentGetItemClass ( object ) :
def __getitem__ ( self , key ) :
raise SomeException
2013-11-02 21:34:05 +00:00
2010-03-22 19:08:04 +00:00
class SilentAttrClass ( object ) :
def b ( self ) :
raise SomeException
b = property ( b )
2013-11-02 21:34:05 +00:00
2012-08-18 08:18:24 +00:00
@python_2_unicode_compatible
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 12:11:04 +00:00
class UTF8Class :
2012-08-18 08:18:24 +00:00
" Class whose __str__ returns non-ASCII data on Python 2 "
2006-12-05 19:48:46 +00:00
def __str__ ( self ) :
2012-08-18 08:18:24 +00:00
return ' ŠĐĆŽćžšđ '
2006-12-05 19:48:46 +00:00
2013-06-06 12:27:00 +00:00
class TemplateLoaderTests ( TestCase ) :
2010-11-17 15:36:26 +00:00
2007-07-23 04:45:01 +00:00
def test_loaders_security ( self ) :
2009-12-14 12:08:23 +00:00
ad_loader = app_directories . Loader ( )
fs_loader = filesystem . Loader ( )
2013-10-22 10:21:07 +00:00
2007-07-23 04:45:01 +00:00
def test_template_sources ( path , template_dirs , expected_sources ) :
2008-10-06 06:34:54 +00:00
if isinstance ( expected_sources , list ) :
2011-05-22 23:56:42 +00:00
# Fix expected sources so they are abspathed
expected_sources = [ os . path . abspath ( s ) for s in expected_sources ]
2008-10-06 06:34:54 +00:00
# Test the two loaders (app_directores and filesystem).
2009-12-14 12:08:23 +00:00
func1 = lambda p , t : list ( ad_loader . get_template_sources ( p , t ) )
func2 = lambda p , t : list ( fs_loader . get_template_sources ( p , t ) )
2008-10-06 06:34:54 +00:00
for func in ( func1 , func2 ) :
if isinstance ( expected_sources , list ) :
self . assertEqual ( func ( path , template_dirs ) , expected_sources )
else :
self . assertRaises ( expected_sources , func , path , template_dirs )
2007-07-23 04:45:01 +00:00
template_dirs = [ ' /dir1 ' , ' /dir2 ' ]
test_template_sources ( ' index.html ' , template_dirs ,
[ ' /dir1/index.html ' , ' /dir2/index.html ' ] )
2008-10-06 06:34:54 +00:00
test_template_sources ( ' /etc/passwd ' , template_dirs , [ ] )
2007-07-23 04:45:01 +00:00
test_template_sources ( ' etc/passwd ' , template_dirs ,
[ ' /dir1/etc/passwd ' , ' /dir2/etc/passwd ' ] )
2008-10-06 06:34:54 +00:00
test_template_sources ( ' ../etc/passwd ' , template_dirs , [ ] )
test_template_sources ( ' ../../../etc/passwd ' , template_dirs , [ ] )
2007-07-23 04:45:01 +00:00
test_template_sources ( ' /dir1/index.html ' , template_dirs ,
[ ' /dir1/index.html ' ] )
test_template_sources ( ' ../dir2/index.html ' , template_dirs ,
[ ' /dir2/index.html ' ] )
2008-10-06 06:34:54 +00:00
test_template_sources ( ' /dir1blah ' , template_dirs , [ ] )
test_template_sources ( ' ../dir1blah ' , template_dirs , [ ] )
# UTF-8 bytestrings are permitted.
2012-05-19 15:43:34 +00:00
test_template_sources ( b ' \xc3 \x85 ngstr \xc3 \xb6 m ' , template_dirs ,
2012-06-07 16:08:47 +00:00
[ ' /dir1/Ångström ' , ' /dir2/Ångström ' ] )
2008-10-06 06:34:54 +00:00
# Unicode strings are permitted.
2012-06-07 16:08:47 +00:00
test_template_sources ( ' Ångström ' , template_dirs ,
[ ' /dir1/Ångström ' , ' /dir2/Ångström ' ] )
test_template_sources ( ' Ångström ' , [ b ' /Stra \xc3 \x9f e ' ] , [ ' /Straße/Ångström ' ] )
2012-05-19 15:43:34 +00:00
test_template_sources ( b ' \xc3 \x85 ngstr \xc3 \xb6 m ' , [ b ' /Stra \xc3 \x9f e ' ] ,
2012-06-07 16:08:47 +00:00
[ ' /Straße/Ångström ' ] )
2008-10-06 06:34:54 +00:00
# Invalid UTF-8 encoding in bytestrings is not. Should raise a
# semi-useful error message.
2012-05-19 15:43:34 +00:00
test_template_sources ( b ' \xc3 \xc3 ' , template_dirs , UnicodeDecodeError )
2007-07-23 04:45:01 +00:00
# Case insensitive tests (for win32). Not run unless we're on
# a case insensitive operating system.
if os . path . normcase ( ' /TEST ' ) == os . path . normpath ( ' /test ' ) :
template_dirs = [ ' /dir1 ' , ' /DIR2 ' ]
test_template_sources ( ' index.html ' , template_dirs ,
2011-05-22 23:56:42 +00:00
[ ' /dir1/index.html ' , ' /DIR2/index.html ' ] )
2007-07-23 04:45:01 +00:00
test_template_sources ( ' /DIR1/index.HTML ' , template_dirs ,
2011-05-22 23:56:42 +00:00
[ ' /DIR1/index.HTML ' ] )
2007-07-23 04:45:01 +00:00
2013-10-14 13:14:17 +00:00
# Turn TEMPLATE_DEBUG on, so that the origin file name will be kept with
# the compiled templates.
@override_settings ( TEMPLATE_DEBUG = True )
2010-03-01 23:05:35 +00:00
def test_loader_debug_origin ( self ) :
2010-03-16 14:34:57 +00:00
old_loaders = loader . template_source_loaders
2010-03-01 23:05:35 +00:00
2010-03-16 14:34:57 +00:00
try :
loader . template_source_loaders = ( filesystem . Loader ( ) , )
# We rely on the fact that runtests.py sets up TEMPLATE_DIRS to
2012-09-30 21:16:14 +00:00
# point to a directory containing a login.html file. Also that
2010-03-16 14:34:57 +00:00
# the file system and app directories loaders both inherit the
# load_template method from the BaseLoader class, so we only need
# to test one of them.
2012-09-30 21:16:14 +00:00
load_name = ' login.html '
2010-03-16 14:34:57 +00:00
template = loader . get_template ( load_name )
template_name = template . nodelist [ 0 ] . source [ 0 ] . name
self . assertTrue ( template_name . endswith ( load_name ) ,
' Template loaded by filesystem loader has incorrect name for debug page: %s ' % template_name )
2014-03-02 14:25:53 +00:00
# Also test the cached loader, since it overrides load_template
2010-03-16 14:34:57 +00:00
cache_loader = cached . Loader ( ( ' ' , ) )
cache_loader . _cached_loaders = loader . template_source_loaders
loader . template_source_loaders = ( cache_loader , )
template = loader . get_template ( load_name )
template_name = template . nodelist [ 0 ] . source [ 0 ] . name
self . assertTrue ( template_name . endswith ( load_name ) ,
' Template loaded through cached loader has incorrect name for debug page: %s ' % template_name )
template = loader . get_template ( load_name )
template_name = template . nodelist [ 0 ] . source [ 0 ] . name
self . assertTrue ( template_name . endswith ( load_name ) ,
' Cached template loaded through cached loader has incorrect name for debug page: %s ' % template_name )
finally :
loader . template_source_loaders = old_loaders
2013-08-30 19:08:40 +00:00
def test_loader_origin ( self ) :
with self . settings ( TEMPLATE_DEBUG = True ) :
template = loader . get_template ( ' login.html ' )
self . assertEqual ( template . origin . loadname , ' login.html ' )
def test_string_origin ( self ) :
with self . settings ( TEMPLATE_DEBUG = True ) :
template = Template ( ' string template ' )
self . assertEqual ( template . origin . source , ' string template ' )
def test_debug_false_origin ( self ) :
template = loader . get_template ( ' login.html ' )
self . assertEqual ( template . origin , None )
2011-03-03 00:41:40 +00:00
2013-10-14 13:14:17 +00:00
# TEMPLATE_DEBUG must be true, otherwise the exception raised
# during {% include %} processing will be suppressed.
@override_settings ( TEMPLATE_DEBUG = True )
2011-03-03 00:41:40 +00:00
def test_include_missing_template ( self ) :
"""
Tests that the correct template is identified as not existing
when { % include % } specifies a template that does not exist .
"""
old_loaders = loader . template_source_loaders
try :
# Test the base loader class via the app loader. load_template
# from base is used by all shipped loaders excepting cached,
# which has its own test.
loader . template_source_loaders = ( app_directories . Loader ( ) , )
load_name = ' test_include_error.html '
r = None
try :
tmpl = loader . select_template ( [ load_name ] )
r = tmpl . render ( template . Context ( { } ) )
2012-04-28 16:09:37 +00:00
except template . TemplateDoesNotExist as e :
2011-03-03 00:41:40 +00:00
self . assertEqual ( e . args [ 0 ] , ' missing.html ' )
self . assertEqual ( r , None , ' Template rendering unexpectedly succeeded, produced: -> %r <- ' % r )
finally :
loader . template_source_loaders = old_loaders
2013-10-14 13:14:17 +00:00
# TEMPLATE_DEBUG must be true, otherwise the exception raised
# during {% include %} processing will be suppressed.
@override_settings ( TEMPLATE_DEBUG = True )
2010-03-16 14:34:57 +00:00
def test_extends_include_missing_baseloader ( self ) :
"""
2010-03-30 12:44:30 +00:00
Tests that the correct template is identified as not existing
when { % extends % } specifies a template that does exist , but
2010-03-16 14:34:57 +00:00
that template has an { % include % } of something that does not
exist . See #12787.
"""
2010-03-01 23:05:35 +00:00
old_loaders = loader . template_source_loaders
2010-03-16 14:34:57 +00:00
try :
2010-03-30 12:44:30 +00:00
# Test the base loader class via the app loader. load_template
# from base is used by all shipped loaders excepting cached,
2010-03-16 14:34:57 +00:00
# which has its own test.
loader . template_source_loaders = ( app_directories . Loader ( ) , )
load_name = ' test_extends_error.html '
tmpl = loader . get_template ( load_name )
r = None
try :
r = tmpl . render ( template . Context ( { } ) )
2012-04-28 16:09:37 +00:00
except template . TemplateDoesNotExist as e :
2011-09-16 01:16:25 +00:00
self . assertEqual ( e . args [ 0 ] , ' missing.html ' )
2010-03-16 14:34:57 +00:00
self . assertEqual ( r , None , ' Template rendering unexpectedly succeeded, produced: -> %r <- ' % r )
finally :
loader . template_source_loaders = old_loaders
2013-10-14 13:14:17 +00:00
@override_settings ( TEMPLATE_DEBUG = True )
2010-03-16 14:34:57 +00:00
def test_extends_include_missing_cachedloader ( self ) :
"""
2010-03-30 12:44:30 +00:00
Same as test_extends_include_missing_baseloader , only tests
2010-03-16 14:34:57 +00:00
behavior of the cached loader instead of BaseLoader .
"""
old_loaders = loader . template_source_loaders
try :
cache_loader = cached . Loader ( ( ' ' , ) )
cache_loader . _cached_loaders = ( app_directories . Loader ( ) , )
loader . template_source_loaders = ( cache_loader , )
load_name = ' test_extends_error.html '
tmpl = loader . get_template ( load_name )
r = None
try :
r = tmpl . render ( template . Context ( { } ) )
2012-04-28 16:09:37 +00:00
except template . TemplateDoesNotExist as e :
2011-09-16 01:16:25 +00:00
self . assertEqual ( e . args [ 0 ] , ' missing.html ' )
2010-03-16 14:34:57 +00:00
self . assertEqual ( r , None , ' Template rendering unexpectedly succeeded, produced: -> %r <- ' % r )
# For the cached loader, repeat the test, to ensure the first attempt did not cache a
# result that behaves incorrectly on subsequent attempts.
tmpl = loader . get_template ( load_name )
try :
tmpl . render ( template . Context ( { } ) )
2012-04-28 16:09:37 +00:00
except template . TemplateDoesNotExist as e :
2011-09-16 01:16:25 +00:00
self . assertEqual ( e . args [ 0 ] , ' missing.html ' )
2010-03-16 14:34:57 +00:00
self . assertEqual ( r , None , ' Template rendering unexpectedly succeeded, produced: -> %r <- ' % r )
finally :
loader . template_source_loaders = old_loaders
2010-03-01 23:05:35 +00:00
2013-08-28 12:17:20 +00:00
def test_include_template_argument ( self ) :
"""
Support any render ( ) supporting object
"""
ctx = Context ( {
' tmpl ' : Template ( ' This worked! ' ) ,
} )
outer_tmpl = Template ( ' { % i nclude tmpl % } ' )
output = outer_tmpl . render ( ctx )
self . assertEqual ( output , ' This worked! ' )
2013-08-29 08:58:56 +00:00
@override_settings ( TEMPLATE_DEBUG = True )
def test_include_immediate_missing ( self ) :
"""
Regression test for #16417 -- {% include %} tag raises TemplateDoesNotExist at compile time if TEMPLATE_DEBUG is True
Test that an { % include % } tag with a literal string referencing a
template that does not exist does not raise an exception at parse
time .
"""
tmpl = Template ( ' { % i nclude " this_does_not_exist.html " % } ' )
self . assertIsInstance ( tmpl , Template )
@override_settings ( TEMPLATE_DEBUG = True )
def test_include_recursive ( self ) :
comments = [
{
' comment ' : ' A1 ' ,
' children ' : [
{ ' comment ' : ' B1 ' , ' children ' : [ ] } ,
{ ' comment ' : ' B2 ' , ' children ' : [ ] } ,
{ ' comment ' : ' B3 ' , ' children ' : [
{ ' comment ' : ' C1 ' , ' children ' : [ ] }
] } ,
]
}
]
t = loader . get_template ( ' recursive_include.html ' )
self . assertEqual (
" Recursion! A1 Recursion! B1 B2 B3 Recursion! C1 " ,
t . render ( Context ( { ' comments ' : comments } ) ) . replace ( ' ' , ' ' ) . replace ( ' \n ' , ' ' ) . strip ( ) ,
)
2013-06-06 12:27:00 +00:00
class TemplateRegressionTests ( TestCase ) :
2008-08-31 18:28:06 +00:00
def test_token_smart_split ( self ) :
# Regression test for #7027
token = template . Token ( template . TOKEN_BLOCK , ' sometag _( " Page not found " ) value|yesno:_( " yes,no " ) ' )
split = token . split_contents ( )
self . assertEqual ( split , [ " sometag " , ' _( " Page not found " ) ' , ' value|yesno:_( " yes,no " ) ' ] )
2011-09-16 01:16:25 +00:00
@override_settings ( SETTINGS_MODULE = None , TEMPLATE_DEBUG = True )
2009-04-01 22:46:46 +00:00
def test_url_reverse_no_settings_module ( self ) :
2009-04-04 19:34:52 +00:00
# Regression test for #9005
2009-04-01 22:46:46 +00:00
t = Template ( ' { % u rl will_not_match % } ' )
c = Context ( )
2011-09-16 01:16:25 +00:00
with self . assertRaises ( urlresolvers . NoReverseMatch ) :
t . render ( c )
2013-02-23 16:41:30 +00:00
@override_settings ( TEMPLATE_STRING_IF_INVALID = ' %s is invalid ' , SETTINGS_MODULE = ' also_something ' )
def test_url_reverse_view_name ( self ) :
# Regression test for #19827
t = Template ( ' { % u rl will_not_match % } ' )
c = Context ( )
try :
t . render ( c )
except urlresolvers . NoReverseMatch :
tb = sys . exc_info ( ) [ 2 ]
depth = 0
while tb . tb_next is not None :
tb = tb . tb_next
depth + = 1
self . assertTrue ( depth > 5 ,
" The traceback context was lost when reraising the traceback. See #19827 " )
2012-04-10 20:49:45 +00:00
@override_settings ( DEBUG = True , TEMPLATE_DEBUG = True )
2011-09-16 01:16:25 +00:00
def test_no_wrapped_exception ( self ) :
"""
The template system doesn ' t wrap exceptions, but annotates them.
Refs #16770
"""
c = Context ( { " coconuts " : lambda : 42 / 0 } )
t = Template ( " {{ coconuts }} " )
with self . assertRaises ( ZeroDivisionError ) as cm :
t . render ( c )
self . assertEqual ( cm . exception . django_template_source [ 1 ] , ( 0 , 14 ) )
2009-04-04 19:34:52 +00:00
2010-02-21 23:38:33 +00:00
def test_invalid_block_suggestion ( self ) :
# See #7876
try :
2013-10-19 12:31:38 +00:00
Template ( " { % i f 1 % }lala { % e ndblock % } { % e ndif % } " )
2012-04-28 16:09:37 +00:00
except TemplateSyntaxError as e :
2011-12-09 22:13:27 +00:00
self . assertEqual ( e . args [ 0 ] , " Invalid block tag: ' endblock ' , expected ' elif ' , ' else ' or ' endif ' " )
2010-02-21 23:38:33 +00:00
2013-02-23 12:13:44 +00:00
def test_ifchanged_concurrency ( self ) :
# Tests for #15849
template = Template ( ' [0 { % f or x in foo % }, { % with var=get_value % } { % i fchanged % } {{ var }} { % e ndifchanged % } { % e ndwith % } { % e ndfor % }] ' )
# Using generator to mimic concurrency.
# The generator is not passed to the 'for' loop, because it does a list(values)
# instead, call gen.next() in the template to control the generator.
def gen ( ) :
yield 1
yield 2
# Simulate that another thread is now rendering.
# When the IfChangeNode stores state at 'self' it stays at '3' and skip the last yielded value below.
iter2 = iter ( [ 1 , 2 , 3 ] )
output2 = template . render ( Context ( { ' foo ' : range ( 3 ) , ' get_value ' : lambda : next ( iter2 ) } ) )
self . assertEqual ( output2 , ' [0,1,2,3] ' , ' Expected [0,1,2,3] in second parallel template, got {0} ' . format ( output2 ) )
yield 3
gen1 = gen ( )
output1 = template . render ( Context ( { ' foo ' : range ( 3 ) , ' get_value ' : lambda : next ( gen1 ) } ) )
self . assertEqual ( output1 , ' [0,1,2,3] ' , ' Expected [0,1,2,3] in first template, got {0} ' . format ( output1 ) )
2013-03-25 08:10:32 +00:00
def test_cache_regression_20130 ( self ) :
t = Template ( ' { % lo ad cache % } { % c ache 1 regression_20130 % }foo { % e ndcache % } ' )
cachenode = t . nodelist [ 1 ]
self . assertEqual ( cachenode . fragment_name , ' regression_20130 ' )
2013-10-03 21:36:21 +00:00
@override_settings ( CACHES = {
' default ' : {
' BACKEND ' : ' django.core.cache.backends.locmem.LocMemCache ' ,
' LOCATION ' : ' default ' ,
} ,
' template_fragments ' : {
' BACKEND ' : ' django.core.cache.backends.locmem.LocMemCache ' ,
' LOCATION ' : ' fragments ' ,
} ,
} )
def test_cache_fragment_cache ( self ) :
"""
When a cache called " template_fragments " is present , the cache tag
will use it in preference to ' default '
"""
t1 = Template ( ' { % lo ad cache % } { % c ache 1 fragment % }foo { % e ndcache % } ' )
t2 = Template ( ' { % lo ad cache % } { % c ache 1 fragment using= " default " % }bar { % e ndcache % } ' )
ctx = Context ( )
o1 = t1 . render ( ctx )
o2 = t2 . render ( ctx )
self . assertEqual ( o1 , ' foo ' )
2013-10-18 22:49:24 +00:00
self . assertEqual ( o2 , ' bar ' )
2013-10-03 21:36:21 +00:00
def test_cache_missing_backend ( self ) :
"""
When a cache that doesn ' t exist is specified, the cache tag will
raise a TemplateSyntaxError
' " " "
t = Template ( ' { % lo ad cache % } { % c ache 1 backend using= " unknown " % }bar { % e ndcache % } ' )
ctx = Context ( )
with self . assertRaises ( TemplateSyntaxError ) :
t . render ( ctx )
2013-02-24 15:49:28 +00:00
def test_ifchanged_render_once ( self ) :
""" Test for ticket #19890. The content of ifchanged template tag was
rendered twice . """
2014-03-27 20:24:19 +00:00
template = Template ( ' { % i fchanged % } { % c ycle " 1st time " " 2nd time " % } { % e ndifchanged % } ' )
2013-02-24 21:47:14 +00:00
output = template . render ( Context ( { } ) )
self . assertEqual ( output , ' 1st time ' )
2013-02-24 15:49:28 +00:00
2013-05-30 07:25:58 +00:00
def test_super_errors ( self ) :
"""
Test behavior of the raise errors into included blocks .
See #18169
"""
t = loader . get_template ( ' included_content.html ' )
with self . assertRaises ( urlresolvers . NoReverseMatch ) :
t . render ( Context ( { } ) )
2013-06-06 12:27:00 +00:00
2013-11-28 13:22:07 +00:00
# Set ALLOWED_INCLUDE_ROOTS so that ssi works.
@override_settings ( MEDIA_URL = " /media/ " , STATIC_URL = " /static/ " ,
TEMPLATE_DEBUG = False , ALLOWED_INCLUDE_ROOTS = (
os . path . dirname ( os . path . abspath ( upath ( __file__ ) ) ) , ) ,
2014-04-05 06:04:46 +00:00
ROOT_URLCONF = ' template_tests.urls ' ,
2013-11-28 13:22:07 +00:00
)
2014-01-26 13:29:04 +00:00
class TemplateTests ( TestCase ) :
2014-01-14 15:43:27 +00:00
2006-08-27 13:59:47 +00:00
def test_templates ( self ) :
2007-11-14 12:58:53 +00:00
template_tests = self . get_template_tests ( )
filter_tests = filters . get_filter_tests ( )
2006-08-27 13:59:47 +00:00
2007-11-14 12:58:53 +00:00
# Quickly check that we aren't accidentally using a name in both
# template and filter tests.
2008-06-26 04:30:06 +00:00
overlapping_names = [ name for name in filter_tests if name in template_tests ]
2007-11-14 12:58:53 +00:00
assert not overlapping_names , ' Duplicate test name(s): %s ' % ' , ' . join ( overlapping_names )
template_tests . update ( filter_tests )
2011-04-17 04:52:17 +00:00
cache_loader = setup_test_template_loader (
2013-08-29 23:20:00 +00:00
dict ( ( name , t [ 0 ] ) for name , t in six . iteritems ( template_tests ) ) ,
2011-04-17 04:52:17 +00:00
use_cached_loader = True ,
)
2007-11-14 12:58:53 +00:00
failures = [ ]
2012-08-14 10:03:45 +00:00
tests = sorted ( template_tests . items ( ) )
2007-11-14 12:58:53 +00:00
2008-06-26 04:30:06 +00:00
# Set TEMPLATE_STRING_IF_INVALID to a known string.
2007-11-14 12:58:53 +00:00
expected_invalid_str = ' INVALID '
2010-04-19 14:18:14 +00:00
# Warm the URL reversing cache. This ensures we don't pay the cost
# warming the cache during one of the tests.
2013-02-26 12:19:18 +00:00
urlresolvers . reverse ( ' template_tests.views.client_action ' ,
2013-10-26 19:15:03 +00:00
kwargs = { ' id ' : 0 , ' action ' : " update " } )
2010-04-19 14:18:14 +00:00
2007-11-14 12:58:53 +00:00
for name , vals in tests :
if isinstance ( vals [ 2 ] , tuple ) :
normal_string_result = vals [ 2 ] [ 0 ]
invalid_string_result = vals [ 2 ] [ 1 ]
2011-02-04 17:10:21 +00:00
if isinstance ( invalid_string_result , tuple ) :
2007-11-14 12:58:53 +00:00
expected_invalid_str = ' INVALID %s '
2011-02-04 17:10:21 +00:00
invalid_string_result = invalid_string_result [ 0 ] % invalid_string_result [ 1 ]
2010-11-27 05:47:30 +00:00
template_base . invalid_var_format_string = True
2011-02-04 17:10:21 +00:00
try :
template_debug_result = vals [ 2 ] [ 2 ]
except IndexError :
template_debug_result = normal_string_result
2007-11-14 12:58:53 +00:00
else :
normal_string_result = vals [ 2 ]
invalid_string_result = vals [ 2 ]
2011-02-04 17:10:21 +00:00
template_debug_result = vals [ 2 ]
2007-11-14 12:58:53 +00:00
2014-01-26 13:29:04 +00:00
with translation . override ( vals [ 1 ] . get ( ' LANGUAGE_CODE ' , ' en-us ' ) ) :
2013-11-28 13:22:07 +00:00
2014-01-26 13:29:04 +00:00
for invalid_str , template_debug , result in [
( ' ' , False , normal_string_result ) ,
( expected_invalid_str , False , invalid_string_result ) ,
( ' ' , True , template_debug_result )
] :
with override_settings ( TEMPLATE_STRING_IF_INVALID = invalid_str ,
TEMPLATE_DEBUG = template_debug ) :
for is_cached in ( False , True ) :
2013-11-28 13:22:07 +00:00
try :
2014-01-26 13:29:04 +00:00
try :
with warnings . catch_warnings ( ) :
2014-02-16 12:23:16 +00:00
# Ignore pending deprecations of loading 'ssi' and 'url' tags from future.
2014-02-26 21:48:20 +00:00
warnings . filterwarnings ( " ignore " , category = RemovedInDjango19Warning , module = ' django.templatetags.future ' )
2014-03-27 20:24:19 +00:00
# Ignore deprecations of loading 'cycle' and 'firstof' tags from future.
warnings . filterwarnings ( " ignore " , category = RemovedInDjango20Warning , module = " django.templatetags.future " )
2014-01-26 13:29:04 +00:00
test_template = loader . get_template ( name )
except ShouldNotExecuteException :
failures . append ( " Template test (Cached= ' %s ' , TEMPLATE_STRING_IF_INVALID= ' %s ' , TEMPLATE_DEBUG= %s ): %s -- FAILED. Template loading invoked method that shouldn ' t have been invoked. " % ( is_cached , invalid_str , template_debug , name ) )
try :
2014-03-21 12:32:01 +00:00
output = self . render ( test_template , vals )
2014-01-26 13:29:04 +00:00
except ShouldNotExecuteException :
failures . append ( " Template test (Cached= ' %s ' , TEMPLATE_STRING_IF_INVALID= ' %s ' , TEMPLATE_DEBUG= %s ): %s -- FAILED. Template rendering invoked method that shouldn ' t have been invoked. " % ( is_cached , invalid_str , template_debug , name ) )
except ContextStackException :
failures . append ( " Template test (Cached= ' %s ' , TEMPLATE_STRING_IF_INVALID= ' %s ' , TEMPLATE_DEBUG= %s ): %s -- FAILED. Context stack was left imbalanced " % ( is_cached , invalid_str , template_debug , name ) )
continue
except Exception :
exc_type , exc_value , exc_tb = sys . exc_info ( )
if exc_type != result :
tb = ' \n ' . join ( traceback . format_exception ( exc_type , exc_value , exc_tb ) )
failures . append ( " Template test (Cached= ' %s ' , TEMPLATE_STRING_IF_INVALID= ' %s ' , TEMPLATE_DEBUG= %s ): %s -- FAILED. Got %s , exception: %s \n %s " % ( is_cached , invalid_str , template_debug , name , exc_type , exc_value , tb ) )
continue
if output != result :
failures . append ( " Template test (Cached= ' %s ' , TEMPLATE_STRING_IF_INVALID= ' %s ' , TEMPLATE_DEBUG= %s ): %s -- FAILED. Expected %r , got %r " % ( is_cached , invalid_str , template_debug , name , result , output ) )
cache_loader . reset ( )
if template_base . invalid_var_format_string :
expected_invalid_str = ' INVALID '
template_base . invalid_var_format_string = False
2007-11-14 12:58:53 +00:00
2011-04-17 04:52:17 +00:00
restore_template_loaders ( )
2007-11-14 12:58:53 +00:00
2009-03-30 16:05:57 +00:00
self . assertEqual ( failures , [ ] , " Tests failed: \n %s \n %s " %
2013-11-02 21:34:05 +00:00
( ' - ' * 70 , ( " \n %s \n " % ( ' - ' * 70 ) ) . join ( failures ) ) )
2007-11-14 12:58:53 +00:00
def render ( self , test_template , vals ) :
2009-04-07 22:02:34 +00:00
context = template . Context ( vals [ 1 ] )
before_stack_size = len ( context . dicts )
output = test_template . render ( context )
if len ( context . dicts ) != before_stack_size :
raise ContextStackException
return output
2007-11-14 12:58:53 +00:00
def get_template_tests ( self ) :
2006-08-27 13:59:47 +00:00
# SYNTAX --
# 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class)
2014-03-15 11:33:04 +00:00
# This import is necessary when tests are run isolated:
2014-03-21 10:24:45 +00:00
from . templatetags import custom # noqa
2012-12-08 10:13:52 +00:00
basedir = os . path . dirname ( os . path . abspath ( upath ( __file__ ) ) )
2011-08-25 23:02:15 +00:00
tests = {
2007-11-14 12:58:53 +00:00
### BASIC SYNTAX ################################################
2006-08-27 13:59:47 +00:00
# Plain text should go through the template parser untouched
' basic-syntax01 ' : ( " something cool " , { } , " something cool " ) ,
2007-11-14 12:58:53 +00:00
# Variables should be replaced with their value in the current
# context
2013-10-26 19:15:03 +00:00
' basic-syntax02 ' : ( " {{ headline }} " , { ' headline ' : ' Success ' } , " Success " ) ,
2006-08-27 13:59:47 +00:00
# More than one replacement variable is allowed in a template
2013-10-27 01:27:42 +00:00
' basic-syntax03 ' : ( " {{ first }} --- {{ second }} " , { " first " : 1 , " second " : 2 } , " 1 --- 2 " ) ,
2006-08-27 13:59:47 +00:00
# Fail silently when a variable is not found in the current context
2013-10-26 19:15:03 +00:00
' basic-syntax04 ' : ( " as {{ missing }}df " , { } , ( " asdf " , " asINVALIDdf " ) ) ,
2006-08-27 13:59:47 +00:00
# A variable may not contain more than one word
' basic-syntax06 ' : ( " {{ multi word variable }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for empty variable tags
2013-11-02 19:37:48 +00:00
' basic-syntax07 ' : ( " {{ }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
' basic-syntax08 ' : ( " {{ }} " , { } , template . TemplateSyntaxError ) ,
# Attribute syntax allows a template to call an object's attribute
' basic-syntax09 ' : ( " {{ var.method }} " , { " var " : SomeClass ( ) } , " SomeClass.method " ) ,
# Multiple levels of attribute access are allowed
' basic-syntax10 ' : ( " {{ var.otherclass.method }} " , { " var " : SomeClass ( ) } , " OtherClass.method " ) ,
# Fail silently when a variable's attribute isn't found
2013-10-26 19:15:03 +00:00
' basic-syntax11 ' : ( " {{ var.blech }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 13:59:47 +00:00
# Raise TemplateSyntaxError when trying to access a variable beginning with an underscore
' basic-syntax12 ' : ( " {{ var.__dict__ }} " , { " var " : SomeClass ( ) } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError when trying to access a variable containing an illegal character
' basic-syntax13 ' : ( " {{ va>r }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax14 ' : ( " {{ (var.r) }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax15 ' : ( " {{ sp %a m }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax16 ' : ( " {{ eggs! }} " , { } , template . TemplateSyntaxError ) ,
' basic-syntax17 ' : ( " {{ moo? }} " , { } , template . TemplateSyntaxError ) ,
# Attribute syntax allows a template to call a dictionary key's value
2013-10-26 19:15:03 +00:00
' basic-syntax18 ' : ( " {{ foo.bar }} " , { " foo " : { " bar " : " baz " } } , " baz " ) ,
2006-08-27 13:59:47 +00:00
# Fail silently when a variable's dictionary key isn't found
2013-10-26 19:15:03 +00:00
' basic-syntax19 ' : ( " {{ foo.spam }} " , { " foo " : { " bar " : " baz " } } , ( " " , " INVALID " ) ) ,
2006-08-27 13:59:47 +00:00
# Fail silently when accessing a non-simple method
2013-10-26 19:15:03 +00:00
' basic-syntax20 ' : ( " {{ var.method2 }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 13:59:47 +00:00
2013-09-08 13:07:12 +00:00
# Don't silence a TypeError if it was raised inside a callable
' basic-syntax20b ' : ( " {{ var.method5 }} " , { " var " : SomeClass ( ) } , TypeError ) ,
2007-04-27 12:16:22 +00:00
# Don't get confused when parsing something that is almost, but not
# quite, a template tag.
' basic-syntax21 ' : ( " a {{ moo % } b " , { } , " a {{ moo % } b " ) ,
' basic-syntax22 ' : ( " {{ moo #} " , { } , " {{ moo #} " ) ,
# Will try to treat "moo #} {{ cow" as the variable. Not ideal, but
# costly to work around, so this triggers an error.
' basic-syntax23 ' : ( " {{ moo #} {{ cow }} " , { " cow " : " cow " } , template . TemplateSyntaxError ) ,
# Embedded newlines make it not-a-tag.
' basic-syntax24 ' : ( " {{ moo \n }} " , { } , " {{ moo \n }} " ) ,
2007-11-28 21:04:05 +00:00
# Literal strings are permitted inside variables, mostly for i18n
# purposes.
' basic-syntax25 ' : ( ' {{ " fred " }} ' , { } , " fred " ) ,
' basic-syntax26 ' : ( r ' {{ " \ " fred \ " " }} ' , { } , " \" fred \" " ) ,
' basic-syntax27 ' : ( r ' {{ _( " \ " fred \ " " ) }} ' , { } , " \" fred \" " ) ,
2010-03-20 20:27:57 +00:00
# regression test for ticket #12554
# make sure a silent_variable_failure Exception is supressed
2010-03-22 19:08:04 +00:00
# on dictionary and attribute lookup
2010-03-20 20:27:57 +00:00
' basic-syntax28 ' : ( " {{ a.b }} " , { ' a ' : SilentGetItemClass ( ) } , ( ' ' , ' INVALID ' ) ) ,
2010-03-22 19:08:04 +00:00
' basic-syntax29 ' : ( " {{ a.b }} " , { ' a ' : SilentAttrClass ( ) } , ( ' ' , ' INVALID ' ) ) ,
2010-03-20 20:27:57 +00:00
2010-10-11 12:55:17 +00:00
# Something that starts like a number but has an extra lookup works as a lookup.
' basic-syntax30 ' : ( " {{ 1.2.3 }} " , { " 1 " : { " 2 " : { " 3 " : " d " } } } , " d " ) ,
' basic-syntax31 ' : ( " {{ 1.2.3 }} " , { " 1 " : { " 2 " : ( " a " , " b " , " c " , " d " ) } } , " d " ) ,
' basic-syntax32 ' : ( " {{ 1.2.3 }} " , { " 1 " : ( ( " x " , " x " , " x " , " x " ) , ( " y " , " y " , " y " , " y " ) , ( " a " , " b " , " c " , " d " ) ) } , " d " ) ,
' basic-syntax33 ' : ( " {{ 1.2.3 }} " , { " 1 " : ( " xxxx " , " yyyy " , " abcd " ) } , " d " ) ,
' basic-syntax34 ' : ( " {{ 1.2.3 }} " , { " 1 " : ( { " x " : " x " } , { " y " : " y " } , { " z " : " z " , " 3 " : " d " } ) } , " d " ) ,
# Numbers are numbers even if their digits are in the context.
' basic-syntax35 ' : ( " {{ 1 }} " , { " 1 " : " abc " } , " 1 " ) ,
' basic-syntax36 ' : ( " {{ 1.2 }} " , { " 1 " : " abc " } , " 1.2 " ) ,
2010-08-03 15:34:52 +00:00
2010-12-19 23:47:24 +00:00
# Call methods in the top level of the context
' basic-syntax37 ' : ( ' {{ callable }} ' , { " callable " : lambda : " foo bar " } , " foo bar " ) ,
# Call methods returned from dictionary lookups
' basic-syntax38 ' : ( ' {{ var.callable }} ' , { " var " : { " callable " : lambda : " foo bar " } } , " foo bar " ) ,
2012-04-10 20:49:45 +00:00
' builtins01 ' : ( ' {{ True }} ' , { } , " True " ) ,
' builtins02 ' : ( ' {{ False }} ' , { } , " False " ) ,
' builtins03 ' : ( ' {{ None }} ' , { } , " None " ) ,
2007-02-27 20:25:27 +00:00
# List-index syntax allows a template to access a certain item of a subscriptable object.
' list-index01 ' : ( " {{ var.1 }} " , { " var " : [ " first item " , " second item " ] } , " second item " ) ,
# Fail silently when the list index is out of range.
' list-index02 ' : ( " {{ var.5 }} " , { " var " : [ " first item " , " second item " ] } , ( " " , " INVALID " ) ) ,
# Fail silently when the variable is not a subscriptable object.
' list-index03 ' : ( " {{ var.1 }} " , { " var " : None } , ( " " , " INVALID " ) ) ,
# Fail silently when variable is a dict without the specified key.
' list-index04 ' : ( " {{ var.1 }} " , { " var " : { } } , ( " " , " INVALID " ) ) ,
# Dictionary lookup wins out when dict's key is a string.
' list-index05 ' : ( " {{ var.1 }} " , { " var " : { ' 1 ' : " hello " } } , " hello " ) ,
# But list-index lookup wins out when dict's key is an int, which
# behind the scenes is really a dictionary lookup (for a dict)
# after converting the key to an int.
' list-index06 ' : ( " {{ var.1 }} " , { " var " : { 1 : " hello " } } , " hello " ) ,
# Dictionary lookup wins out when there is a string and int version of the key.
' list-index07 ' : ( " {{ var.1 }} " , { " var " : { ' 1 ' : " hello " , 1 : " world " } } , " hello " ) ,
2007-03-30 01:50:06 +00:00
2006-08-27 13:59:47 +00:00
# Basic filter usage
2007-04-27 11:01:45 +00:00
' filter-syntax01 ' : ( " {{ var|upper }} " , { " var " : " Django is the greatest! " } , " DJANGO IS THE GREATEST! " ) ,
2006-08-27 13:59:47 +00:00
# Chained filters
2007-04-27 11:01:45 +00:00
' filter-syntax02 ' : ( " {{ var|upper|lower }} " , { " var " : " Django is the greatest! " } , " django is the greatest! " ) ,
2006-08-27 13:59:47 +00:00
2012-04-30 19:01:06 +00:00
# Allow spaces before the filter pipe
' filter-syntax03 ' : ( " {{ var |upper }} " , { " var " : " Django is the greatest! " } , " DJANGO IS THE GREATEST! " ) ,
2006-08-27 13:59:47 +00:00
2012-04-30 19:01:06 +00:00
# Allow spaces after the filter pipe
' filter-syntax04 ' : ( " {{ var| upper }} " , { " var " : " Django is the greatest! " } , " DJANGO IS THE GREATEST! " ) ,
2006-08-27 13:59:47 +00:00
# Raise TemplateSyntaxError for a nonexistent filter
2007-04-27 11:01:45 +00:00
' filter-syntax05 ' : ( " {{ var|does_not_exist }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
# Raise TemplateSyntaxError when trying to access a filter containing an illegal character
2007-04-27 11:01:45 +00:00
' filter-syntax06 ' : ( " {{ var|fil(ter) }} " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
# Raise TemplateSyntaxError for invalid block tags
2007-04-27 11:01:45 +00:00
' filter-syntax07 ' : ( " { % nothing_to_see_here % } " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
# Raise TemplateSyntaxError for empty block tags
2007-04-27 11:01:45 +00:00
' filter-syntax08 ' : ( " { % % } " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
# Chained filters, with an argument to the first one
2007-04-27 11:01:45 +00:00
' filter-syntax09 ' : ( ' {{ var|removetags: " b i " |upper|lower }} ' , { " var " : " <b><i>Yes</i></b> " } , " yes " ) ,
2006-08-27 13:59:47 +00:00
2007-11-17 12:11:26 +00:00
# Literal string as argument is always "safe" from auto-escaping..
2007-11-14 12:58:53 +00:00
' filter-syntax10 ' : ( r ' {{ var|default_if_none: " endquote \ " hah " }} ' ,
2007-11-17 12:11:26 +00:00
{ " var " : None } , ' endquote " hah ' ) ,
2006-08-27 13:59:47 +00:00
# Variable as argument
2007-04-27 11:01:45 +00:00
' filter-syntax11 ' : ( r ' {{ var|default_if_none:var2 }} ' , { " var " : None , " var2 " : " happy " } , ' happy ' ) ,
2006-08-27 13:59:47 +00:00
# Default argument testing
2007-04-27 11:01:45 +00:00
' filter-syntax12 ' : ( r ' {{ var|yesno: " yup,nup,mup " }} {{ var|yesno }} ' , { " var " : True } , ' yup yes ' ) ,
2006-08-27 13:59:47 +00:00
2007-04-27 11:01:45 +00:00
# Fail silently for methods that raise an exception with a
# "silent_variable_failure" attribute
' filter-syntax13 ' : ( r ' 1 {{ var.method3 }}2 ' , { " var " : SomeClass ( ) } , ( " 12 " , " 1INVALID2 " ) ) ,
2006-08-27 13:59:47 +00:00
2007-04-27 11:01:45 +00:00
# In methods that raise an exception without a
# "silent_variable_attribute" set to True, the exception propagates
2011-09-16 01:16:25 +00:00
' filter-syntax14 ' : ( r ' 1 {{ var.method4 }}2 ' , { " var " : SomeClass ( ) } , ( SomeOtherException , SomeOtherException ) ) ,
2006-08-27 13:59:47 +00:00
# Escaped backslash in argument
2007-04-27 11:01:45 +00:00
' filter-syntax15 ' : ( r ' {{ var|default_if_none: " foo \ bar " }} ' , { " var " : None } , r ' foo \ bar ' ) ,
2006-08-27 13:59:47 +00:00
# Escaped backslash using known escape char
2007-04-27 11:01:45 +00:00
' filter-syntax16 ' : ( r ' {{ var|default_if_none: " foo \ now " }} ' , { " var " : None } , r ' foo \ now ' ) ,
2006-08-27 13:59:47 +00:00
2006-09-26 07:26:07 +00:00
# Empty strings can be passed as arguments to filters
2007-04-27 11:01:45 +00:00
' filter-syntax17 ' : ( r ' {{ var|join: " " }} ' , { ' var ' : [ ' a ' , ' b ' , ' c ' ] } , ' abc ' ) ,
2006-09-26 07:26:07 +00:00
Merged Unicode branch into trunk (r4952:5608). This should be fully
backwards compatible for all practical purposes.
Fixed #2391, #2489, #2996, #3322, #3344, #3370, #3406, #3432, #3454, #3492, #3582, #3690, #3878, #3891, #3937, #4039, #4141, #4227, #4286, #4291, #4300, #4452, #4702
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2007-07-04 12:11:04 +00:00
# Make sure that any unicode strings are converted to bytestrings
# in the final output.
2012-06-07 16:08:47 +00:00
' filter-syntax18 ' : ( r ' {{ var }} ' , { ' var ' : UTF8Class ( ) } , ' \u0160 \u0110 \u0106 \u017d \u0107 \u017e \u0161 \u0111 ' ) ,
2006-12-05 19:48:46 +00:00
2007-06-27 18:58:10 +00:00
# Numbers as filter arguments should work
' filter-syntax19 ' : ( ' {{ var|truncatewords:1 }} ' , { " var " : " hello world " } , " hello ... " ) ,
2008-10-06 06:34:54 +00:00
2013-11-02 21:02:56 +00:00
# filters should accept empty string constants
2008-08-15 21:08:11 +00:00
' filter-syntax20 ' : ( ' {{ " " |default_if_none: " was none " }} ' , { } , " " ) ,
2010-10-11 12:55:17 +00:00
2010-12-19 23:47:24 +00:00
# Fail silently for non-callable attribute and dict lookups which
# raise an exception with a "silent_variable_failure" attribute
' filter-syntax21 ' : ( r ' 1 {{ var.silent_fail_key }}2 ' , { " var " : SomeClass ( ) } , ( " 12 " , " 1INVALID2 " ) ) ,
' filter-syntax22 ' : ( r ' 1 {{ var.silent_fail_attribute }}2 ' , { " var " : SomeClass ( ) } , ( " 12 " , " 1INVALID2 " ) ) ,
# In attribute and dict lookups that raise an unexpected exception
# without a "silent_variable_attribute" set to True, the exception
# propagates
2011-09-16 01:16:25 +00:00
' filter-syntax23 ' : ( r ' 1 {{ var.noisy_fail_key }}2 ' , { " var " : SomeClass ( ) } , ( SomeOtherException , SomeOtherException ) ) ,
' filter-syntax24 ' : ( r ' 1 {{ var.noisy_fail_attribute }}2 ' , { " var " : SomeClass ( ) } , ( SomeOtherException , SomeOtherException ) ) ,
2010-12-19 23:47:24 +00:00
2006-10-24 21:30:38 +00:00
### COMMENT SYNTAX ########################################################
' comment-syntax01 ' : ( " { # this is hidden #}hello " , { } , " hello " ) ,
' comment-syntax02 ' : ( " { # this is hidden #}hello { # foo #} " , { } , " hello " ) ,
# Comments can contain invalid stuff.
' comment-syntax03 ' : ( " foo { # { % i f % } #} " , { } , " foo " ) ,
' comment-syntax04 ' : ( " foo { # { % e ndblock % } #} " , { } , " foo " ) ,
' comment-syntax05 ' : ( " foo { # { % s omerandomtag % } #} " , { } , " foo " ) ,
' comment-syntax06 ' : ( " foo { # { % #} " , { } , " foo " ) ,
' comment-syntax07 ' : ( " foo { # % } #} " , { } , " foo " ) ,
' comment-syntax08 ' : ( " foo { # % } #}bar " , { } , " foobar " ) ,
' comment-syntax09 ' : ( " foo { # {{ #} " , { } , " foo " ) ,
' comment-syntax10 ' : ( " foo { # }} #} " , { } , " foo " ) ,
' comment-syntax11 ' : ( " foo { # { #} " , { } , " foo " ) ,
' comment-syntax12 ' : ( " foo { # } #} " , { } , " foo " ) ,
2006-08-27 13:59:47 +00:00
### COMMENT TAG ###########################################################
' comment-tag01 ' : ( " { % c omment % }this is hidden { % e ndcomment % }hello " , { } , " hello " ) ,
' comment-tag02 ' : ( " { % c omment % }this is hidden { % e ndcomment % }hello { % c omment % }foo { % e ndcomment % } " , { } , " hello " ) ,
# Comment tag can contain invalid stuff.
' comment-tag03 ' : ( " foo { % c omment % } { % i f % } { % e ndcomment % } " , { } , " foo " ) ,
' comment-tag04 ' : ( " foo { % c omment % } { % e ndblock % } { % e ndcomment % } " , { } , " foo " ) ,
' comment-tag05 ' : ( " foo { % c omment % } { % s omerandomtag % } { % e ndcomment % } " , { } , " foo " ) ,
### CYCLE TAG #############################################################
' cycle01 ' : ( ' { % c ycle a % } ' , { } , template . TemplateSyntaxError ) ,
' cycle02 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } ' , { } , ' ab ' ) ,
' cycle03 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } { % c ycle abc % } ' , { } , ' abc ' ) ,
' cycle04 ' : ( ' { % c ycle a,b,c as abc % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } ' , { } , ' abca ' ) ,
' cycle05 ' : ( ' { % c ycle % } ' , { } , template . TemplateSyntaxError ) ,
' cycle06 ' : ( ' { % c ycle a % } ' , { } , template . TemplateSyntaxError ) ,
' cycle07 ' : ( ' { % c ycle a,b,c as foo % } { % c ycle bar % } ' , { } , template . TemplateSyntaxError ) ,
2006-09-21 13:09:00 +00:00
' cycle08 ' : ( ' { % c ycle a,b,c as foo % } { % c ycle foo % } {{ foo }} {{ foo }} { % c ycle foo % } {{ foo }} ' , { } , ' abbbcc ' ) ,
2007-09-14 02:49:21 +00:00
' cycle09 ' : ( " { % f or i in test % } { % c ycle a,b % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) } , ' a0,b1,a2,b3,a4, ' ) ,
' cycle10 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } " , { } , ' ab ' ) ,
' cycle11 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } { % c ycle abc % } " , { } , ' abc ' ) ,
' cycle12 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } " , { } , ' abca ' ) ,
' cycle13 ' : ( " { % f or i in test % } { % c ycle ' a ' ' b ' % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) } , ' a0,b1,a2,b3,a4, ' ) ,
2013-10-26 19:15:03 +00:00
' cycle14 ' : ( " { % c ycle one two as foo % } { % c ycle foo % } " , { ' one ' : ' 1 ' , ' two ' : ' 2 ' } , ' 12 ' ) ,
2009-03-01 06:54:38 +00:00
' cycle15 ' : ( " { % f or i in test % } { % c ycle aye bee % } {{ i }}, { % e ndfor % } " , { ' test ' : range ( 5 ) , ' aye ' : ' a ' , ' bee ' : ' b ' } , ' a0,b1,a2,b3,a4, ' ) ,
2013-10-26 19:15:03 +00:00
' cycle16 ' : ( " { % c ycle one|lower two as foo % } { % c ycle foo % } " , { ' one ' : ' A ' , ' two ' : ' 2 ' } , ' a2 ' ) ,
2011-03-08 13:43:53 +00:00
' cycle17 ' : ( " { % c ycle ' a ' ' b ' ' c ' as abc silent % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } { % c ycle abc % } " , { } , " " ) ,
2010-11-02 13:42:30 +00:00
' cycle18 ' : ( " { % c ycle ' a ' ' b ' ' c ' as foo invalid_flag % } " , { } , template . TemplateSyntaxError ) ,
' cycle19 ' : ( " { % c ycle ' a ' ' b ' as silent % } { % c ycle silent % } " , { } , " ab " ) ,
2014-03-21 17:17:10 +00:00
' cycle20 ' : ( " { % c ycle one two as foo % } & { % c ycle foo % } " , { ' one ' : ' A & B ' , ' two ' : ' C & D ' } , " A & B & C & D " ) ,
' cycle21 ' : ( " { % f ilter force_escape % } { % c ycle one two as foo % } & { % c ycle foo % } { % e ndfilter % } " , { ' one ' : ' A & B ' , ' two ' : ' C & D ' } , " A &amp; B & C &amp; D " ) ,
2013-10-26 19:15:03 +00:00
' cycle22 ' : ( " { % f or x in values % } { % c ycle ' a ' ' b ' ' c ' as abc silent % } {{ x }} { % e ndfor % } " , { ' values ' : [ 1 , 2 , 3 , 4 ] } , " 1234 " ) ,
' cycle23 ' : ( " { % f or x in values % } { % c ycle ' a ' ' b ' ' c ' as abc silent % } {{ abc }} {{ x }} { % e ndfor % } " , { ' values ' : [ 1 , 2 , 3 , 4 ] } , " a1b2c3a4 " ) ,
2011-03-08 13:43:53 +00:00
' included-cycle ' : ( ' {{ abc }} ' , { ' abc ' : ' xxx ' } , ' xxx ' ) ,
2013-10-26 19:15:03 +00:00
' cycle24 ' : ( " { % f or x in values % } { % c ycle ' a ' ' b ' ' c ' as abc silent % } { % i nclude ' included-cycle ' % } { % e ndfor % } " , { ' values ' : [ 1 , 2 , 3 , 4 ] } , " abca " ) ,
2014-03-21 17:17:10 +00:00
' cycle25 ' : ( ' { % c ycle a as abc % } ' , { ' a ' : ' < ' } , ' < ' ) ,
2013-02-23 14:07:21 +00:00
' cycle26 ' : ( ' { % lo ad cycle from future % } { % c ycle a b as ab % } { % c ycle ab % } ' , { ' a ' : ' < ' , ' b ' : ' > ' } , ' <> ' ) ,
' cycle27 ' : ( ' { % lo ad cycle from future % } { % a utoescape off % } { % c ycle a b as ab % } { % c ycle ab % } { % e ndautoescape % } ' , { ' a ' : ' < ' , ' b ' : ' > ' } , ' <> ' ) ,
' cycle28 ' : ( ' { % lo ad cycle from future % } { % c ycle a|safe b as ab % } { % c ycle ab % } ' , { ' a ' : ' < ' , ' b ' : ' > ' } , ' <> ' ) ,
2006-08-27 13:59:47 +00:00
### EXCEPTIONS ############################################################
# Raise exception for invalid template name
2011-09-16 01:16:25 +00:00
' exception01 ' : ( " { % e xtends ' nonexistent ' % } " , { } , ( template . TemplateDoesNotExist , template . TemplateDoesNotExist ) ) ,
2006-08-27 13:59:47 +00:00
# Raise exception for invalid template name (in variable)
2010-03-16 14:34:57 +00:00
' exception02 ' : ( " { % e xtends nonexistent % } " , { } , ( template . TemplateSyntaxError , template . TemplateDoesNotExist ) ) ,
2006-08-27 13:59:47 +00:00
# Raise exception for extra {% extends %} tags
' exception03 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % e ndblock % } { % e xtends ' inheritance16 ' % } " , { } , template . TemplateSyntaxError ) ,
# Raise exception for custom tags used in child with {% load %} tag in parent, not in child
' exception04 ' : ( " { % e xtends ' inheritance17 ' % } { % block first % } { % e cho 400 % }5678 { % e ndblock % } " , { } , template . TemplateSyntaxError ) ,
### FILTER TAG ############################################################
' filter01 ' : ( ' { % f ilter upper % } { % e ndfilter % } ' , { } , ' ' ) ,
' filter02 ' : ( ' { % f ilter upper % }django { % e ndfilter % } ' , { } , ' DJANGO ' ) ,
' filter03 ' : ( ' { % f ilter upper|lower % }django { % e ndfilter % } ' , { } , ' django ' ) ,
2007-04-21 04:44:30 +00:00
' filter04 ' : ( ' { % f ilter cut:remove % }djangospam { % e ndfilter % } ' , { ' remove ' : ' spam ' } , ' django ' ) ,
2013-06-25 18:28:35 +00:00
' filter05 ' : ( ' { % f ilter safe % }fail { % e ndfilter % } ' , { } , template . TemplateSyntaxError ) ,
' filter05bis ' : ( ' { % f ilter upper|safe % }fail { % e ndfilter % } ' , { } , template . TemplateSyntaxError ) ,
' filter06 ' : ( ' { % f ilter escape % }fail { % e ndfilter % } ' , { } , template . TemplateSyntaxError ) ,
' filter06bis ' : ( ' { % f ilter upper|escape % }fail { % e ndfilter % } ' , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
### FIRSTOF TAG ###########################################################
2013-10-26 19:15:03 +00:00
' firstof01 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 0 , ' c ' : 0 } , ' ' ) ,
' firstof02 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 1 , ' b ' : 0 , ' c ' : 0 } , ' 1 ' ) ,
' firstof03 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 2 , ' c ' : 0 } , ' 2 ' ) ,
' firstof04 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 0 , ' b ' : 0 , ' c ' : 3 } , ' 3 ' ) ,
' firstof05 ' : ( ' { % f irstof a b c % } ' , { ' a ' : 1 , ' b ' : 2 , ' c ' : 3 } , ' 1 ' ) ,
' firstof06 ' : ( ' { % f irstof a b c % } ' , { ' b ' : 0 , ' c ' : 3 } , ' 3 ' ) ,
' firstof07 ' : ( ' { % f irstof a b " c " % } ' , { ' a ' : 0 } , ' c ' ) ,
' firstof08 ' : ( ' { % f irstof a b " c and d " % } ' , { ' a ' : 0 , ' b ' : 0 } , ' c and d ' ) ,
2007-10-20 15:01:31 +00:00
' firstof09 ' : ( ' { % f irstof % } ' , { } , template . TemplateSyntaxError ) ,
2014-03-21 17:17:10 +00:00
' firstof10 ' : ( ' { % f irstof a % } ' , { ' a ' : ' < ' } , ' < ' ) ,
2013-02-23 14:07:21 +00:00
' firstof11 ' : ( ' { % lo ad firstof from future % } { % f irstof a b % } ' , { ' a ' : ' < ' , ' b ' : ' > ' } , ' < ' ) ,
' firstof12 ' : ( ' { % lo ad firstof from future % } { % f irstof a b % } ' , { ' a ' : ' ' , ' b ' : ' > ' } , ' > ' ) ,
' firstof13 ' : ( ' { % lo ad firstof from future % } { % a utoescape off % } { % f irstof a % } { % e ndautoescape % } ' , { ' a ' : ' < ' } , ' < ' ) ,
' firstof14 ' : ( ' { % lo ad firstof from future % } { % f irstof a|safe b % } ' , { ' a ' : ' < ' } , ' < ' ) ,
2006-08-27 13:59:47 +00:00
### FOR TAG ###############################################################
' for-tag01 ' : ( " { % f or val in values % } {{ val }} { % e ndfor % } " , { " values " : [ 1 , 2 , 3 ] } , " 123 " ) ,
' for-tag02 ' : ( " { % f or val in values reversed % } {{ val }} { % e ndfor % } " , { " values " : [ 1 , 2 , 3 ] } , " 321 " ) ,
' for-tag-vars01 ' : ( " { % f or val in values % } {{ forloop.counter }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 123 " ) ,
' for-tag-vars02 ' : ( " { % f or val in values % } {{ forloop.counter0 }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 012 " ) ,
' for-tag-vars03 ' : ( " { % f or val in values % } {{ forloop.revcounter }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 321 " ) ,
' for-tag-vars04 ' : ( " { % f or val in values % } {{ forloop.revcounter0 }} { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " 210 " ) ,
2008-01-02 05:01:03 +00:00
' for-tag-vars05 ' : ( " { % f or val in values % } { % i f forloop.first % }f { % e lse % }x { % e ndif % } { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " fxx " ) ,
' for-tag-vars06 ' : ( " { % f or val in values % } { % i f forloop.last % }l { % e lse % }x { % e ndif % } { % e ndfor % } " , { " values " : [ 6 , 6 , 6 ] } , " xxl " ) ,
2007-06-08 11:58:03 +00:00
' for-tag-unpack01 ' : ( " { % f or key,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack03 ' : ( " { % f or key, value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack04 ' : ( " { % f or key , value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack05 ' : ( " { % f or key ,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack06 ' : ( " { % f or key value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
' for-tag-unpack07 ' : ( " { % f or key,,value in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
' for-tag-unpack08 ' : ( " { % f or key,value, in items % } {{ key }}: {{ value }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , template . TemplateSyntaxError ) ,
# Ensure that a single loopvar doesn't truncate the list in val.
' for-tag-unpack09 ' : ( " { % f or val in items % } {{ val.0 }}: {{ val.1 }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , " one:1/two:2/ " ) ,
# Otherwise, silently truncate if the length of loopvars differs to the length of each set of items.
' for-tag-unpack10 ' : ( " { % f or x,y in items % } {{ x }}: {{ y }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 , ' orange ' ) ) } , " one:1/two:2/ " ) ,
' for-tag-unpack11 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 ) , ( ' two ' , 2 ) ) } , ( " one:1,/two:2,/ " , " one:1,INVALID/two:2,INVALID/ " ) ) ,
' for-tag-unpack12 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 ) ) } , ( " one:1,carrot/two:2,/ " , " one:1,carrot/two:2,INVALID/ " ) ) ,
' for-tag-unpack13 ' : ( " { % f or x,y,z in items % } {{ x }}: {{ y }}, {{ z }}/ { % e ndfor % } " , { " items " : ( ( ' one ' , 1 , ' carrot ' ) , ( ' two ' , 2 , ' cheese ' ) ) } , ( " one:1,carrot/two:2,cheese/ " , " one:1,carrot/two:2,cheese/ " ) ) ,
2010-09-07 20:30:46 +00:00
' for-tag-unpack14 ' : ( " { % f or x,y in items % } {{ x }}: {{ y }}/ { % e ndfor % } " , { " items " : ( 1 , 2 ) } , ( " :/:/ " , " INVALID:INVALID/INVALID:INVALID/ " ) ) ,
2008-11-24 22:33:32 +00:00
' for-tag-empty01 ' : ( " { % f or val in values % } {{ val }} { % e mpty % }empty text { % e ndfor % } " , { " values " : [ 1 , 2 , 3 ] } , " 123 " ) ,
' for-tag-empty02 ' : ( " { % f or val in values % } {{ val }} { % e mpty % }values array empty { % e ndfor % } " , { " values " : [ ] } , " values array empty " ) ,
' for-tag-empty03 ' : ( " { % f or val in values % } {{ val }} { % e mpty % }values array not found { % e ndfor % } " , { } , " values array not found " ) ,
2013-02-22 18:08:35 +00:00
# Ticket 19882
2013-02-23 09:24:35 +00:00
' for-tag-filter-ws ' : ( " { % lo ad custom % } { % f or x in s|noop: ' x y ' % } {{ x }} { % e ndfor % } " , { ' s ' : ' abc ' } , ' abc ' ) ,
2006-08-27 13:59:47 +00:00
### IF TAG ################################################################
' if-tag01 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { " foo " : True } , " yes " ) ,
' if-tag02 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { " foo " : False } , " no " ) ,
' if-tag03 ' : ( " { % i f foo % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
2011-12-09 22:13:27 +00:00
' if-tag04 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e ndif % } " , { ' foo ' : True } , " foo " ) ,
' if-tag05 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e ndif % } " , { ' bar ' : True } , " bar " ) ,
' if-tag06 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e ndif % } " , { } , " " ) ,
' if-tag07 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lse % }nothing { % e ndif % } " , { ' foo ' : True } , " foo " ) ,
' if-tag08 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lse % }nothing { % e ndif % } " , { ' bar ' : True } , " bar " ) ,
' if-tag09 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lse % }nothing { % e ndif % } " , { } , " nothing " ) ,
' if-tag10 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lif baz % }baz { % e lse % }nothing { % e ndif % } " , { ' foo ' : True } , " foo " ) ,
' if-tag11 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lif baz % }baz { % e lse % }nothing { % e ndif % } " , { ' bar ' : True } , " bar " ) ,
' if-tag12 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lif baz % }baz { % e lse % }nothing { % e ndif % } " , { ' baz ' : True } , " baz " ) ,
' if-tag13 ' : ( " { % i f foo % }foo { % e lif bar % }bar { % e lif baz % }baz { % e lse % }nothing { % e ndif % } " , { } , " nothing " ) ,
2009-12-09 22:40:36 +00:00
# Filters
' if-tag-filter01 ' : ( " { % i f foo|length == 5 % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : ' abcde ' } , " yes " ) ,
' if-tag-filter02 ' : ( " { % i f foo|upper == ' ABC ' % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
# Equality
' if-tag-eq01 ' : ( " { % i f foo == bar % }yes { % e lse % }no { % e ndif % } " , { } , " yes " ) ,
' if-tag-eq02 ' : ( " { % i f foo == bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : 1 } , " no " ) ,
' if-tag-eq03 ' : ( " { % i f foo == bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : 1 , ' bar ' : 1 } , " yes " ) ,
' if-tag-eq04 ' : ( " { % i f foo == bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : 1 , ' bar ' : 2 } , " no " ) ,
' if-tag-eq05 ' : ( " { % i f foo == ' ' % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
# Comparison
' if-tag-gt-01 ' : ( " { % i f 2 > 1 % }yes { % e lse % }no { % e ndif % } " , { } , " yes " ) ,
' if-tag-gt-02 ' : ( " { % i f 1 > 1 % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
' if-tag-gte-01 ' : ( " { % i f 1 >= 1 % }yes { % e lse % }no { % e ndif % } " , { } , " yes " ) ,
' if-tag-gte-02 ' : ( " { % i f 1 >= 2 % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
' if-tag-lt-01 ' : ( " { % i f 1 < 2 % }yes { % e lse % }no { % e ndif % } " , { } , " yes " ) ,
' if-tag-lt-02 ' : ( " { % i f 1 < 1 % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
' if-tag-lte-01 ' : ( " { % i f 1 <= 1 % }yes { % e lse % }no { % e ndif % } " , { } , " yes " ) ,
' if-tag-lte-02 ' : ( " { % i f 2 <= 1 % }yes { % e lse % }no { % e ndif % } " , { } , " no " ) ,
2010-03-08 23:25:37 +00:00
# Contains
2013-10-26 19:15:03 +00:00
' if-tag-in-01 ' : ( " { % i f 1 in x % }yes { % e lse % }no { % e ndif % } " , { ' x ' : [ 1 ] } , " yes " ) ,
' if-tag-in-02 ' : ( " { % i f 2 in x % }yes { % e lse % }no { % e ndif % } " , { ' x ' : [ 1 ] } , " no " ) ,
' if-tag-not-in-01 ' : ( " { % i f 1 not in x % }yes { % e lse % }no { % e ndif % } " , { ' x ' : [ 1 ] } , " no " ) ,
' if-tag-not-in-02 ' : ( " { % i f 2 not in x % }yes { % e lse % }no { % e ndif % } " , { ' x ' : [ 1 ] } , " yes " ) ,
2010-03-08 23:25:37 +00:00
2006-08-27 13:59:47 +00:00
# AND
' if-tag-and01 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-and02 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-and03 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-and04 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-and05 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False } , ' no ' ) ,
' if-tag-and06 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : False } , ' no ' ) ,
' if-tag-and07 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' no ' ) ,
' if-tag-and08 ' : ( " { % i f foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : True } , ' no ' ) ,
# OR
' if-tag-or01 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-or02 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-or03 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-or04 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-or05 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False } , ' no ' ) ,
' if-tag-or06 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : False } , ' no ' ) ,
' if-tag-or07 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' yes ' ) ,
' if-tag-or08 ' : ( " { % i f foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' bar ' : True } , ' yes ' ) ,
2009-12-09 22:40:36 +00:00
# multiple ORs
' if-tag-or09 ' : ( " { % i f foo or bar or baz % }yes { % e lse % }no { % e ndif % } " , { ' baz ' : True } , ' yes ' ) ,
2006-08-27 13:59:47 +00:00
# NOT
' if-tag-not01 ' : ( " { % i f not foo % }no { % e lse % }yes { % e ndif % } " , { ' foo ' : True } , ' yes ' ) ,
2009-12-09 22:40:36 +00:00
' if-tag-not02 ' : ( " { % i f not not foo % }no { % e lse % }yes { % e ndif % } " , { ' foo ' : True } , ' no ' ) ,
# not03 to not05 removed, now TemplateSyntaxErrors
2006-08-27 13:59:47 +00:00
' if-tag-not06 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' no ' ) ,
' if-tag-not07 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not08 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not09 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not10 ' : ( " { % i f foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-not11 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { } , ' no ' ) ,
' if-tag-not12 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not13 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not14 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not15 ' : ( " { % i f not foo and bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' no ' ) ,
' if-tag-not16 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not17 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-not18 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not19 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not20 ' : ( " { % i f foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not21 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not22 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' yes ' ) ,
' if-tag-not23 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not24 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not25 ' : ( " { % i f not foo or bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not26 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not27 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not28 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' no ' ) ,
' if-tag-not29 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' no ' ) ,
' if-tag-not30 ' : ( " { % i f not foo and not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
' if-tag-not31 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { } , ' yes ' ) ,
' if-tag-not32 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : True } , ' no ' ) ,
' if-tag-not33 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True , ' bar ' : False } , ' yes ' ) ,
' if-tag-not34 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : True } , ' yes ' ) ,
' if-tag-not35 ' : ( " { % i f not foo or not bar % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , ' yes ' ) ,
2009-12-09 22:40:36 +00:00
# Various syntax errors
' if-tag-error01 ' : ( " { % i f % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
' if-tag-error02 ' : ( " { % i f foo and % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error03 ' : ( " { % i f foo or % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error04 ' : ( " { % i f not foo and % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
' if-tag-error05 ' : ( " { % i f not foo or % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , template . TemplateSyntaxError ) ,
2009-12-09 22:40:36 +00:00
' if-tag-error06 ' : ( " { % i f abc def % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error07 ' : ( " { % i f not % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error08 ' : ( " { % i f and % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error09 ' : ( " { % i f or % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error10 ' : ( " { % i f == % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error11 ' : ( " { % i f 1 == % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
' if-tag-error12 ' : ( " { % i f a not b % }yes { % e ndif % } " , { } , template . TemplateSyntaxError ) ,
2010-04-19 14:18:14 +00:00
# If evaluations are shortcircuited where possible
2011-09-09 17:54:04 +00:00
# If is_bad is invoked, it will raise a ShouldNotExecuteException
2010-04-19 14:18:14 +00:00
' if-tag-shortcircuit01 ' : ( ' { % i f x.is_true or x.is_bad % }yes { % e lse % }no { % e ndif % } ' , { ' x ' : TestObj ( ) } , " yes " ) ,
' if-tag-shortcircuit02 ' : ( ' { % i f x.is_false and x.is_bad % }yes { % e lse % }no { % e ndif % } ' , { ' x ' : TestObj ( ) } , " no " ) ,
2010-04-12 13:56:38 +00:00
# Non-existent args
2013-10-26 19:15:03 +00:00
' if-tag-badarg01 ' : ( " { % i f x|default_if_none:y % }yes { % e ndif % } " , { } , ' ' ) ,
' if-tag-badarg02 ' : ( " { % i f x|default_if_none:y % }yes { % e ndif % } " , { ' y ' : 0 } , ' ' ) ,
' if-tag-badarg03 ' : ( " { % i f x|default_if_none:y % }yes { % e ndif % } " , { ' y ' : 1 } , ' yes ' ) ,
' if-tag-badarg04 ' : ( " { % i f x|default_if_none:y % }yes { % e lse % }no { % e ndif % } " , { } , ' no ' ) ,
2010-04-12 13:56:38 +00:00
2009-12-09 22:40:36 +00:00
# Additional, more precise parsing tests are in SmartIfTests
2006-08-27 13:59:47 +00:00
### IFCHANGED TAG #########################################################
2013-10-26 19:15:03 +00:00
' ifchanged01 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) } , ' 123 ' ) ,
' ifchanged02 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 3 ) } , ' 13 ' ) ,
' ifchanged03 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) } , ' 1 ' ) ,
2008-06-26 04:25:40 +00:00
' ifchanged04 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) , ' numx ' : ( 2 , 2 , 2 ) } , ' 122232 ' ) ,
' ifchanged05 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 1 , 2 , 3 ) } , ' 1123123123 ' ) ,
' ifchanged06 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 2 , 2 , 2 ) } , ' 1222 ' ) ,
' ifchanged07 ' : ( ' { % f or n in num % } { % i fchanged % } {{ n }} { % e ndifchanged % } { % f or x in numx % } { % i fchanged % } {{ x }} { % e ndifchanged % } { % f or y in numy % } { % i fchanged % } {{ y }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 1 ) , ' numx ' : ( 2 , 2 , 2 ) , ' numy ' : ( 3 , 3 , 3 ) } , ' 1233323332333 ' ) ,
2008-06-26 04:30:06 +00:00
' ifchanged08 ' : ( ' { % f or data in datalist % } { % f or c,d in data % } { % i f c % } { % i fchanged % } {{ d }} { % e ndifchanged % } { % e ndif % } { % e ndfor % } { % e ndfor % } ' , { ' datalist ' : [ [ ( 1 , ' a ' ) , ( 1 , ' a ' ) , ( 0 , ' b ' ) , ( 1 , ' c ' ) ] , [ ( 0 , ' a ' ) , ( 1 , ' c ' ) , ( 1 , ' d ' ) , ( 1 , ' d ' ) , ( 0 , ' e ' ) ] ] } , ' accd ' ) ,
2006-12-05 19:48:46 +00:00
2006-11-07 05:36:51 +00:00
# Test one parameter given to ifchanged.
2013-10-26 19:15:03 +00:00
' ifchanged-param01 ' : ( ' { % f or n in num % } { % i fchanged n % }.. { % e ndifchanged % } {{ n }} { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) } , ' ..1..2..3 ' ) ,
' ifchanged-param02 ' : ( ' { % f or n in num % } { % f or x in numx % } { % i fchanged n % }.. { % e ndifchanged % } {{ x }} { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) , ' numx ' : ( 5 , 6 , 7 ) } , ' ..567..567..567 ' ) ,
2006-12-05 19:48:46 +00:00
2006-11-07 05:36:51 +00:00
# Test multiple parameters to ifchanged.
2013-10-26 19:15:03 +00:00
' ifchanged-param03 ' : ( ' { % f or n in num % } {{ n }} { % f or x in numx % } { % i fchanged x n % } {{ x }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' num ' : ( 1 , 1 , 2 ) , ' numx ' : ( 5 , 6 , 6 ) } , ' 156156256 ' ) ,
2006-12-05 19:48:46 +00:00
2006-11-07 05:36:51 +00:00
# Test a date+hour like construct, where the hour of the last day
# is the same but the date had changed, so print the hour anyway.
2013-10-26 19:15:03 +00:00
' ifchanged-param04 ' : ( ' { % f or d in days % } { % i fchanged % } {{ d.day }} { % e ndifchanged % } { % f or h in d.hours % } { % i fchanged d h % } {{ h }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' days ' : [ { ' day ' : 1 , ' hours ' : [ 1 , 2 , 3 ] } , { ' day ' : 2 , ' hours ' : [ 3 ] } ] } , ' 112323 ' ) ,
2006-12-05 19:48:46 +00:00
2006-11-07 05:36:51 +00:00
# Logically the same as above, just written with explicit
# ifchanged for the day.
2013-10-26 19:15:03 +00:00
' ifchanged-param05 ' : ( ' { % f or d in days % } { % i fchanged d.day % } {{ d.day }} { % e ndifchanged % } { % f or h in d.hours % } { % i fchanged d.day h % } {{ h }} { % e ndifchanged % } { % e ndfor % } { % e ndfor % } ' , { ' days ' : [ { ' day ' : 1 , ' hours ' : [ 1 , 2 , 3 ] } , { ' day ' : 2 , ' hours ' : [ 3 ] } ] } , ' 112323 ' ) ,
2006-08-27 13:59:47 +00:00
2008-07-26 22:09:43 +00:00
# Test the else clause of ifchanged.
2013-10-26 19:15:03 +00:00
' ifchanged-else01 ' : ( ' { % f or id in ids % } {{ id }} { % i fchanged id % }-first { % e lse % }-other { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-first,1-other,2-first,2-other,2-other,3-first, ' ) ,
2008-07-26 22:09:43 +00:00
2013-10-26 19:15:03 +00:00
' ifchanged-else02 ' : ( ' { % f or id in ids % } {{ id }}- { % i fchanged id % } { % c ycle red,blue % } { % e lse % }grey { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-red,1-grey,2-blue,2-grey,2-grey,3-red, ' ) ,
' ifchanged-else03 ' : ( ' { % f or id in ids % } {{ id }} { % i fchanged id % }- { % c ycle red,blue % } { % e lse % } { % e ndifchanged % }, { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 ] } , ' 1-red,1,2-blue,2,2,3-red, ' ) ,
2008-07-26 22:09:43 +00:00
2013-10-26 19:15:03 +00:00
' ifchanged-else04 ' : ( ' { % f or id in ids % } { % i fchanged % }*** {{ id }}* { % e lse % }... { % e ndifchanged % } {{ forloop.counter }} { % e ndfor % } ' , { ' ids ' : [ 1 , 1 , 2 , 2 , 2 , 3 , 4 ] } , ' ***1*1...2***2*3...4...5***3*6***4*7 ' ) ,
2008-07-26 22:09:43 +00:00
2013-02-23 09:24:35 +00:00
# Test whitespace in filter arguments
2013-10-26 19:15:03 +00:00
' ifchanged-filter-ws ' : ( ' { % lo ad custom % } { % f or n in num % } { % i fchanged n|noop: " x y " % }.. { % e ndifchanged % } {{ n }} { % e ndfor % } ' , { ' num ' : ( 1 , 2 , 3 ) } , ' ..1..2..3 ' ) ,
2013-02-23 09:24:35 +00:00
2006-08-27 13:59:47 +00:00
### IFEQUAL TAG ###########################################################
' ifequal01 ' : ( " { % i fequal a b % }yes { % e ndifequal % } " , { " a " : 1 , " b " : 2 } , " " ) ,
' ifequal02 ' : ( " { % i fequal a b % }yes { % e ndifequal % } " , { " a " : 1 , " b " : 1 } , " yes " ) ,
' ifequal03 ' : ( " { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } " , { " a " : 1 , " b " : 2 } , " no " ) ,
' ifequal04 ' : ( " { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } " , { " a " : 1 , " b " : 1 } , " yes " ) ,
' ifequal05 ' : ( " { % i fequal a ' test ' % }yes { % e lse % }no { % e ndifequal % } " , { " a " : " test " } , " yes " ) ,
' ifequal06 ' : ( " { % i fequal a ' test ' % }yes { % e lse % }no { % e ndifequal % } " , { " a " : " no " } , " no " ) ,
' ifequal07 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { " a " : " test " } , " yes " ) ,
' ifequal08 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { " a " : " no " } , " no " ) ,
' ifequal09 ' : ( ' { % i fequal a " test " % }yes { % e lse % }no { % e ndifequal % } ' , { } , " no " ) ,
' ifequal10 ' : ( ' { % i fequal a b % }yes { % e lse % }no { % e ndifequal % } ' , { } , " yes " ) ,
# SMART SPLITTING
' ifequal-split01 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { } , " no " ) ,
' ifequal-split02 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { ' a ' : ' foo ' } , " no " ) ,
' ifequal-split03 ' : ( ' { % i fequal a " test man " % }yes { % e lse % }no { % e ndifequal % } ' , { ' a ' : ' test man ' } , " yes " ) ,
' ifequal-split04 ' : ( " { % i fequal a ' test man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' test man ' } , " yes " ) ,
' ifequal-split05 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' ' } , " no " ) ,
' ifequal-split06 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' i " love " you ' } , " yes " ) ,
' ifequal-split07 ' : ( " { % i fequal a ' i \" love \" you ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : ' i love you ' } , " no " ) ,
' ifequal-split08 ' : ( r " { % i fequal a ' I \ ' m happy ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : " I ' m happy " } , " yes " ) ,
' ifequal-split09 ' : ( r " { % i fequal a ' slash \ man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : r " slash \ man " } , " yes " ) ,
' ifequal-split10 ' : ( r " { % i fequal a ' slash \ man ' % }yes { % e lse % }no { % e ndifequal % } " , { ' a ' : r " slashman " } , " no " ) ,
2007-03-09 06:12:15 +00:00
# NUMERIC RESOLUTION
' ifequal-numeric01 ' : ( ' { % i fequal x 5 % }yes { % e ndifequal % } ' , { ' x ' : ' 5 ' } , ' ' ) ,
' ifequal-numeric02 ' : ( ' { % i fequal x 5 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' yes ' ) ,
' ifequal-numeric03 ' : ( ' { % i fequal x 5.2 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' ' ) ,
' ifequal-numeric04 ' : ( ' { % i fequal x 5.2 % }yes { % e ndifequal % } ' , { ' x ' : 5.2 } , ' yes ' ) ,
' ifequal-numeric05 ' : ( ' { % i fequal x 0.2 % }yes { % e ndifequal % } ' , { ' x ' : .2 } , ' yes ' ) ,
' ifequal-numeric06 ' : ( ' { % i fequal x .2 % }yes { % e ndifequal % } ' , { ' x ' : .2 } , ' yes ' ) ,
' ifequal-numeric07 ' : ( ' { % i fequal x 2. % }yes { % e ndifequal % } ' , { ' x ' : 2 } , ' ' ) ,
' ifequal-numeric08 ' : ( ' { % i fequal x " 5 " % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' ' ) ,
' ifequal-numeric09 ' : ( ' { % i fequal x " 5 " % }yes { % e ndifequal % } ' , { ' x ' : ' 5 ' } , ' yes ' ) ,
' ifequal-numeric10 ' : ( ' { % i fequal x -5 % }yes { % e ndifequal % } ' , { ' x ' : - 5 } , ' yes ' ) ,
' ifequal-numeric11 ' : ( ' { % i fequal x -5.2 % }yes { % e ndifequal % } ' , { ' x ' : - 5.2 } , ' yes ' ) ,
' ifequal-numeric12 ' : ( ' { % i fequal x +5 % }yes { % e ndifequal % } ' , { ' x ' : 5 } , ' yes ' ) ,
2009-03-23 09:42:51 +00:00
# FILTER EXPRESSIONS AS ARGUMENTS
' ifequal-filter01 ' : ( ' { % i fequal a|upper " A " % }x { % e ndifequal % } ' , { ' a ' : ' a ' } , ' x ' ) ,
' ifequal-filter02 ' : ( ' { % i fequal " A " a|upper % }x { % e ndifequal % } ' , { ' a ' : ' a ' } , ' x ' ) ,
' ifequal-filter03 ' : ( ' { % i fequal a|upper b|upper % }x { % e ndifequal % } ' , { ' a ' : ' x ' , ' b ' : ' X ' } , ' x ' ) ,
' ifequal-filter04 ' : ( ' { % i fequal x|slice: " 1 " " a " % }x { % e ndifequal % } ' , { ' x ' : ' aaa ' } , ' x ' ) ,
' ifequal-filter05 ' : ( ' { % i fequal x|slice: " 1 " |upper " A " % }x { % e ndifequal % } ' , { ' x ' : ' aaa ' } , ' x ' ) ,
2006-08-27 13:59:47 +00:00
### IFNOTEQUAL TAG ########################################################
' ifnotequal01 ' : ( " { % i fnotequal a b % }yes { % e ndifnotequal % } " , { " a " : 1 , " b " : 2 } , " yes " ) ,
' ifnotequal02 ' : ( " { % i fnotequal a b % }yes { % e ndifnotequal % } " , { " a " : 1 , " b " : 1 } , " " ) ,
' ifnotequal03 ' : ( " { % i fnotequal a b % }yes { % e lse % }no { % e ndifnotequal % } " , { " a " : 1 , " b " : 2 } , " yes " ) ,
' ifnotequal04 ' : ( " { % i fnotequal a b % }yes { % e lse % }no { % e ndifnotequal % } " , { " a " : 1 , " b " : 1 } , " no " ) ,
2010-12-18 02:50:26 +00:00
## INCLUDE TAG ###########################################################
2006-08-27 13:59:47 +00:00
' include01 ' : ( ' { % i nclude " basic-syntax01 " % } ' , { } , " something cool " ) ,
' include02 ' : ( ' { % i nclude " basic-syntax02 " % } ' , { ' headline ' : ' Included ' } , " Included " ) ,
' include03 ' : ( ' { % i nclude template_name % } ' , { ' template_name ' : ' basic-syntax02 ' , ' headline ' : ' Included ' } , " Included " ) ,
2011-02-04 17:10:21 +00:00
' include04 ' : ( ' a { % i nclude " nonexistent " % }b ' , { } , ( " ab " , " ab " , template . TemplateDoesNotExist ) ) ,
2009-03-30 20:30:28 +00:00
' include 05 ' : ( ' template with a space ' , { } , ' template with a space ' ) ,
' include06 ' : ( ' { % i nclude " include 05 " % } ' , { } , ' template with a space ' ) ,
2006-08-27 13:59:47 +00:00
2010-12-18 02:50:26 +00:00
# extra inline context
' include07 ' : ( ' { % i nclude " basic-syntax02 " with headline= " Inline " % } ' , { ' headline ' : ' Included ' } , ' Inline ' ) ,
' include08 ' : ( ' { % i nclude headline with headline= " Dynamic " % } ' , { ' headline ' : ' basic-syntax02 ' } , ' Dynamic ' ) ,
' include09 ' : ( ' {{ first }}-- { % i nclude " basic-syntax03 " with first=second|lower|upper second=first|upper % }-- {{ second }} ' , { ' first ' : ' Ul ' , ' second ' : ' lU ' } , ' Ul--LU --- UL--lU ' ) ,
# isolated context
' include10 ' : ( ' { % i nclude " basic-syntax03 " only % } ' , { ' first ' : ' 1 ' } , ( ' --- ' , ' INVALID --- INVALID ' ) ) ,
' include11 ' : ( ' { % i nclude " basic-syntax03 " only with second=2 % } ' , { ' first ' : ' 1 ' } , ( ' --- 2 ' , ' INVALID --- 2 ' ) ) ,
' include12 ' : ( ' { % i nclude " basic-syntax03 " with first=1 only % } ' , { ' second ' : ' 2 ' } , ( ' 1 --- ' , ' 1 --- INVALID ' ) ) ,
2011-03-10 18:42:24 +00:00
# autoescape context
' include13 ' : ( ' { % a utoescape off % } { % i nclude " basic-syntax03 " % } { % e ndautoescape % } ' , { ' first ' : ' & ' } , ( ' & --- ' , ' & --- INVALID ' ) ) ,
' include14 ' : ( ' { % a utoescape off % } { % i nclude " basic-syntax03 " with first=var1 only % } { % e ndautoescape % } ' , { ' var1 ' : ' & ' } , ( ' & --- ' , ' & --- INVALID ' ) ) ,
2010-12-18 02:50:26 +00:00
' include-error01 ' : ( ' { % i nclude " basic-syntax01 " with % } ' , { } , template . TemplateSyntaxError ) ,
' include-error02 ' : ( ' { % i nclude " basic-syntax01 " with " no key " % } ' , { } , template . TemplateSyntaxError ) ,
' include-error03 ' : ( ' { % i nclude " basic-syntax01 " with dotted.arg= " error " % } ' , { } , template . TemplateSyntaxError ) ,
' include-error04 ' : ( ' { % i nclude " basic-syntax01 " something_random % } ' , { } , template . TemplateSyntaxError ) ,
' include-error05 ' : ( ' { % i nclude " basic-syntax01 " foo= " duplicate " foo= " key " % } ' , { } , template . TemplateSyntaxError ) ,
' include-error06 ' : ( ' { % i nclude " basic-syntax01 " only only % } ' , { } , template . TemplateSyntaxError ) ,
2011-02-04 17:10:21 +00:00
### INCLUSION ERROR REPORTING #############################################
' include-fail1 ' : ( ' { % lo ad bad_tag % } { % badtag % } ' , { } , RuntimeError ) ,
' include-fail2 ' : ( ' { % lo ad broken_tag % } ' , { } , template . TemplateSyntaxError ) ,
' include-error07 ' : ( ' { % i nclude " include-fail1 " % } ' , { } , ( ' ' , ' ' , RuntimeError ) ) ,
' include-error08 ' : ( ' { % i nclude " include-fail2 " % } ' , { } , ( ' ' , ' ' , template . TemplateSyntaxError ) ) ,
2011-09-16 01:16:25 +00:00
' include-error09 ' : ( ' { % i nclude failed_include % } ' , { ' failed_include ' : ' include-fail1 ' } , ( ' ' , ' ' , RuntimeError ) ) ,
2011-02-04 17:10:21 +00:00
' include-error10 ' : ( ' { % i nclude failed_include % } ' , { ' failed_include ' : ' include-fail2 ' } , ( ' ' , ' ' , template . TemplateSyntaxError ) ) ,
2007-02-12 00:22:22 +00:00
### NAMED ENDBLOCKS #######################################################
# Basic test
' namedendblocks01 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock first % }3 " , { } , ' 1_2_3 ' ) ,
# Unbalanced blocks
2007-02-13 02:54:17 +00:00
' namedendblocks02 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock first % }_ { % e ndblock second % }3 " , { } , template . TemplateSyntaxError ) ,
2007-02-12 00:22:22 +00:00
' namedendblocks03 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock % }_ { % e ndblock second % }3 " , { } , template . TemplateSyntaxError ) ,
' namedendblocks04 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock third % }3 " , { } , template . TemplateSyntaxError ) ,
' namedendblocks05 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock first % } " , { } , template . TemplateSyntaxError ) ,
# Mixed named and unnamed endblocks
' namedendblocks06 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock % }_ { % e ndblock first % }3 " , { } , ' 1_2_3 ' ) ,
' namedendblocks07 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock second % }_ { % e ndblock % }3 " , { } , ' 1_2_3 ' ) ,
2006-08-27 13:59:47 +00:00
### INHERITANCE ###########################################################
# Standard template with no inheritance
2007-11-14 21:07:27 +00:00
' inheritance01 ' : ( " 1 { % block first % }& { % e ndblock % }3 { % block second % }_ { % e ndblock % } " , { } , ' 1&3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Standard two-level inheritance
' inheritance02 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { } , ' 1234 ' ) ,
# Three-level with no redefinitions on third level
' inheritance03 ' : ( " { % e xtends ' inheritance02 ' % } " , { } , ' 1234 ' ) ,
# Two-level with no redefinitions on second level
2007-11-14 21:07:27 +00:00
' inheritance04 ' : ( " { % e xtends ' inheritance01 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Two-level with double quotes instead of single quotes
' inheritance05 ' : ( ' { % e xtends " inheritance02 " % } ' , { } , ' 1234 ' ) ,
# Three-level with variable parent-template name
' inheritance06 ' : ( " { % e xtends foo % } " , { ' foo ' : ' inheritance02 ' } , ' 1234 ' ) ,
# Two-level with one block defined, one block not defined
2007-11-14 21:07:27 +00:00
' inheritance07 ' : ( " { % e xtends ' inheritance01 ' % } { % block second % }5 { % e ndblock % } " , { } , ' 1&35 ' ) ,
2006-08-27 13:59:47 +00:00
# Three-level with one block defined on this level, two blocks defined next level
' inheritance08 ' : ( " { % e xtends ' inheritance02 ' % } { % block second % }5 { % e ndblock % } " , { } , ' 1235 ' ) ,
# Three-level with second and third levels blank
2007-11-14 21:07:27 +00:00
' inheritance09 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Three-level with space NOT in a block -- should be ignored
2007-11-14 21:07:27 +00:00
' inheritance10 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1&3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Three-level with both blocks defined on this level, but none on second level
' inheritance11 ' : ( " { % e xtends ' inheritance04 ' % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { } , ' 1234 ' ) ,
# Three-level with this level providing one and second level providing the other
' inheritance12 ' : ( " { % e xtends ' inheritance07 ' % } { % block first % }2 { % e ndblock % } " , { } , ' 1235 ' ) ,
# Three-level with this level overriding second level
' inheritance13 ' : ( " { % e xtends ' inheritance02 ' % } { % block first % }a { % e ndblock % } { % block second % }b { % e ndblock % } " , { } , ' 1a3b ' ) ,
# A block defined only in a child template shouldn't be displayed
2007-11-14 21:07:27 +00:00
' inheritance14 ' : ( " { % e xtends ' inheritance01 ' % } { % block newblock % }NO DISPLAY { % e ndblock % } " , { } , ' 1&3_ ' ) ,
2006-08-27 13:59:47 +00:00
# A block within another block
' inheritance15 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % }2 { % block inner % }inner { % e ndblock % } { % e ndblock % } " , { } , ' 12inner3_ ' ) ,
# A block within another block (level 2)
' inheritance16 ' : ( " { % e xtends ' inheritance15 ' % } { % block inner % }out { % e ndblock % } " , { } , ' 12out3_ ' ) ,
# {% load %} tag (parent -- setup for exception04)
' inheritance17 ' : ( " { % lo ad testtags % } { % block first % }1234 { % e ndblock % } " , { } , ' 1234 ' ) ,
# {% load %} tag (standard usage, without inheritance)
' inheritance18 ' : ( " { % lo ad testtags % } { % e cho this that theother % }5678 " , { } , ' this that theother5678 ' ) ,
# {% load %} tag (within a child template)
' inheritance19 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % } { % lo ad testtags % } { % e cho 400 % }5678 { % e ndblock % } " , { } , ' 140056783_ ' ) ,
# Two-level inheritance with {{ block.super }}
2007-11-14 21:07:27 +00:00
' inheritance20 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1&a3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Three-level inheritance with {{ block.super }} from parent
' inheritance21 ' : ( " { % e xtends ' inheritance02 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 12a34 ' ) ,
# Three-level inheritance with {{ block.super }} from grandparent
2007-11-14 21:07:27 +00:00
' inheritance22 ' : ( " { % e xtends ' inheritance04 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1&a3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Three-level inheritance with {{ block.super }} from parent and grandparent
2007-11-14 21:07:27 +00:00
' inheritance23 ' : ( " { % e xtends ' inheritance20 ' % } { % block first % } {{ block.super }}b { % e ndblock % } " , { } , ' 1&ab3_ ' ) ,
2006-08-27 13:59:47 +00:00
# Inheritance from local context without use of template loader
' inheritance24 ' : ( " { % e xtends context_template % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { ' context_template ' : template . Template ( " 1 { % block first % }_ { % e ndblock % }3 { % block second % }_ { % e ndblock % } " ) } , ' 1234 ' ) ,
# Inheritance from local context with variable parent template
' inheritance25 ' : ( " { % e xtends context_template.1 % } { % block first % }2 { % e ndblock % } { % block second % }4 { % e ndblock % } " , { ' context_template ' : [ template . Template ( " Wrong " ) , template . Template ( " 1 { % block first % }_ { % e ndblock % }3 { % block second % }_ { % e ndblock % } " ) ] } , ' 1234 ' ) ,
2008-06-18 12:59:39 +00:00
# Set up a base template to extend
2008-08-30 19:25:40 +00:00
' inheritance26 ' : ( " no tags " , { } , ' no tags ' ) ,
2008-06-18 12:59:39 +00:00
2008-08-30 19:25:40 +00:00
# Inheritance from a template that doesn't have any blocks
' inheritance27 ' : ( " { % e xtends ' inheritance26 ' % } " , { } , ' no tags ' ) ,
2008-07-26 22:09:43 +00:00
2009-03-30 20:30:28 +00:00
# Set up a base template with a space in it.
' inheritance 28 ' : ( " { % block first % }! { % e ndblock % } " , { } , ' ! ' ) ,
# Inheritance from a template with a space in its name should work.
' inheritance29 ' : ( " { % e xtends ' inheritance 28 ' % } " , { } , ' ! ' ) ,
2010-03-02 07:42:51 +00:00
# Base template, putting block in a conditional {% if %} tag
' inheritance30 ' : ( " 1 { % i f optional % } { % block opt % }2 { % e ndblock % } { % e ndif % }3 " , { ' optional ' : True } , ' 123 ' ) ,
# Inherit from a template with block wrapped in an {% if %} tag (in parent), still gets overridden
' inheritance31 ' : ( " { % e xtends ' inheritance30 ' % } { % block opt % }two { % e ndblock % } " , { ' optional ' : True } , ' 1two3 ' ) ,
' inheritance32 ' : ( " { % e xtends ' inheritance30 ' % } { % block opt % }two { % e ndblock % } " , { } , ' 13 ' ) ,
# Base template, putting block in a conditional {% ifequal %} tag
' inheritance33 ' : ( " 1 { % i fequal optional 1 % } { % block opt % }2 { % e ndblock % } { % e ndifequal % }3 " , { ' optional ' : 1 } , ' 123 ' ) ,
# Inherit from a template with block wrapped in an {% ifequal %} tag (in parent), still gets overridden
' inheritance34 ' : ( " { % e xtends ' inheritance33 ' % } { % block opt % }two { % e ndblock % } " , { ' optional ' : 1 } , ' 1two3 ' ) ,
' inheritance35 ' : ( " { % e xtends ' inheritance33 ' % } { % block opt % }two { % e ndblock % } " , { ' optional ' : 2 } , ' 13 ' ) ,
# Base template, putting block in a {% for %} tag
' inheritance36 ' : ( " { % f or n in numbers % }_ { % block opt % } {{ n }} { % e ndblock % } { % e ndfor % }_ " , { ' numbers ' : ' 123 ' } , ' _1_2_3_ ' ) ,
# Inherit from a template with block wrapped in an {% for %} tag (in parent), still gets overridden
' inheritance37 ' : ( " { % e xtends ' inheritance36 ' % } { % block opt % }X { % e ndblock % } " , { ' numbers ' : ' 123 ' } , ' _X_X_X_ ' ) ,
' inheritance38 ' : ( " { % e xtends ' inheritance36 ' % } { % block opt % }X { % e ndblock % } " , { } , ' _ ' ) ,
# The super block will still be found.
' inheritance39 ' : ( " { % e xtends ' inheritance30 ' % } { % block opt % }new {{ block.super }} { % e ndblock % } " , { ' optional ' : True } , ' 1new23 ' ) ,
' inheritance40 ' : ( " { % e xtends ' inheritance33 ' % } { % block opt % }new {{ block.super }} { % e ndblock % } " , { ' optional ' : 1 } , ' 1new23 ' ) ,
' inheritance41 ' : ( " { % e xtends ' inheritance36 ' % } { % block opt % }new {{ block.super }} { % e ndblock % } " , { ' numbers ' : ' 123 ' } , ' _new1_new2_new3_ ' ) ,
2012-02-21 02:59:05 +00:00
# Expression starting and ending with a quote
' inheritance42 ' : ( " { % e xtends ' inheritance02 ' |cut: ' ' % } " , { } , ' 1234 ' ) ,
2010-11-20 06:22:28 +00:00
### LOADING TAG LIBRARIES #################################################
2011-11-21 10:28:12 +00:00
' load01 ' : ( " { % lo ad testtags subpackage.echo % } { % e cho test % } { % e cho2 \" test \" % } " , { } , " test test " ) ,
' load02 ' : ( " { % lo ad subpackage.echo % } { % e cho2 \" test \" % } " , { } , " test " ) ,
2010-11-20 06:22:28 +00:00
# {% load %} tag, importing individual tags
2011-11-21 10:28:12 +00:00
' load03 ' : ( " { % lo ad echo from testtags % } { % e cho this that theother % } " , { } , ' this that theother ' ) ,
' load04 ' : ( " { % lo ad echo other_echo from testtags % } { % e cho this that theother % } { % o ther_echo and another thing % } " , { } , ' this that theother and another thing ' ) ,
' load05 ' : ( " { % lo ad echo upper from testtags % } { % e cho this that theother % } {{ statement|upper }} " , { ' statement ' : ' not shouting ' } , ' this that theother NOT SHOUTING ' ) ,
' load06 ' : ( " { % lo ad echo2 from subpackage.echo % } { % e cho2 \" test \" % } " , { } , " test " ) ,
2010-11-20 06:22:28 +00:00
# {% load %} tag errors
2011-11-21 10:28:12 +00:00
' load07 ' : ( " { % lo ad echo other_echo bad_tag from testtags % } " , { } , template . TemplateSyntaxError ) ,
' load08 ' : ( " { % lo ad echo other_echo bad_tag from % } " , { } , template . TemplateSyntaxError ) ,
' load09 ' : ( " { % lo ad from testtags % } " , { } , template . TemplateSyntaxError ) ,
' load10 ' : ( " { % lo ad echo from bad_library % } " , { } , template . TemplateSyntaxError ) ,
' load11 ' : ( " { % lo ad subpackage.echo_invalid % } " , { } , template . TemplateSyntaxError ) ,
' load12 ' : ( " { % lo ad subpackage.missing % } " , { } , template . TemplateSyntaxError ) ,
2010-11-20 06:22:28 +00:00
2006-08-27 13:59:47 +00:00
### I18N ##################################################################
# {% spaceless %} tag
2007-04-01 01:09:21 +00:00
' spaceless01 ' : ( " { % s paceless % } <b> <i> text </i> </b> { % e ndspaceless % } " , { } , " <b><i> text </i></b> " ) ,
' spaceless02 ' : ( " { % s paceless % } <b> \n <i> text </i> \n </b> { % e ndspaceless % } " , { } , " <b><i> text </i></b> " ) ,
2006-08-27 13:59:47 +00:00
' spaceless03 ' : ( " { % s paceless % }<b><i>text</i></b> { % e ndspaceless % } " , { } , " <b><i>text</i></b> " ) ,
2013-10-27 01:27:42 +00:00
' spaceless04 ' : ( " { % s paceless % }<b> <i> {{ text }}</i> </b> { % e ndspaceless % } " , { ' text ' : ' This & that ' } , " <b><i>This & that</i></b> " ) ,
' spaceless05 ' : ( " { % a utoescape off % } { % s paceless % }<b> <i> {{ text }}</i> </b> { % e ndspaceless % } { % e ndautoescape % } " , { ' text ' : ' This & that ' } , " <b><i>This & that</i></b> " ) ,
' spaceless06 ' : ( " { % s paceless % }<b> <i> {{ text|safe }}</i> </b> { % e ndspaceless % } " , { ' text ' : ' This & that ' } , " <b><i>This & that</i></b> " ) ,
2006-08-27 13:59:47 +00:00
# simple translation of a string delimited by '
' i18n01 ' : ( " { % lo ad i18n % } { % trans ' xxxyyyxxx ' % } " , { } , " xxxyyyxxx " ) ,
# simple translation of a string delimited by "
' i18n02 ' : ( ' { % lo ad i18n % } { % trans " xxxyyyxxx " % } ' , { } , " xxxyyyxxx " ) ,
# simple translation of a variable
2012-06-07 16:08:47 +00:00
' i18n03 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ anton }} { % e ndblocktrans % } ' , { ' anton ' : b ' \xc3 \x85 ' } , " Å " ) ,
2006-08-27 13:59:47 +00:00
# simple translation of a variable and filter
2012-06-07 16:08:47 +00:00
' i18n04 ' : ( ' { % lo ad i18n % } { % blocktrans with berta=anton|lower % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : b ' \xc3 \x85 ' } , ' å ' ) ,
' legacyi18n04 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|lower as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : b ' \xc3 \x85 ' } , ' å ' ) ,
2006-08-27 13:59:47 +00:00
# simple translation of a string with interpolation
' i18n05 ' : ( ' { % lo ad i18n % } { % blocktrans % }xxx {{ anton }}xxx { % e ndblocktrans % } ' , { ' anton ' : ' yyy ' } , " xxxyyyxxx " ) ,
# simple translation of a string to german
' i18n06 ' : ( ' { % lo ad i18n % } { % trans " Page not found " % } ' , { ' LANGUAGE_CODE ' : ' de ' } , " Seite nicht gefunden " ) ,
# translation of singular form
2010-12-18 02:50:26 +00:00
' i18n07 ' : ( ' { % lo ad i18n % } { % blocktrans count counter=number % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 1 } , " singular " ) ,
' legacyi18n07 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 1 } , " singular " ) ,
2006-08-27 13:59:47 +00:00
# translation of plural form
2007-11-18 03:36:03 +00:00
' i18n08 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 2 } , " 2 plural " ) ,
2010-12-18 02:50:26 +00:00
' legacyi18n08 ' : ( ' { % lo ad i18n % } { % blocktrans count counter=number % }singular { % plural % } {{ counter }} plural { % e ndblocktrans % } ' , { ' number ' : 2 } , " 2 plural " ) ,
2006-08-27 13:59:47 +00:00
# simple non-translation (only marking) of a string to german
' i18n09 ' : ( ' { % lo ad i18n % } { % trans " Page not found " noop % } ' , { ' LANGUAGE_CODE ' : ' de ' } , " Page not found " ) ,
# translation of a variable with a translated filter
2008-02-03 01:49:55 +00:00
' i18n10 ' : ( ' {{ bool|yesno:_( " yes,no,maybe " ) }} ' , { ' bool ' : True , ' LANGUAGE_CODE ' : ' de ' } , ' Ja ' ) ,
2006-08-27 13:59:47 +00:00
# translation of a variable with a non-translated filter
' i18n11 ' : ( ' {{ bool|yesno: " ja,nein " }} ' , { ' bool ' : True } , ' ja ' ) ,
# usage of the get_available_languages tag
' i18n12 ' : ( ' { % lo ad i18n % } { % g et_available_languages as langs % } { % f or lang in langs % } { % i fequal lang.0 " de " % } {{ lang.0 }} { % e ndifequal % } { % e ndfor % } ' , { } , ' de ' ) ,
2007-11-17 04:04:12 +00:00
# translation of constant strings
2007-11-17 12:11:26 +00:00
' i18n13 ' : ( ' {{ _( " Password " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' Passwort ' ) ,
2007-11-17 04:04:12 +00:00
' i18n14 ' : ( ' { % c ycle " foo " _( " Password " ) _( \' Password \' ) as c % } { % c ycle c % } { % c ycle c % } ' , { ' LANGUAGE_CODE ' : ' de ' } , ' foo Passwort Passwort ' ) ,
' i18n15 ' : ( ' {{ absent|default:_( " Password " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' , ' absent ' : " " } , ' Passwort ' ) ,
2007-11-17 12:11:26 +00:00
' i18n16 ' : ( ' {{ _( " < " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' < ' ) ,
2006-08-27 13:59:47 +00:00
2009-04-11 12:03:52 +00:00
# Escaping inside blocktrans and trans works as if it was directly in the
2007-11-17 12:12:18 +00:00
# template.
2012-06-07 16:08:47 +00:00
' i18n17 ' : ( ' { % lo ad i18n % } { % blocktrans with berta=anton|escape % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , ' α & β' ) ,
' i18n18 ' : ( ' { % lo ad i18n % } { % blocktrans with berta=anton|force_escape % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , ' α & β' ) ,
' i18n19 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ andrew }} { % e ndblocktrans % } ' , { ' andrew ' : ' a & b ' } , ' a & b ' ) ,
' i18n20 ' : ( ' { % lo ad i18n % } { % trans andrew % } ' , { ' andrew ' : ' a & b ' } , ' a & b ' ) ,
' i18n21 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ andrew }} { % e ndblocktrans % } ' , { ' andrew ' : mark_safe ( ' a & b ' ) } , ' a & b ' ) ,
' i18n22 ' : ( ' { % lo ad i18n % } { % trans andrew % } ' , { ' andrew ' : mark_safe ( ' a & b ' ) } , ' a & b ' ) ,
' legacyi18n17 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|escape as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , ' α & β' ) ,
' legacyi18n18 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|force_escape as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' α & β' } , ' α & β' ) ,
2007-11-17 12:12:18 +00:00
2010-02-21 23:43:28 +00:00
# Use filters with the {% trans %} tag, #5972
2012-06-07 16:08:47 +00:00
' i18n23 ' : ( ' { % lo ad i18n % } { % trans " Page not found " |capfirst|slice: " 6: " % } ' , { ' LANGUAGE_CODE ' : ' de ' } , ' nicht gefunden ' ) ,
' i18n24 ' : ( " { % lo ad i18n % } { % trans ' Page not found ' |upper % } " , { ' LANGUAGE_CODE ' : ' de ' } , ' SEITE NICHT GEFUNDEN ' ) ,
' i18n25 ' : ( ' { % lo ad i18n % } { % trans somevar|upper % } ' , { ' somevar ' : ' Page not found ' , ' LANGUAGE_CODE ' : ' de ' } , ' SEITE NICHT GEFUNDEN ' ) ,
2010-02-21 23:43:28 +00:00
2010-10-01 02:02:01 +00:00
# translation of plural form with extra field in singular form (#13568)
2010-12-18 02:50:26 +00:00
' i18n26 ' : ( ' { % lo ad i18n % } { % blocktrans with extra_field=myextra_field count counter=number % }singular {{ extra_field }} { % plural % }plural { % e ndblocktrans % } ' , { ' number ' : 1 , ' myextra_field ' : ' test ' } , " singular test " ) ,
' legacyi18n26 ' : ( ' { % lo ad i18n % } { % blocktrans with myextra_field as extra_field count number as counter % }singular {{ extra_field }} { % plural % }plural { % e ndblocktrans % } ' , { ' number ' : 1 , ' myextra_field ' : ' test ' } , " singular test " ) ,
2010-10-01 02:02:01 +00:00
2010-10-16 20:40:17 +00:00
# translation of singular form in russian (#14126)
2012-06-07 16:08:47 +00:00
' i18n27 ' : ( ' { % lo ad i18n % } { % blocktrans count counter=number % } {{ counter }} result { % plural % } {{ counter }} results { % e ndblocktrans % } ' , { ' number ' : 1 , ' LANGUAGE_CODE ' : ' ru ' } , ' 1 \u0440 \u0435 \u0437 \u0443 \u043b \u044c \u0442 \u0430 \u0442 ' ) ,
' legacyi18n27 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % } {{ counter }} result { % plural % } {{ counter }} results { % e ndblocktrans % } ' , { ' number ' : 1 , ' LANGUAGE_CODE ' : ' ru ' } , ' 1 \u0440 \u0435 \u0437 \u0443 \u043b \u044c \u0442 \u0430 \u0442 ' ) ,
2010-12-18 02:50:26 +00:00
# simple translation of multiple variables
2012-06-07 16:08:47 +00:00
' i18n28 ' : ( ' { % lo ad i18n % } { % blocktrans with a=anton b=berta % } {{ a }} + {{ b }} { % e ndblocktrans % } ' , { ' anton ' : ' α ' , ' berta ' : ' β ' } , ' α + β' ) ,
' legacyi18n28 ' : ( ' { % lo ad i18n % } { % blocktrans with anton as a and berta as b % } {{ a }} + {{ b }} { % e ndblocktrans % } ' , { ' anton ' : ' α ' , ' berta ' : ' β ' } , ' α + β' ) ,
2010-10-16 20:40:17 +00:00
2010-12-12 23:02:45 +00:00
# retrieving language information
2011-06-10 10:18:06 +00:00
' i18n28_2 ' : ( ' { % lo ad i18n % } { % g et_language_info for " de " as l % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }} ' , { } , ' de: German/Deutsch bidi=False ' ) ,
2010-12-12 23:02:45 +00:00
' i18n29 ' : ( ' { % lo ad i18n % } { % g et_language_info for LANGUAGE_CODE as l % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }} ' , { ' LANGUAGE_CODE ' : ' fi ' } , ' fi: Finnish/suomi bidi=False ' ) ,
2012-11-25 18:53:24 +00:00
' i18n30 ' : ( ' { % lo ad i18n % } { % g et_language_info_list for langcodes as langs % } { % f or l in langs % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }}; { % e ndfor % } ' , { ' langcodes ' : [ ' it ' , ' no ' ] } , ' it: Italian/italiano bidi=False; no: Norwegian/norsk bidi=False; ' ) ,
2012-06-07 16:08:47 +00:00
' i18n31 ' : ( ' { % lo ad i18n % } { % g et_language_info_list for langcodes as langs % } { % f or l in langs % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }}; { % e ndfor % } ' , { ' langcodes ' : ( ( ' sl ' , ' Slovenian ' ) , ( ' fa ' , ' Persian ' ) ) } , ' sl: Slovenian/Sloven \u0161 \u010d ina bidi=False; fa: Persian/ \u0641 \u0627 \u0631 \u0633 \u06cc bidi=True; ' ) ,
' i18n32 ' : ( ' { % lo ad i18n % } {{ " hu " |language_name }} {{ " hu " |language_name_local }} {{ " hu " |language_bidi }} ' , { } , ' Hungarian Magyar False ' ) ,
' i18n33 ' : ( ' { % lo ad i18n % } {{ langcode|language_name }} {{ langcode|language_name_local }} {{ langcode|language_bidi }} ' , { ' langcode ' : ' nl ' } , ' Dutch Nederlands False ' ) ,
2010-12-12 23:02:45 +00:00
2011-03-02 21:36:41 +00:00
# blocktrans handling of variables which are not in the context.
2013-02-27 20:50:33 +00:00
# this should work as if blocktrans was not there (bug #19915)
' i18n34 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ missing }} { % e ndblocktrans % } ' , { } , ( ' ' , ' INVALID ' ) ) ,
' i18n34_2 ' : ( " { % lo ad i18n % } { % blocktrans with a= ' α ' % } {{ missing }} { % e ndblocktrans % } " , { } , ( ' ' , ' INVALID ' ) ) ,
' i18n34_3 ' : ( ' { % lo ad i18n % } { % blocktrans with a=anton % } {{ missing }} { % e ndblocktrans % } ' , { ' anton ' : ' α ' } , ( ' ' , ' INVALID ' ) ) ,
2011-03-02 21:36:41 +00:00
2011-08-30 12:09:45 +00:00
# trans tag with as var
' i18n35 ' : ( ' { % lo ad i18n % } { % trans " Page not found " as page_not_found % } {{ page_not_found }} ' , { ' LANGUAGE_CODE ' : ' de ' } , " Seite nicht gefunden " ) ,
' i18n36 ' : ( ' { % lo ad i18n % } { % trans " Page not found " noop as page_not_found % } {{ page_not_found }} ' , { ' LANGUAGE_CODE ' : ' de ' } , " Page not found " ) ,
' i18n36 ' : ( ' { % lo ad i18n % } { % trans " Page not found " as page_not_found noop % } {{ page_not_found }} ' , { ' LANGUAGE_CODE ' : ' de ' } , " Page not found " ) ,
' i18n37 ' : ( ' { % lo ad i18n % } { % trans " Page not found " as page_not_found % } { % blocktrans % }Error: {{ page_not_found }} { % e ndblocktrans % } ' , { ' LANGUAGE_CODE ' : ' de ' } , " Error: Seite nicht gefunden " ) ,
2013-02-23 09:24:35 +00:00
# Test whitespace in filter arguments
' i18n38 ' : ( ' { % lo ad i18n custom % } { % g et_language_info for " de " |noop: " x y " as l % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }} ' , { } , ' de: German/Deutsch bidi=False ' ) ,
' i18n38_2 ' : ( ' { % lo ad i18n custom % } { % g et_language_info_list for langcodes|noop: " x y " as langs % } { % f or l in langs % } {{ l.code }}: {{ l.name }}/ {{ l.name_local }} bidi= {{ l.bidi }}; { % e ndfor % } ' , { ' langcodes ' : [ ' it ' , ' no ' ] } , ' it: Italian/italiano bidi=False; no: Norwegian/norsk bidi=False; ' ) ,
2007-07-20 12:15:02 +00:00
### HANDLING OF TEMPLATE_STRING_IF_INVALID ###################################
2006-10-24 21:30:38 +00:00
2013-10-26 19:15:03 +00:00
' invalidstr01 ' : ( ' {{ var|default: " Foo " }} ' , { } , ( ' Foo ' , ' INVALID ' ) ) ,
' invalidstr02 ' : ( ' {{ var|default_if_none: " Foo " }} ' , { } , ( ' ' , ' INVALID ' ) ) ,
2006-09-04 14:02:11 +00:00
' invalidstr03 ' : ( ' { % f or v in var % }( {{ v }}) { % e ndfor % } ' , { } , ' ' ) ,
' invalidstr04 ' : ( ' { % i f var % }Yes { % e lse % }No { % e ndif % } ' , { } , ' No ' ) ,
2011-06-10 10:18:06 +00:00
' invalidstr04_2 ' : ( ' { % i f var|default: " Foo " % }Yes { % e lse % }No { % e ndif % } ' , { } , ' Yes ' ) ,
2011-02-04 17:10:21 +00:00
' invalidstr05 ' : ( ' {{ var }} ' , { } , ( ' ' , ( ' INVALID %s ' , ' var ' ) ) ) ,
' invalidstr06 ' : ( ' {{ var.prop }} ' , { ' var ' : { } } , ( ' ' , ( ' INVALID %s ' , ' var.prop ' ) ) ) ,
2014-02-08 10:06:54 +00:00
' invalidstr07 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ var }} { % e ndblocktrans % } ' ,
{ } , ( ' ' , ( ' INVALID %s ' , ' var ' ) ) ) ,
2006-09-04 14:02:11 +00:00
2006-08-27 13:59:47 +00:00
### MULTILINE #############################################################
' multiline01 ' : ( """
Hello ,
boys .
How
are
you
gentlemen .
""" ,
{ } ,
"""
Hello ,
boys .
How
are
you
gentlemen .
""" ),
### REGROUP TAG ###########################################################
2011-06-10 10:18:06 +00:00
' regroup01 ' : ( ' { % r egroup data by bar as grouped % } '
' { % f or group in grouped % } '
' {{ group.grouper }}: '
' { % f or item in group.list % } '
' {{ item.foo }} '
' { % e ndfor % }, '
2006-08-27 13:59:47 +00:00
' { % e ndfor % } ' ,
2013-10-26 19:15:03 +00:00
{ ' data ' : [ { ' foo ' : ' c ' , ' bar ' : 1 } ,
2013-11-02 21:34:05 +00:00
{ ' foo ' : ' d ' , ' bar ' : 1 } ,
{ ' foo ' : ' a ' , ' bar ' : 2 } ,
{ ' foo ' : ' b ' , ' bar ' : 2 } ,
{ ' foo ' : ' x ' , ' bar ' : 3 } ] } ,
2006-08-27 13:59:47 +00:00
' 1:cd,2:ab,3:x, ' ) ,
# Test for silent failure when target variable isn't found
2011-06-10 10:18:06 +00:00
' regroup02 ' : ( ' { % r egroup data by bar as grouped % } '
' { % f or group in grouped % } '
' {{ group.grouper }}: '
' { % f or item in group.list % } '
' {{ item.foo }} '
' { % e ndfor % }, '
2006-08-27 13:59:47 +00:00
' { % e ndfor % } ' ,
2006-09-04 14:02:11 +00:00
{ } , ' ' ) ,
2012-02-14 21:29:50 +00:00
# Regression tests for #17675
# The date template filter has expects_localtime = True
' regroup03 ' : ( ' { % r egroup data by at|date: " m " as grouped % } '
' { % f or group in grouped % } '
' {{ group.grouper }}: '
' { % f or item in group.list % } '
' {{ item.at|date: " d " }} '
' { % e ndfor % }, '
' { % e ndfor % } ' ,
{ ' data ' : [ { ' at ' : date ( 2012 , 2 , 14 ) } ,
{ ' at ' : date ( 2012 , 2 , 28 ) } ,
{ ' at ' : date ( 2012 , 7 , 4 ) } ] } ,
' 02:1428,07:04, ' ) ,
# The join template filter has needs_autoescape = True
' regroup04 ' : ( ' { % r egroup data by bar|join: " " as grouped % } '
' { % f or group in grouped % } '
' {{ group.grouper }}: '
' { % f or item in group.list % } '
' {{ item.foo|first }} '
' { % e ndfor % }, '
' { % e ndfor % } ' ,
{ ' data ' : [ { ' foo ' : ' x ' , ' bar ' : [ ' ab ' , ' c ' ] } ,
{ ' foo ' : ' y ' , ' bar ' : [ ' a ' , ' bc ' ] } ,
{ ' foo ' : ' z ' , ' bar ' : [ ' a ' , ' d ' ] } ] } ,
' abc:xy,ad:z, ' ) ,
2013-02-23 09:24:35 +00:00
# Test syntax
' regroup05 ' : ( ' { % r egroup data by bar as % } ' , { } ,
2013-11-02 21:34:05 +00:00
template . TemplateSyntaxError ) ,
2013-02-23 09:24:35 +00:00
' regroup06 ' : ( ' { % r egroup data by bar thisaintright grouped % } ' , { } ,
2013-11-02 21:34:05 +00:00
template . TemplateSyntaxError ) ,
2013-02-23 09:24:35 +00:00
' regroup07 ' : ( ' { % r egroup data thisaintright bar as grouped % } ' , { } ,
2013-11-02 21:34:05 +00:00
template . TemplateSyntaxError ) ,
2013-02-23 09:24:35 +00:00
' regroup08 ' : ( ' { % r egroup data by bar as grouped toomanyargs % } ' , { } ,
2013-11-02 21:34:05 +00:00
template . TemplateSyntaxError ) ,
2013-02-23 09:24:35 +00:00
2010-11-20 06:22:28 +00:00
### SSI TAG ########################################################
# Test normal behavior
2012-04-24 19:55:52 +00:00
' ssi01 ' : ( ' { %% ssi " %s " %% } ' % os . path . join ( basedir , ' templates ' , ' ssi_include.html ' ) , { } , ' This is for testing an ssi include. {{ test }} \n ' ) ,
' ssi02 ' : ( ' { %% ssi " %s " %% } ' % os . path . join ( basedir , ' not_here ' ) , { } , ' ' ) ,
' ssi03 ' : ( " { %% ssi ' %s ' %% } " % os . path . join ( basedir , ' not_here ' ) , { } , ' ' ) ,
2010-11-20 06:22:28 +00:00
# Test passing as a variable
2011-08-25 23:02:15 +00:00
' ssi04 ' : ( ' { % lo ad ssi from future % } { % s si ssi_file % } ' , { ' ssi_file ' : os . path . join ( basedir , ' templates ' , ' ssi_include.html ' ) } , ' This is for testing an ssi include. {{ test }} \n ' ) ,
2010-11-20 06:22:28 +00:00
' ssi05 ' : ( ' { % lo ad ssi from future % } { % s si ssi_file % } ' , { ' ssi_file ' : ' no_file ' } , ' ' ) ,
# Test parsed output
2012-04-24 19:55:52 +00:00
' ssi06 ' : ( ' { %% ssi " %s " parsed %% } ' % os . path . join ( basedir , ' templates ' , ' ssi_include.html ' ) , { ' test ' : ' Look ma! It parsed! ' } , ' This is for testing an ssi include. Look ma! It parsed! \n ' ) ,
' ssi07 ' : ( ' { %% ssi " %s " parsed %% } ' % os . path . join ( basedir , ' not_here ' ) , { ' test ' : ' Look ma! It parsed! ' } , ' ' ) ,
2010-11-20 06:22:28 +00:00
2011-08-25 23:02:15 +00:00
# Test space in file name
2012-04-24 19:55:52 +00:00
' ssi08 ' : ( ' { %% ssi " %s " %% } ' % os . path . join ( basedir , ' templates ' , ' ssi include with spaces.html ' ) , { } , ' This is for testing an ssi include with spaces in its name. {{ test }} \n ' ) ,
' ssi09 ' : ( ' { %% ssi " %s " parsed %% } ' % os . path . join ( basedir , ' templates ' , ' ssi include with spaces.html ' ) , { ' test ' : ' Look ma! It parsed! ' } , ' This is for testing an ssi include with spaces in its name. Look ma! It parsed! \n ' ) ,
2006-08-27 13:59:47 +00:00
### TEMPLATETAG TAG #######################################################
' templatetag01 ' : ( ' { % templatetag openblock % } ' , { } , ' { % ' ) ,
' templatetag02 ' : ( ' { % templatetag closeblock % } ' , { } , ' % } ' ) ,
' templatetag03 ' : ( ' { % templatetag openvariable % } ' , { } , ' {{ ' ) ,
' templatetag04 ' : ( ' { % templatetag closevariable % } ' , { } , ' }} ' ) ,
' templatetag05 ' : ( ' { % templatetag % } ' , { } , template . TemplateSyntaxError ) ,
' templatetag06 ' : ( ' { % templatetag foo % } ' , { } , template . TemplateSyntaxError ) ,
' templatetag07 ' : ( ' { % templatetag openbrace % } ' , { } , ' { ' ) ,
' templatetag08 ' : ( ' { % templatetag closebrace % } ' , { } , ' } ' ) ,
' templatetag09 ' : ( ' { % templatetag openbrace % } { % templatetag openbrace % } ' , { } , ' {{ ' ) ,
' templatetag10 ' : ( ' { % templatetag closebrace % } { % templatetag closebrace % } ' , { } , ' }} ' ) ,
2006-10-27 01:58:13 +00:00
' templatetag11 ' : ( ' { % templatetag opencomment % } ' , { } , ' { # ' ) ,
' templatetag12 ' : ( ' { % templatetag closecomment % } ' , { } , ' #} ' ) ,
2006-08-27 13:59:47 +00:00
2011-06-11 16:05:28 +00:00
# Simple tags with customized names
' simpletag-renamed01 ' : ( ' { % lo ad custom % } { % minusone 7 % } ' , { } , ' 6 ' ) ,
' simpletag-renamed02 ' : ( ' { % lo ad custom % } { % minustwo 7 % } ' , { } , ' 5 ' ) ,
' simpletag-renamed03 ' : ( ' { % lo ad custom % } { % minustwo_overridden_name 7 % } ' , { } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
### WIDTHRATIO TAG ########################################################
2013-10-26 19:15:03 +00:00
' widthratio01 ' : ( ' { % widthratio a b 0 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 0 ' ) ,
' widthratio02 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 0 , ' b ' : 0 } , ' 0 ' ) ,
' widthratio03 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 0 , ' b ' : 100 } , ' 0 ' ) ,
' widthratio04 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 50 ' ) ,
' widthratio05 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 100 , ' b ' : 100 } , ' 100 ' ) ,
2006-08-27 13:59:47 +00:00
2012-08-18 08:18:24 +00:00
# 62.5 should round to 63 on Python 2 and 62 on Python 3
# See http://docs.python.org/py3k/whatsnew/3.0.html
2013-10-26 19:15:03 +00:00
' widthratio06 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 80 } , ' 62 ' if six . PY3 else ' 63 ' ) ,
2006-08-27 13:59:47 +00:00
# 71.4 should round to 71
2013-10-26 19:15:03 +00:00
' widthratio07 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 70 } , ' 71 ' ) ,
2006-08-27 13:59:47 +00:00
# Raise exception if we don't have 3 args, last one an integer
' widthratio08 ' : ( ' { % widthratio % } ' , { } , template . TemplateSyntaxError ) ,
2013-10-26 19:15:03 +00:00
' widthratio09 ' : ( ' { % widthratio a b % } ' , { ' a ' : 50 , ' b ' : 100 } , template . TemplateSyntaxError ) ,
' widthratio10 ' : ( ' { % widthratio a b 100.0 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 50 ' ) ,
2009-04-04 19:34:52 +00:00
2009-04-01 23:41:36 +00:00
# #10043: widthratio should allow max_width to be a variable
2013-10-26 19:15:03 +00:00
' widthratio11 ' : ( ' { % widthratio a b c % } ' , { ' a ' : 50 , ' b ' : 100 , ' c ' : 100 } , ' 50 ' ) ,
2006-08-27 13:59:47 +00:00
2012-08-11 23:15:50 +00:00
# #18739: widthratio should handle None args consistently with non-numerics
2013-10-26 19:15:03 +00:00
' widthratio12a ' : ( ' { % widthratio a b c % } ' , { ' a ' : ' a ' , ' b ' : 100 , ' c ' : 100 } , ' ' ) ,
' widthratio12b ' : ( ' { % widthratio a b c % } ' , { ' a ' : None , ' b ' : 100 , ' c ' : 100 } , ' ' ) ,
' widthratio13a ' : ( ' { % widthratio a b c % } ' , { ' a ' : 0 , ' b ' : ' b ' , ' c ' : 100 } , ' ' ) ,
' widthratio13b ' : ( ' { % widthratio a b c % } ' , { ' a ' : 0 , ' b ' : None , ' c ' : 100 } , ' ' ) ,
' widthratio14a ' : ( ' { % widthratio a b c % } ' , { ' a ' : 0 , ' b ' : 100 , ' c ' : ' c ' } , template . TemplateSyntaxError ) ,
' widthratio14b ' : ( ' { % widthratio a b c % } ' , { ' a ' : 0 , ' b ' : 100 , ' c ' : None } , template . TemplateSyntaxError ) ,
2012-08-11 23:15:50 +00:00
2013-02-23 09:24:35 +00:00
# Test whitespace in filter argument
2013-10-26 19:15:03 +00:00
' widthratio15 ' : ( ' { % lo ad custom % } { % widthratio a|noop: " x y " b 0 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 0 ' ) ,
2013-02-23 09:24:35 +00:00
2013-08-14 14:14:32 +00:00
# Widthratio with variable assignment
2013-10-26 19:15:03 +00:00
' widthratio16 ' : ( ' { % widthratio a b 100 as variable % }- {{ variable }}- ' , { ' a ' : 50 , ' b ' : 100 } , ' -50- ' ) ,
' widthratio17 ' : ( ' { % widthratio a b 100 as variable % }- {{ variable }}- ' , { ' a ' : 100 , ' b ' : 100 } , ' -100- ' ) ,
2013-08-14 14:14:32 +00:00
2013-10-14 19:13:14 +00:00
' widthratio18 ' : ( ' { % widthratio a b 100 as % } ' , { } , template . TemplateSyntaxError ) ,
' widthratio19 ' : ( ' { % widthratio a b 100 not_as variable % } ' , { } , template . TemplateSyntaxError ) ,
2014-02-08 20:00:43 +00:00
' widthratio20 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : float ( ' inf ' ) , ' b ' : float ( ' inf ' ) } , ' ' ) ,
' widthratio21 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : float ( ' inf ' ) , ' b ' : 2 } , ' ' ) ,
2013-08-14 14:14:32 +00:00
2007-03-27 17:25:56 +00:00
### WITH TAG ########################################################
2010-12-18 02:50:26 +00:00
' with01 ' : ( ' { % with key=dict.key % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , ' 50 ' ) ,
' legacywith01 ' : ( ' { % with dict.key as key % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , ' 50 ' ) ,
' with02 ' : ( ' {{ key }} { % with key=dict.key % } {{ key }}- {{ dict.key }}- {{ key }} { % e ndwith % } {{ key }} ' , { ' dict ' : { ' key ' : 50 } } , ( ' 50-50-50 ' , ' INVALID50-50-50INVALID ' ) ) ,
' legacywith02 ' : ( ' {{ key }} { % with dict.key as key % } {{ key }}- {{ dict.key }}- {{ key }} { % e ndwith % } {{ key }} ' , { ' dict ' : { ' key ' : 50 } } , ( ' 50-50-50 ' , ' INVALID50-50-50INVALID ' ) ) ,
' with03 ' : ( ' { % with a=alpha b=beta % } {{ a }} {{ b }} { % e ndwith % } ' , { ' alpha ' : ' A ' , ' beta ' : ' B ' } , ' AB ' ) ,
2007-03-27 17:25:56 +00:00
2010-12-18 02:50:26 +00:00
' with-error01 ' : ( ' { % with dict.key xx key % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , template . TemplateSyntaxError ) ,
' with-error02 ' : ( ' { % with dict.key as % } {{ key }} { % e ndwith % } ' , { ' dict ' : { ' key ' : 50 } } , template . TemplateSyntaxError ) ,
2007-04-21 04:13:52 +00:00
2006-08-27 13:59:47 +00:00
### NOW TAG ########################################################
# Simple case
2012-01-24 08:02:34 +00:00
' now01 ' : ( ' { % now " j n Y " % } ' , { } , " %d %d %d " % (
datetime . now ( ) . day , datetime . now ( ) . month , datetime . now ( ) . year ) ) ,
2011-05-07 16:58:45 +00:00
# Check parsing of locale strings
2013-11-02 19:37:48 +00:00
' now02 ' : ( ' { % now " DATE_FORMAT " % } ' , { } , date_format ( datetime . now ( ) ) ) ,
2012-01-24 08:02:34 +00:00
# Also accept simple quotes - #15092
' now03 ' : ( " { % now ' j n Y ' % } " , { } , " %d %d %d " % (
datetime . now ( ) . day , datetime . now ( ) . month , datetime . now ( ) . year ) ) ,
2013-11-02 19:37:48 +00:00
' now04 ' : ( " { % now ' DATE_FORMAT ' % } " , { } , date_format ( datetime . now ( ) ) ) ,
2012-01-24 08:02:34 +00:00
' now05 ' : ( ''' { % now ' j " n " Y ' % } ''' , { } , ''' %d " %d " %d ''' % (
datetime . now ( ) . day , datetime . now ( ) . month , datetime . now ( ) . year ) ) ,
' now06 ' : ( ''' { % now " j ' n ' Y " % } ''' , { } , ''' %d ' %d ' %d ''' % (
datetime . now ( ) . day , datetime . now ( ) . month , datetime . now ( ) . year ) ) ,
2006-08-27 13:59:47 +00:00
2007-02-13 04:24:58 +00:00
### URL TAG ########################################################
# Successes
2014-01-14 15:43:27 +00:00
' url01 ' : ( ' { % u rl " template_tests.views.client " client.id % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/ ' ) ,
' url02 ' : ( ' { % u rl " template_tests.views.client_action " id=client.id action= " update " % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/update/ ' ) ,
' url02a ' : ( ' { % u rl " template_tests.views.client_action " client.id " update " % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/update/ ' ) ,
' url02b ' : ( " { % u rl ' template_tests.views.client_action ' id=client.id action= ' update ' % } " , { ' client ' : { ' id ' : 1 } } , ' /client/1/update/ ' ) ,
' url02c ' : ( " { % u rl ' template_tests.views.client_action ' client.id ' update ' % } " , { ' client ' : { ' id ' : 1 } } , ' /client/1/update/ ' ) ,
' url03 ' : ( ' { % u rl " template_tests.views.index " % } ' , { } , ' / ' ) ,
' url04 ' : ( ' { % u rl " named.client " client.id % } ' , { ' client ' : { ' id ' : 1 } } , ' /named-client/1/ ' ) ,
' url05 ' : ( ' { % u rl " ме тка _о пе р а то р а " v % } ' , { ' v ' : ' Ω ' } , ' / % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url06 ' : ( ' { % u rl " ме тка _о пе р а то р а _2 " tag=v % } ' , { ' v ' : ' Ω ' } , ' / % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url07 ' : ( ' { % u rl " template_tests.views.client2 " tag=v % } ' , { ' v ' : ' Ω ' } , ' / % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url08 ' : ( ' { % u rl " ме тка _о пе р а то р а " v % } ' , { ' v ' : ' Ω ' } , ' / % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url09 ' : ( ' { % u rl " ме тка _о пе р а то р а _2 " tag=v % } ' , { ' v ' : ' Ω ' } , ' / % D0 % AE % D0 % BD % D0 % B8 % D0 % BA % D0 % BE % D0 % B4/ % CE % A9/ ' ) ,
' url10 ' : ( ' { % u rl " template_tests.views.client_action " id=client.id action= " two words " % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/two % 20words/ ' ) ,
' url11 ' : ( ' { % u rl " template_tests.views.client_action " id=client.id action= " == " % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/ % 3D % 3D/ ' ) ,
' url12 ' : ( ' { % u rl " template_tests.views.client_action " id=client.id action= " , " % } ' , { ' client ' : { ' id ' : 1 } } , ' /client/1/ % 2C/ ' ) ,
' url13 ' : ( ' { % u rl " template_tests.views.client_action " id=client.id action=arg|join: " - " % } ' , { ' client ' : { ' id ' : 1 } , ' arg ' : [ ' a ' , ' b ' ] } , ' /client/1/a-b/ ' ) ,
' url14 ' : ( ' { % u rl " template_tests.views.client_action " client.id arg|join: " - " % } ' , { ' client ' : { ' id ' : 1 } , ' arg ' : [ ' a ' , ' b ' ] } , ' /client/1/a-b/ ' ) ,
' url15 ' : ( ' { % u rl " template_tests.views.client_action " 12 " test " % } ' , { } , ' /client/12/test/ ' ) ,
' url18 ' : ( ' { % u rl " template_tests.views.client " " 1,2 " % } ' , { } , ' /client/1 % 2C2/ ' ) ,
' url19 ' : ( ' { % u rl named_url client.id % } ' , { ' named_url ' : ' template_tests.views.client ' , ' client ' : { ' id ' : 1 } } , ' /client/1/ ' ) ,
' url20 ' : ( ' { % u rl url_name_in_var client.id % } ' , { ' url_name_in_var ' : ' named.client ' , ' client ' : { ' id ' : 1 } } , ' /named-client/1/ ' ) ,
2007-02-13 04:24:58 +00:00
# Failures
2012-04-24 19:55:52 +00:00
' url-fail01 ' : ( ' { % u rl % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail02 ' : ( ' { % u rl " no_such_view " % } ' , { } , ( urlresolvers . NoReverseMatch , urlresolvers . NoReverseMatch ) ) ,
2013-02-26 12:19:18 +00:00
' url-fail03 ' : ( ' { % u rl " template_tests.views.client " % } ' , { } , ( urlresolvers . NoReverseMatch , urlresolvers . NoReverseMatch ) ) ,
2012-04-24 19:55:52 +00:00
' url-fail04 ' : ( ' { % u rl " view " id, % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail05 ' : ( ' { % u rl " view " id= % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail06 ' : ( ' { % u rl " view " a.id=id % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail07 ' : ( ' { % u rl " view " a.id!id % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail08 ' : ( ' { % u rl " view " id= " unterminatedstring % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail09 ' : ( ' { % u rl " view " id= " , % } ' , { } , template . TemplateSyntaxError ) ,
' url-fail11 ' : ( ' { % u rl named_url % } ' , { } , ( urlresolvers . NoReverseMatch , urlresolvers . NoReverseMatch ) ) ,
' url-fail12 ' : ( ' { % u rl named_url % } ' , { ' named_url ' : ' no_such_view ' } , ( urlresolvers . NoReverseMatch , urlresolvers . NoReverseMatch ) ) ,
2013-02-26 12:19:18 +00:00
' url-fail13 ' : ( ' { % u rl named_url % } ' , { ' named_url ' : ' template_tests.views.client ' } , ( urlresolvers . NoReverseMatch , urlresolvers . NoReverseMatch ) ) ,
2012-04-24 19:55:52 +00:00
' url-fail14 ' : ( ' { % u rl named_url id, % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
' url-fail15 ' : ( ' { % u rl named_url id= % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
' url-fail16 ' : ( ' { % u rl named_url a.id=id % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
' url-fail17 ' : ( ' { % u rl named_url a.id!id % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
' url-fail18 ' : ( ' { % u rl named_url id= " unterminatedstring % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
' url-fail19 ' : ( ' { % u rl named_url id= " , % } ' , { ' named_url ' : ' view ' } , template . TemplateSyntaxError ) ,
2007-10-21 15:48:40 +00:00
2008-08-29 19:28:03 +00:00
# {% url ... as var %}
2013-02-26 12:19:18 +00:00
' url-asvar01 ' : ( ' { % u rl " template_tests.views.index " as url % } ' , { } , ' ' ) ,
2014-01-14 15:43:27 +00:00
' url-asvar02 ' : ( ' { % u rl " template_tests.views.index " as url % } {{ url }} ' , { } , ' / ' ) ,
2012-04-24 19:55:52 +00:00
' url-asvar03 ' : ( ' { % u rl " no_such_view " as url % } {{ url }} ' , { } , ' ' ) ,
2008-08-29 19:28:03 +00:00
2007-10-21 15:48:40 +00:00
### CACHE TAG ######################################################
2008-06-26 04:54:10 +00:00
' cache03 ' : ( ' { % lo ad cache % } { % c ache 2 test % }cache03 { % e ndcache % } ' , { } , ' cache03 ' ) ,
' cache04 ' : ( ' { % lo ad cache % } { % c ache 2 test % }cache04 { % e ndcache % } ' , { } , ' cache03 ' ) ,
' cache05 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache05 { % e ndcache % } ' , { ' foo ' : 1 } , ' cache05 ' ) ,
' cache06 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache06 { % e ndcache % } ' , { ' foo ' : 2 } , ' cache06 ' ) ,
' cache07 ' : ( ' { % lo ad cache % } { % c ache 2 test foo % }cache07 { % e ndcache % } ' , { ' foo ' : 1 } , ' cache05 ' ) ,
# Allow first argument to be a variable.
2008-07-26 22:09:43 +00:00
' cache08 ' : ( ' { % lo ad cache % } { % c ache time test foo % }cache08 { % e ndcache % } ' , { ' foo ' : 2 , ' time ' : 2 } , ' cache06 ' ) ,
2007-10-21 15:48:40 +00:00
2008-06-26 04:33:18 +00:00
# Raise exception if we don't have at least 2 args, first one integer.
2008-06-26 04:54:10 +00:00
' cache11 ' : ( ' { % lo ad cache % } { % c ache % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
' cache12 ' : ( ' { % lo ad cache % } { % c ache 1 % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
' cache13 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { } , template . TemplateSyntaxError ) ,
2008-07-26 22:09:43 +00:00
' cache14 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { ' foo ' : ' fail ' } , template . TemplateSyntaxError ) ,
' cache15 ' : ( ' { % lo ad cache % } { % c ache foo bar % } { % e ndcache % } ' , { ' foo ' : [ ] } , template . TemplateSyntaxError ) ,
2006-08-27 13:59:47 +00:00
2008-08-25 04:52:55 +00:00
# Regression test for #7460.
' cache16 ' : ( ' { % lo ad cache % } { % c ache 1 foo bar % } { % e ndcache % } ' , { ' foo ' : ' foo ' , ' bar ' : ' with spaces ' } , ' ' ) ,
2009-06-18 15:04:00 +00:00
# Regression test for #11270.
' cache17 ' : ( ' { % lo ad cache % } { % c ache 10 long_cache_key poem % }Some Content { % e ndcache % } ' , { ' poem ' : ' Oh freddled gruntbuggly/Thy micturations are to me/As plurdled gabbleblotchits/On a lurgid bee/That mordiously hath bitled out/Its earted jurtles/Into a rancid festering/Or else I shall rend thee in the gobberwarts with my blurglecruncheon/See if I dont. ' } , ' Some Content ' ) ,
2010-10-11 12:55:17 +00:00
2013-02-23 09:24:35 +00:00
# Test whitespace in filter arguments
' cache18 ' : ( ' { % lo ad cache custom % } { % c ache 2|noop: " x y " cache18 % }cache18 { % e ndcache % } ' , { } , ' cache18 ' ) ,
2007-11-14 12:58:53 +00:00
### AUTOESCAPE TAG ##############################################
' autoescape-tag01 ' : ( " { % a utoescape off % }hello { % e ndautoescape % } " , { } , " hello " ) ,
' autoescape-tag02 ' : ( " { % a utoescape off % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>hello</b> " } , " <b>hello</b> " ) ,
' autoescape-tag03 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>hello</b> " } , " <b>hello</b> " ) ,
2006-08-27 13:59:47 +00:00
2007-11-14 12:58:53 +00:00
# Autoescape disabling and enabling nest in a predictable way.
' autoescape-tag04 ' : ( " { % a utoescape off % } {{ first }} { % a utoescape on % } {{ first }} { % e ndautoescape % } { % e ndautoescape % } " , { " first " : " <a> " } , " <a> <a> " ) ,
2006-08-27 13:59:47 +00:00
2007-11-14 12:58:53 +00:00
' autoescape-tag05 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : " <b>first</b> " } , " <b>first</b> " ) ,
2006-08-27 13:59:47 +00:00
2007-11-14 12:58:53 +00:00
# Strings (ASCII or unicode) already marked as "safe" are not
# auto-escaped
' autoescape-tag06 ' : ( " {{ first }} " , { " first " : mark_safe ( " <b>first</b> " ) } , " <b>first</b> " ) ,
2012-06-07 16:08:47 +00:00
' autoescape-tag07 ' : ( " { % a utoescape on % } {{ first }} { % e ndautoescape % } " , { " first " : mark_safe ( " <b>Apple</b> " ) } , " <b>Apple</b> " ) ,
2006-10-24 21:30:38 +00:00
2007-11-17 12:11:26 +00:00
# Literal string arguments to filters, if used in the result, are
# safe.
2007-11-29 01:44:30 +00:00
' autoescape-tag08 ' : ( r ' { % a utoescape on % } {{ var|default_if_none: " endquote \ " hah " }} { % e ndautoescape % } ' , { " var " : None } , ' endquote " hah ' ) ,
# Objects which return safe strings as their __unicode__ method
# won't get double-escaped.
' autoescape-tag09 ' : ( r ' {{ unsafe }} ' , { ' unsafe ' : filters . UnsafeClass ( ) } , ' you & me ' ) ,
' autoescape-tag10 ' : ( r ' {{ safe }} ' , { ' safe ' : filters . SafeClass ( ) } , ' you > me ' ) ,
2006-10-24 21:30:38 +00:00
2007-11-14 12:58:53 +00:00
# The "safe" and "escape" filters cannot work due to internal
# implementation details (fortunately, the (no)autoescape block
# tags can be used in those cases)
' autoescape-filtertag01 ' : ( " {{ first }} { % f ilter safe % } {{ first }} x<y { % e ndfilter % } " , { " first " : " <a> " } , template . TemplateSyntaxError ) ,
2010-10-11 12:55:17 +00:00
2010-08-03 15:34:59 +00:00
# ifqeual compares unescaped vales.
2013-10-14 19:13:14 +00:00
' autoescape-ifequal01 ' : ( ' { % i fequal var " this & that " % }yes { % e ndifequal % } ' , { " var " : " this & that " } , " yes " ) ,
2010-10-11 12:55:17 +00:00
# Arguments to filters are 'safe' and manipulate their input unescaped.
2013-10-14 19:13:14 +00:00
' autoescape-filters01 ' : ( ' {{ var|cut: " & " }} ' , { " var " : " this & that " } , " this that " ) ,
' autoescape-filters02 ' : ( ' {{ var|join: " & \" }} ' , { " var " : ( " Tom " , " Dick " , " Harry " ) } , " Tom & Dick & Harry " ) ,
2010-10-11 12:55:17 +00:00
# Literal strings are safe.
2013-10-26 19:15:03 +00:00
' autoescape-literals01 ' : ( ' {{ " this & that " }} ' , { } , " this & that " ) ,
2010-10-11 12:55:17 +00:00
# Iterating over strings outputs safe characters.
2010-11-17 15:36:26 +00:00
' autoescape-stringiterations01 ' : ( ' { % f or l in var % } {{ l }}, { % e ndfor % } ' , { ' var ' : ' K&R ' } , " K,&,R, " ) ,
2010-10-11 12:55:17 +00:00
# Escape requirement survives lookup.
2013-10-14 19:13:14 +00:00
' autoescape-lookup01 ' : ( ' {{ var.key }} ' , { " var " : { " key " : " this & that " } } , " this & that " ) ,
2010-10-11 12:55:17 +00:00
2010-11-17 15:36:26 +00:00
# Static template tags
' static-prefixtag01 ' : ( ' { % lo ad static % } { % g et_static_prefix % } ' , { } , settings . STATIC_URL ) ,
' static-prefixtag02 ' : ( ' { % lo ad static % } { % g et_static_prefix as static_prefix % } {{ static_prefix }} ' , { } , settings . STATIC_URL ) ,
' static-prefixtag03 ' : ( ' { % lo ad static % } { % g et_media_prefix % } ' , { } , settings . MEDIA_URL ) ,
' static-prefixtag04 ' : ( ' { % lo ad static % } { % g et_media_prefix as media_prefix % } {{ media_prefix }} ' , { } , settings . MEDIA_URL ) ,
2011-06-30 09:06:19 +00:00
' static-statictag01 ' : ( ' { % lo ad static % } { % s tatic " admin/base.css " % } ' , { } , urljoin ( settings . STATIC_URL , ' admin/base.css ' ) ) ,
' static-statictag02 ' : ( ' { % lo ad static % } { % s tatic base_css % } ' , { ' base_css ' : ' admin/base.css ' } , urljoin ( settings . STATIC_URL , ' admin/base.css ' ) ) ,
2012-07-07 13:30:25 +00:00
' static-statictag03 ' : ( ' { % lo ad static % } { % s tatic " admin/base.css " as foo % } {{ foo }} ' , { } , urljoin ( settings . STATIC_URL , ' admin/base.css ' ) ) ,
' static-statictag04 ' : ( ' { % lo ad static % } { % s tatic base_css as foo % } {{ foo }} ' , { ' base_css ' : ' admin/base.css ' } , urljoin ( settings . STATIC_URL , ' admin/base.css ' ) ) ,
2012-06-07 07:59:14 +00:00
# Verbatim template tag outputs contents without rendering.
' verbatim-tag01 ' : ( ' { % verbatim % } {{ bare }} { % e ndverbatim % } ' , { } , ' {{ bare }} ' ) ,
' verbatim-tag02 ' : ( ' { % verbatim % } { % e ndif % } { % e ndverbatim % } ' , { } , ' { % e ndif % } ' ) ,
' verbatim-tag03 ' : ( " { % verbatim % }It ' s the { % verbatim % } tag { % e ndverbatim % } " , { } , " It ' s the { % verbatim % } tag " ) ,
' verbatim-tag04 ' : ( ' { % verbatim % } { % verbatim % } { % e ndverbatim % } { % e ndverbatim % } ' , { } , template . TemplateSyntaxError ) ,
' verbatim-tag05 ' : ( ' { % verbatim % } { % e ndverbatim % } { % verbatim % } { % e ndverbatim % } ' , { } , ' ' ) ,
2012-06-18 22:49:30 +00:00
' verbatim-tag06 ' : ( " { % verbatim special % }Don ' t { % e ndverbatim % } just yet { % e ndverbatim special % } " , { } , " Don ' t { % e ndverbatim % } just yet " ) ,
2007-11-14 12:58:53 +00:00
}
2013-02-15 07:29:15 +00:00
if numpy :
tests . update ( {
# Numpy's array-index syntax allows a template to access a certain item of a subscriptable object.
' numpy-array-index01 ' : ( " {{ var.1 }} " , { " var " : numpy . array ( [ " first item " , " second item " ] ) } , " second item " ) ,
# Fail silently when the array index is out of range.
' numpy-array-index02 ' : ( " {{ var.5 }} " , { " var " : numpy . array ( [ " first item " , " second item " ] ) } , ( " " , " INVALID " ) ) ,
} )
2011-08-25 23:02:15 +00:00
return tests
2006-08-27 13:59:47 +00:00
2013-10-17 23:58:02 +00:00
2013-10-14 13:14:17 +00:00
class TemplateTagLoading ( TestCase ) :
2010-04-15 19:57:09 +00:00
def setUp ( self ) :
2012-12-08 10:13:52 +00:00
self . egg_dir = ' %s /eggs ' % os . path . dirname ( upath ( __file__ ) )
2010-11-27 05:47:30 +00:00
self . old_tag_modules = template_base . templatetags_modules
template_base . templatetags_modules = [ ]
2010-04-15 19:57:09 +00:00
def tearDown ( self ) :
2010-11-27 05:47:30 +00:00
template_base . templatetags_modules = self . old_tag_modules
2010-04-15 19:57:09 +00:00
def test_load_error ( self ) :
ttext = " { % lo ad broken_tag % } "
self . assertRaises ( template . TemplateSyntaxError , template . Template , ttext )
try :
template . Template ( ttext )
2012-04-28 16:09:37 +00:00
except template . TemplateSyntaxError as e :
2010-04-15 19:57:09 +00:00
self . assertTrue ( ' ImportError ' in e . args [ 0 ] )
self . assertTrue ( ' Xtemplate ' in e . args [ 0 ] )
def test_load_error_egg ( self ) :
ttext = " { % lo ad broken_egg % } "
egg_name = ' %s /tagsegg.egg ' % self . egg_dir
2014-01-26 05:50:40 +00:00
with extend_sys_path ( egg_name ) :
with self . assertRaises ( template . TemplateSyntaxError ) :
with self . settings ( INSTALLED_APPS = [ ' tagsegg ' ] ) :
template . Template ( ttext )
try :
with self . settings ( INSTALLED_APPS = [ ' tagsegg ' ] ) :
template . Template ( ttext )
except template . TemplateSyntaxError as e :
self . assertTrue ( ' ImportError ' in e . args [ 0 ] )
self . assertTrue ( ' Xtemplate ' in e . args [ 0 ] )
2010-04-15 19:57:09 +00:00
def test_load_working_egg ( self ) :
ttext = " { % lo ad working_egg % } "
egg_name = ' %s /tagsegg.egg ' % self . egg_dir
2014-01-26 05:50:40 +00:00
with extend_sys_path ( egg_name ) :
with self . settings ( INSTALLED_APPS = [ ' tagsegg ' ] ) :
template . Template ( ttext )
2010-04-15 19:57:09 +00:00
2011-04-17 04:52:31 +00:00
2012-04-09 13:24:57 +00:00
class RequestContextTests ( unittest . TestCase ) :
2011-04-17 04:52:31 +00:00
def setUp ( self ) :
templates = {
' child ' : Template ( ' {{ var|default: " none " }} ' ) ,
}
setup_test_template_loader ( templates )
self . fake_request = RequestFactory ( ) . get ( ' / ' )
def tearDown ( self ) :
restore_template_loaders ( )
def test_include_only ( self ) :
"""
Regression test for #15721, ``{% include %}`` and ``RequestContext``
not playing together nicely .
"""
ctx = RequestContext ( self . fake_request , { ' var ' : ' parent ' } )
self . assertEqual (
template . Template ( ' { % i nclude " child " % } ' ) . render ( ctx ) ,
' parent '
)
self . assertEqual (
template . Template ( ' { % i nclude " child " only % } ' ) . render ( ctx ) ,
' none '
)
2013-08-29 04:08:01 +00:00
def test_stack_size ( self ) :
"""
Regression test for #7116, Optimize RequetsContext construction
"""
ctx = RequestContext ( self . fake_request , { } )
# The stack should now contain 3 items:
# [builtins, supplied context, context processor]
self . assertEqual ( len ( ctx . dicts ) , 3 )
2013-08-27 22:50:11 +00:00
2014-02-15 12:45:52 +00:00
@override_settings ( TEMPLATE_CONTEXT_PROCESSORS = ( ) )
def test_context_comparable ( self ) :
test_data = { ' x ' : ' y ' , ' v ' : ' z ' , ' d ' : { ' o ' : object , ' a ' : ' b ' } }
# test comparing RequestContext to prevent problems if somebody
# adds __eq__ in the future
request = RequestFactory ( ) . get ( ' / ' )
2014-02-17 03:54:36 +00:00
self . assertEqual (
2014-02-15 12:45:52 +00:00
RequestContext ( request , dict_ = test_data ) ,
RequestContext ( request , dict_ = test_data )
)
2013-08-27 22:50:11 +00:00
class SSITests ( TestCase ) :
def setUp ( self ) :
self . this_dir = os . path . dirname ( os . path . abspath ( upath ( __file__ ) ) )
self . ssi_dir = os . path . join ( self . this_dir , " templates " , " first " )
def render_ssi ( self , path ) :
# the path must exist for the test to be reliable
self . assertTrue ( os . path . exists ( path ) )
return template . Template ( ' { %% ssi " %s " %% } ' % path ) . render ( Context ( ) )
def test_allowed_paths ( self ) :
acceptable_path = os . path . join ( self . ssi_dir , " .. " , " first " , " test.html " )
with override_settings ( ALLOWED_INCLUDE_ROOTS = ( self . ssi_dir , ) ) :
self . assertEqual ( self . render_ssi ( acceptable_path ) , ' First template \n ' )
def test_relative_include_exploit ( self ) :
"""
May not bypass ALLOWED_INCLUDE_ROOTS with relative paths
e . g . if ALLOWED_INCLUDE_ROOTS = ( " /var/www " , ) , it should not be
possible to do { % ssi " /var/www/../../etc/passwd " % }
"""
disallowed_paths = [
os . path . join ( self . ssi_dir , " .. " , " ssi_include.html " ) ,
os . path . join ( self . ssi_dir , " .. " , " second " , " test.html " ) ,
]
with override_settings ( ALLOWED_INCLUDE_ROOTS = ( self . ssi_dir , ) ) :
for path in disallowed_paths :
self . assertEqual ( self . render_ssi ( path ) , ' ' )