2006-12-06 03:48:46 +08:00
# -*- coding: utf-8 -*-
2006-08-27 21:59:47 +08:00
from django . conf import settings
if __name__ == ' __main__ ' :
# When running this file in isolation, we need to set up the configuration
# before importing 'template'.
settings . configure ( )
from django import template
from django . template import loader
from django . utils . translation import activate , deactivate , install
from django . utils . tzinfo import LocalTimezone
from datetime import datetime , timedelta
import unittest
#################################
# Custom template tag for tests #
#################################
register = template . Library ( )
class EchoNode ( template . Node ) :
def __init__ ( self , contents ) :
self . contents = contents
def render ( self , context ) :
return " " . join ( self . contents )
def do_echo ( parser , token ) :
return EchoNode ( token . contents . split ( ) [ 1 : ] )
register . tag ( " echo " , do_echo )
template . libraries [ ' django.templatetags.testtags ' ] = register
#####################################
# Helper objects for template tests #
#####################################
class SomeException ( Exception ) :
silent_variable_failure = True
class SomeOtherException ( Exception ) :
pass
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
class OtherClass :
def method ( self ) :
return " OtherClass.method "
2006-12-06 03:48:46 +08:00
class UnicodeInStrClass :
" Class whose __str__ returns a Unicode object. "
def __str__ ( self ) :
return u ' ŠĐĆŽćžšđ '
2006-08-27 21:59:47 +08:00
class Templates ( unittest . TestCase ) :
def test_templates ( self ) :
# NOW and NOW_tz are used by timesince tag tests.
NOW = datetime . now ( )
NOW_tz = datetime . now ( LocalTimezone ( datetime . now ( ) ) )
# SYNTAX --
# 'template_name': ('template contents', 'context dict', 'expected string output' or Exception class)
TEMPLATE_TESTS = {
### BASIC SYNTAX ##########################################################
# Plain text should go through the template parser untouched
' basic-syntax01 ' : ( " something cool " , { } , " something cool " ) ,
# Variables should be replaced with their value in the current context
' basic-syntax02 ' : ( " {{ headline }} " , { ' headline ' : ' Success ' } , " Success " ) ,
# More than one replacement variable is allowed in a template
' basic-syntax03 ' : ( " {{ first }} --- {{ second }} " , { " first " : 1 , " second " : 2 } , " 1 --- 2 " ) ,
# Fail silently when a variable is not found in the current context
2006-09-04 22:02:11 +08:00
' basic-syntax04 ' : ( " as {{ missing }}df " , { } , ( " asdf " , " asINVALIDdf " ) ) ,
2006-08-27 21:59:47 +08:00
# A variable may not contain more than one word
' basic-syntax06 ' : ( " {{ multi word variable }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for empty variable tags
' basic-syntax07 ' : ( " {{ }} " , { } , template . TemplateSyntaxError ) ,
' 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
2006-09-04 22:02:11 +08:00
' basic-syntax11 ' : ( " {{ var.blech }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08: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
' basic-syntax18 ' : ( " {{ foo.bar }} " , { " foo " : { " bar " : " baz " } } , " baz " ) ,
# Fail silently when a variable's dictionary key isn't found
2006-09-04 22:02:11 +08:00
' basic-syntax19 ' : ( " {{ foo.spam }} " , { " foo " : { " bar " : " baz " } } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08:00
# Fail silently when accessing a non-simple method
2006-09-04 22:02:11 +08:00
' basic-syntax20 ' : ( " {{ var.method2 }} " , { " var " : SomeClass ( ) } , ( " " , " INVALID " ) ) ,
2006-08-27 21:59:47 +08:00
2007-02-28 04:25:27 +08: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 " ) ,
2006-08-27 21:59:47 +08:00
# Basic filter usage
' basic-syntax21 ' : ( " {{ var|upper }} " , { " var " : " Django is the greatest! " } , " DJANGO IS THE GREATEST! " ) ,
# Chained filters
' basic-syntax22 ' : ( " {{ var|upper|lower }} " , { " var " : " Django is the greatest! " } , " django is the greatest! " ) ,
# Raise TemplateSyntaxError for space between a variable and filter pipe
' basic-syntax23 ' : ( " {{ var |upper }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for space after a filter pipe
' basic-syntax24 ' : ( " {{ var| upper }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for a nonexistent filter
' basic-syntax25 ' : ( " {{ var|does_not_exist }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError when trying to access a filter containing an illegal character
' basic-syntax26 ' : ( " {{ var|fil(ter) }} " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for invalid block tags
' basic-syntax27 ' : ( " { % nothing_to_see_here % } " , { } , template . TemplateSyntaxError ) ,
# Raise TemplateSyntaxError for empty block tags
' basic-syntax28 ' : ( " { % % } " , { } , template . TemplateSyntaxError ) ,
# Chained filters, with an argument to the first one
' basic-syntax29 ' : ( ' {{ var|removetags: " b i " |upper|lower }} ' , { " var " : " <b><i>Yes</i></b> " } , " yes " ) ,
# Escaped string as argument
' basic-syntax30 ' : ( r ' {{ var|default_if_none: " endquote \ " hah " }} ' , { " var " : None } , ' endquote " hah ' ) ,
# Variable as argument
' basic-syntax31 ' : ( r ' {{ var|default_if_none:var2 }} ' , { " var " : None , " var2 " : " happy " } , ' happy ' ) ,
# Default argument testing
' basic-syntax32 ' : ( r ' {{ var|yesno: " yup,nup,mup " }} {{ var|yesno }} ' , { " var " : True } , ' yup yes ' ) ,
# Fail silently for methods that raise an exception with a "silent_variable_failure" attribute
2006-09-04 22:02:11 +08:00
' basic-syntax33 ' : ( r ' 1 {{ var.method3 }}2 ' , { " var " : SomeClass ( ) } , ( " 12 " , " 1INVALID2 " ) ) ,
2006-08-27 21:59:47 +08:00
# In methods that raise an exception without a "silent_variable_attribute" set to True,
2007-02-28 04:25:27 +08:00
# the exception propagates
2006-08-27 21:59:47 +08:00
' basic-syntax34 ' : ( r ' 1 {{ var.method4 }}2 ' , { " var " : SomeClass ( ) } , SomeOtherException ) ,
# Escaped backslash in argument
' basic-syntax35 ' : ( r ' {{ var|default_if_none: " foo \ bar " }} ' , { " var " : None } , r ' foo \ bar ' ) ,
# Escaped backslash using known escape char
' basic-syntax35 ' : ( r ' {{ var|default_if_none: " foo \ now " }} ' , { " var " : None } , r ' foo \ now ' ) ,
2006-09-26 15:26:07 +08:00
# Empty strings can be passed as arguments to filters
' basic-syntax36 ' : ( r ' {{ var|join: " " }} ' , { ' var ' : [ ' a ' , ' b ' , ' c ' ] } , ' abc ' ) ,
2006-12-06 03:48:46 +08:00
# If a variable has a __str__() that returns a Unicode object, the value
# will be converted to a bytestring.
' basic-syntax37 ' : ( r ' {{ var }} ' , { ' var ' : UnicodeInStrClass ( ) } , ' \xc5 \xa0 \xc4 \x90 \xc4 \x86 \xc5 \xbd \xc4 \x87 \xc5 \xbe \xc5 \xa1 \xc4 \x91 ' ) ,
2006-10-25 05:30:38 +08: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 21:59:47 +08: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 21:09:00 +08:00
' cycle08 ' : ( ' { % c ycle a,b,c as foo % } { % c ycle foo % } {{ foo }} {{ foo }} { % c ycle foo % } {{ foo }} ' , { } , ' abbbcc ' ) ,
2006-08-27 21:59:47 +08:00
### EXCEPTIONS ############################################################
# Raise exception for invalid template name
' exception01 ' : ( " { % e xtends ' nonexistent ' % } " , { } , template . TemplateSyntaxError ) ,
# Raise exception for invalid template name (in variable)
' exception02 ' : ( " { % e xtends nonexistent % } " , { } , template . TemplateSyntaxError ) ,
# 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 ' ) ,
### FIRSTOF TAG ###########################################################
' 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 % } ' , { } , template . TemplateSyntaxError ) ,
### 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 " ) ,
### 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 " ) ,
# 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 ' ) ,
# TODO: multiple ORs
# NOT
' if-tag-not01 ' : ( " { % i f not foo % }no { % e lse % }yes { % e ndif % } " , { ' foo ' : True } , ' yes ' ) ,
' if-tag-not02 ' : ( " { % i f not % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : True } , ' no ' ) ,
' if-tag-not03 ' : ( " { % i f not % }yes { % e lse % }no { % e ndif % } " , { ' not ' : True } , ' yes ' ) ,
' if-tag-not04 ' : ( " { % i f not not % }no { % e lse % }yes { % e ndif % } " , { ' not ' : True } , ' yes ' ) ,
' if-tag-not05 ' : ( " { % i f not not % }no { % e lse % }yes { % e ndif % } " , { } , ' no ' ) ,
' 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 ' ) ,
# AND and OR raises a TemplateSyntaxError
' if-tag-error01 ' : ( " { % i f foo or bar and baz % }yes { % e lse % }no { % e ndif % } " , { ' foo ' : False , ' bar ' : False } , template . TemplateSyntaxError ) ,
' 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 ) ,
### IFCHANGED TAG #########################################################
' 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 ' ) ,
2006-09-23 17:49:58 +08: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 ' ) ,
2006-12-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Test one parameter given to ifchanged.
' 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-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Test multiple parameters to ifchanged.
' 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-06 03:48:46 +08:00
2006-11-07 13:36:51 +08: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.
' 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-06 03:48:46 +08:00
2006-11-07 13:36:51 +08:00
# Logically the same as above, just written with explicit
# ifchanged for the day.
' ifchanged-param04 ' : ( ' { % 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 21:59:47 +08: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 14:12:15 +08: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 ' ) ,
2006-08-27 21:59:47 +08: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 " ) ,
### INCLUDE TAG ###########################################################
' 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 " ) ,
' include04 ' : ( ' a { % i nclude " nonexistent " % }b ' , { } , " ab " ) ,
2007-02-12 08:22:22 +08: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 10:54:17 +08:00
' namedendblocks02 ' : ( " 1 { % block first % }_ { % block second % }2 { % e ndblock first % }_ { % e ndblock second % }3 " , { } , template . TemplateSyntaxError ) ,
2007-02-12 08:22:22 +08: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 21:59:47 +08:00
### INHERITANCE ###########################################################
# Standard template with no inheritance
' inheritance01 ' : ( " 1 { % block first % }_ { % e ndblock % }3 { % block second % }_ { % e ndblock % } " , { } , ' 1_3_ ' ) ,
# 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
' inheritance04 ' : ( " { % e xtends ' inheritance01 ' % } " , { } , ' 1_3_ ' ) ,
# 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
' inheritance07 ' : ( " { % e xtends ' inheritance01 ' % } { % block second % }5 { % e ndblock % } " , { } , ' 1_35 ' ) ,
# 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
' inheritance09 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1_3_ ' ) ,
# Three-level with space NOT in a block -- should be ignored
' inheritance10 ' : ( " { % e xtends ' inheritance04 ' % } " , { } , ' 1_3_ ' ) ,
# 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
' inheritance14 ' : ( " { % e xtends ' inheritance01 ' % } { % block newblock % }NO DISPLAY { % e ndblock % } " , { } , ' 1_3_ ' ) ,
# 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 }}
' inheritance20 ' : ( " { % e xtends ' inheritance01 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1_a3_ ' ) ,
# 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
' inheritance22 ' : ( " { % e xtends ' inheritance04 ' % } { % block first % } {{ block.super }}a { % e ndblock % } " , { } , ' 1_a3_ ' ) ,
# Three-level inheritance with {{ block.super }} from parent and grandparent
' inheritance23 ' : ( " { % e xtends ' inheritance20 ' % } { % block first % } {{ block.super }}b { % e ndblock % } " , { } , ' 1_ab3_ ' ) ,
# 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 ' ) ,
### I18N ##################################################################
# {% spaceless %} tag
' 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> " ) ,
' spaceless03 ' : ( " { % s paceless % }<b><i>text</i></b> { % e ndspaceless % } " , { } , " <b><i>text</i></b> " ) ,
# 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
' i18n03 ' : ( ' { % lo ad i18n % } { % blocktrans % } {{ anton }} { % e ndblocktrans % } ' , { ' anton ' : ' xxxyyyxxx ' } , " xxxyyyxxx " ) ,
# simple translation of a variable and filter
' i18n04 ' : ( ' { % lo ad i18n % } { % blocktrans with anton|lower as berta % } {{ berta }} { % e ndblocktrans % } ' , { ' anton ' : ' XXXYYYXXX ' } , " xxxyyyxxx " ) ,
# 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
' i18n07 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % }plural { % e ndblocktrans % } ' , { ' number ' : 1 } , " singular " ) ,
# translation of plural form
' i18n08 ' : ( ' { % lo ad i18n % } { % blocktrans count number as counter % }singular { % plural % }plural { % e ndblocktrans % } ' , { ' number ' : 2 } , " plural " ) ,
# 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
' i18n10 ' : ( ' {{ bool|yesno:_( " ja,nein " ) }} ' , { ' bool ' : True } , ' ja ' ) ,
# 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 ' ) ,
# translation of a constant string
' i18n13 ' : ( ' {{ _( " Page not found " ) }} ' , { ' LANGUAGE_CODE ' : ' de ' } , ' Seite nicht gefunden ' ) ,
2006-09-04 22:02:11 +08:00
### HANDLING OF TEMPLATE_TAG_IF_INVALID ###################################
2006-10-25 05:30:38 +08:00
2006-09-04 22:02:11 +08:00
' invalidstr01 ' : ( ' {{ var|default: " Foo " }} ' , { } , ( ' Foo ' , ' INVALID ' ) ) ,
' invalidstr02 ' : ( ' {{ var|default_if_none: " Foo " }} ' , { } , ( ' ' , ' INVALID ' ) ) ,
' invalidstr03 ' : ( ' { % f or v in var % }( {{ v }}) { % e ndfor % } ' , { } , ' ' ) ,
' invalidstr04 ' : ( ' { % i f var % }Yes { % e lse % }No { % e ndif % } ' , { } , ' No ' ) ,
' invalidstr04 ' : ( ' { % i f var|default: " Foo " % }Yes { % e lse % }No { % e ndif % } ' , { } , ' Yes ' ) ,
2006-08-27 21:59:47 +08:00
### MULTILINE #############################################################
' multiline01 ' : ( """
Hello ,
boys .
How
are
you
gentlemen .
""" ,
{ } ,
"""
Hello ,
boys .
How
are
you
gentlemen .
""" ),
### REGROUP TAG ###########################################################
' 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 % }, ' + \
' { % e ndfor % } ' ,
{ ' data ' : [ { ' foo ' : ' c ' , ' bar ' : 1 } ,
{ ' foo ' : ' d ' , ' bar ' : 1 } ,
{ ' foo ' : ' a ' , ' bar ' : 2 } ,
{ ' foo ' : ' b ' , ' bar ' : 2 } ,
{ ' foo ' : ' x ' , ' bar ' : 3 } ] } ,
' 1:cd,2:ab,3:x, ' ) ,
# Test for silent failure when target variable isn't found
' 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 % }, ' + \
' { % e ndfor % } ' ,
2006-09-04 22:02:11 +08:00
{ } , ' ' ) ,
2006-08-27 21:59:47 +08: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 09:58:13 +08:00
' templatetag11 ' : ( ' { % templatetag opencomment % } ' , { } , ' { # ' ) ,
' templatetag12 ' : ( ' { % templatetag closecomment % } ' , { } , ' #} ' ) ,
2006-08-27 21:59:47 +08:00
### WIDTHRATIO TAG ########################################################
' widthratio01 ' : ( ' { % widthratio a b 0 % } ' , { ' a ' : 50 , ' b ' : 100 } , ' 0 ' ) ,
' widthratio02 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 0 , ' b ' : 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 ' ) ,
# 62.5 should round to 63
' widthratio06 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 80 } , ' 63 ' ) ,
# 71.4 should round to 71
' widthratio07 ' : ( ' { % widthratio a b 100 % } ' , { ' a ' : 50 , ' b ' : 70 } , ' 71 ' ) ,
# Raise exception if we don't have 3 args, last one an integer
' widthratio08 ' : ( ' { % widthratio % } ' , { } , template . TemplateSyntaxError ) ,
' widthratio09 ' : ( ' { % widthratio a b % } ' , { ' a ' : 50 , ' b ' : 100 } , template . TemplateSyntaxError ) ,
' widthratio10 ' : ( ' { % widthratio a b 100.0 % } ' , { ' a ' : 50 , ' b ' : 100 } , template . TemplateSyntaxError ) ,
### NOW TAG ########################################################
# Simple case
' now01 ' : ( ' { % now " j n Y " % } ' , { } , str ( datetime . now ( ) . day ) + ' ' + str ( datetime . now ( ) . month ) + ' ' + str ( datetime . now ( ) . year ) ) ,
# Check parsing of escaped and special characters
' now02 ' : ( ' { % now " j " n " Y " % } ' , { } , template . TemplateSyntaxError ) ,
# 'now03' : ('{% now "j \"n\" Y"%}', {}, str(datetime.now().day) + '"' + str(datetime.now().month) + '"' + str(datetime.now().year)),
# 'now04' : ('{% now "j \nn\n Y"%}', {}, str(datetime.now().day) + '\n' + str(datetime.now().month) + '\n' + str(datetime.now().year))
### TIMESINCE TAG ##################################################
# Default compare with datetime.now()
' timesince01 ' : ( ' {{ a|timesince }} ' , { ' a ' : datetime . now ( ) + timedelta ( minutes = - 1 , seconds = - 10 ) } , ' 1 minute ' ) ,
' timesince02 ' : ( ' {{ a|timesince }} ' , { ' a ' : ( datetime . now ( ) - timedelta ( days = 1 , minutes = 1 ) ) } , ' 1 day ' ) ,
' timesince03 ' : ( ' {{ a|timesince }} ' , { ' a ' : ( datetime . now ( ) -
timedelta ( hours = 1 , minutes = 25 , seconds = 10 ) ) } , ' 1 hour, 25 minutes ' ) ,
# Compare to a given parameter
' timesince04 ' : ( ' {{ a|timesince:b }} ' , { ' a ' : NOW + timedelta ( days = 2 ) , ' b ' : NOW + timedelta ( days = 1 ) } , ' 1 day ' ) ,
' timesince05 ' : ( ' {{ a|timesince:b }} ' , { ' a ' : NOW + timedelta ( days = 2 , minutes = 1 ) , ' b ' : NOW + timedelta ( days = 2 ) } , ' 1 minute ' ) ,
# Check that timezone is respected
' timesince06 ' : ( ' {{ a|timesince:b }} ' , { ' a ' : NOW_tz + timedelta ( hours = 8 ) , ' b ' : NOW_tz } , ' 8 hours ' ) ,
### TIMEUNTIL TAG ##################################################
# Default compare with datetime.now()
' timeuntil01 ' : ( ' {{ a|timeuntil }} ' , { ' a ' : datetime . now ( ) + timedelta ( minutes = 2 , seconds = 10 ) } , ' 2 minutes ' ) ,
' timeuntil02 ' : ( ' {{ a|timeuntil }} ' , { ' a ' : ( datetime . now ( ) + timedelta ( days = 1 , seconds = 10 ) ) } , ' 1 day ' ) ,
' timeuntil03 ' : ( ' {{ a|timeuntil }} ' , { ' a ' : ( datetime . now ( ) + timedelta ( hours = 8 , minutes = 10 , seconds = 10 ) ) } , ' 8 hours, 10 minutes ' ) ,
# Compare to a given parameter
' timeuntil04 ' : ( ' {{ a|timeuntil:b }} ' , { ' a ' : NOW - timedelta ( days = 1 ) , ' b ' : NOW - timedelta ( days = 2 ) } , ' 1 day ' ) ,
' timeuntil05 ' : ( ' {{ a|timeuntil:b }} ' , { ' a ' : NOW - timedelta ( days = 2 ) , ' b ' : NOW - timedelta ( days = 2 , minutes = 1 ) } , ' 1 minute ' ) ,
2007-02-13 12:24:58 +08:00
### URL TAG ########################################################
# Successes
' url01 ' : ( ' { % u rl regressiontests.templates.views.client client.id % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/client/1/ ' ) ,
' url02 ' : ( ' { % u rl regressiontests.templates.views.client_action client.id,action= " update " % } ' , { ' client ' : { ' id ' : 1 } } , ' /url_tag/client/1/update/ ' ) ,
' url03 ' : ( ' { % u rl regressiontests.templates.views.index % } ' , { } , ' /url_tag/ ' ) ,
# Failures
' url04 ' : ( ' { % u rl % } ' , { } , template . TemplateSyntaxError ) ,
' url05 ' : ( ' { % u rl no_such_view % } ' , { } , ' ' ) ,
' url06 ' : ( ' { % u rl regressiontests.templates.views.client no_such_param= " value " % } ' , { } , ' ' ) ,
2006-08-27 21:59:47 +08:00
}
# Register our custom template loader.
def test_template_loader ( template_name , template_dirs = None ) :
" A custom template loader that loads the unit-test templates. "
try :
return ( TEMPLATE_TESTS [ template_name ] [ 0 ] , " test: %s " % template_name )
except KeyError :
raise template . TemplateDoesNotExist , template_name
old_template_loaders = loader . template_source_loaders
loader . template_source_loaders = [ test_template_loader ]
failures = [ ]
tests = TEMPLATE_TESTS . items ( )
tests . sort ( )
# Turn TEMPLATE_DEBUG off, because tests assume that.
old_td , settings . TEMPLATE_DEBUG = settings . TEMPLATE_DEBUG , False
2006-10-25 05:30:38 +08:00
# Set TEMPLATE_STRING_IF_INVALID to a known string
2006-09-04 22:02:11 +08:00
old_invalid = settings . TEMPLATE_STRING_IF_INVALID
2006-10-25 05:30:38 +08:00
2006-08-27 21:59:47 +08:00
for name , vals in tests :
install ( )
2006-10-25 05:30:38 +08:00
2006-09-04 22:02:11 +08:00
if isinstance ( vals [ 2 ] , tuple ) :
normal_string_result = vals [ 2 ] [ 0 ]
invalid_string_result = vals [ 2 ] [ 1 ]
else :
normal_string_result = vals [ 2 ]
invalid_string_result = vals [ 2 ]
2006-10-25 05:30:38 +08:00
2006-08-27 21:59:47 +08:00
if ' LANGUAGE_CODE ' in vals [ 1 ] :
activate ( vals [ 1 ] [ ' LANGUAGE_CODE ' ] )
else :
activate ( ' en-us ' )
2006-09-04 22:02:11 +08:00
for invalid_str , result in [ ( ' ' , normal_string_result ) ,
( ' INVALID ' , invalid_string_result ) ] :
settings . TEMPLATE_STRING_IF_INVALID = invalid_str
try :
output = loader . get_template ( name ) . render ( template . Context ( vals [ 1 ] ) )
except Exception , e :
if e . __class__ != result :
failures . append ( " Template test (TEMPLATE_STRING_IF_INVALID= ' %s ' ): %s -- FAILED. Got %s , exception: %s " % ( invalid_str , name , e . __class__ , e ) )
continue
if output != result :
failures . append ( " Template test (TEMPLATE_STRING_IF_INVALID= ' %s ' ): %s -- FAILED. Expected %r , got %r " % ( invalid_str , name , result , output ) )
2006-10-25 05:30:38 +08:00
2006-08-27 21:59:47 +08:00
if ' LANGUAGE_CODE ' in vals [ 1 ] :
deactivate ( )
2006-10-25 05:30:38 +08:00
2006-08-27 21:59:47 +08:00
loader . template_source_loaders = old_template_loaders
deactivate ( )
settings . TEMPLATE_DEBUG = old_td
settings . TEMPLATE_STRING_IF_INVALID = old_invalid
2006-09-04 22:02:11 +08:00
self . assertEqual ( failures , [ ] , ' \n ' . join ( failures ) )
2006-08-27 21:59:47 +08:00
if __name__ == " __main__ " :
unittest . main ( )