blob: 50510b0d353791c5dd3c3fd213cfc1545a9576cc [file] [log] [blame]
Armin Ronacher58875382007-02-27 19:40:14 +01001# -*- coding: utf-8 -*-
2"""
Armin Ronacher26c0f512008-04-17 11:16:01 +02003 jinja2.tests
4 ~~~~~~~~~~~~
Armin Ronacher58875382007-02-27 19:40:14 +01005
6 Jinja test functions. Used with the "is" operator.
7
Armin Ronacher55494e42010-01-22 09:41:48 +01008 :copyright: (c) 2010 by the Jinja Team.
Armin Ronacher58875382007-02-27 19:40:14 +01009 :license: BSD, see LICENSE for more details.
10"""
11import re
Armin Ronacher577ad382008-04-16 15:36:49 +020012from jinja2.runtime import Undefined
Armin Ronacher58875382007-02-27 19:40:14 +010013
Armin Ronacheree352ec2011-05-24 16:40:23 +020014try:
15 from collections import Mapping as MappingType
16except ImportError:
17 import UserDict
18 MappingType = (UserDict.UserDict, UserDict.DictMixin, dict)
19
Armin Ronacher8e64adf2010-02-07 02:00:11 +010020# nose, nothing here to test
21__test__ = False
22
Armin Ronacher58875382007-02-27 19:40:14 +010023
Armin Ronacherab45b842007-03-18 20:47:50 +010024number_re = re.compile(r'^-?\d+(\.\d+)?$')
Armin Ronacher58875382007-02-27 19:40:14 +010025regex_type = type(number_re)
26
27
Armin Ronacher42a19882009-08-05 18:45:39 +020028try:
29 test_callable = callable
30except NameError:
31 def test_callable(x):
32 return hasattr(x, '__call__')
33
34
Armin Ronacher577ad382008-04-16 15:36:49 +020035def test_odd(value):
36 """Return true if the variable is odd."""
37 return value % 2 == 1
Armin Ronacher58875382007-02-27 19:40:14 +010038
39
Armin Ronacher577ad382008-04-16 15:36:49 +020040def test_even(value):
Lukas Meuserad48a2e2008-05-01 18:19:57 +020041 """Return true if the variable is even."""
Armin Ronacher577ad382008-04-16 15:36:49 +020042 return value % 2 == 0
Armin Ronacher58875382007-02-27 19:40:14 +010043
44
Armin Ronacherf59bac22008-04-20 13:11:43 +020045def test_divisibleby(value, num):
46 """Check if a variable is divisible by a number."""
47 return value % num == 0
48
49
Armin Ronacher577ad382008-04-16 15:36:49 +020050def test_defined(value):
51 """Return true if the variable is defined:
Armin Ronacher58875382007-02-27 19:40:14 +010052
Armin Ronacher37a88512007-03-02 20:42:18 +010053 .. sourcecode:: jinja
54
55 {% if variable is defined %}
56 value of variable: {{ variable }}
57 {% else %}
58 variable is not defined
59 {% endif %}
60
Armin Ronacher9f258ff2008-05-24 22:28:52 +020061 See the :func:`default` filter for a simple way to set undefined
Armin Ronacher26c0f512008-04-17 11:16:01 +020062 variables.
Armin Ronacher58875382007-02-27 19:40:14 +010063 """
Armin Ronacher577ad382008-04-16 15:36:49 +020064 return not isinstance(value, Undefined)
Armin Ronacher58875382007-02-27 19:40:14 +010065
66
Armin Ronacher53042292008-04-26 18:30:19 +020067def test_undefined(value):
Armin Ronacher9f258ff2008-05-24 22:28:52 +020068 """Like :func:`defined` but the other way round."""
Armin Ronacher53042292008-04-26 18:30:19 +020069 return isinstance(value, Undefined)
70
71
72def test_none(value):
73 """Return true if the variable is none."""
74 return value is None
75
76
Armin Ronacher577ad382008-04-16 15:36:49 +020077def test_lower(value):
Armin Ronacher53042292008-04-26 18:30:19 +020078 """Return true if the variable is lowercased."""
Armin Ronacher577ad382008-04-16 15:36:49 +020079 return unicode(value).islower()
Armin Ronacher58875382007-02-27 19:40:14 +010080
81
Armin Ronacher577ad382008-04-16 15:36:49 +020082def test_upper(value):
Armin Ronacher53042292008-04-26 18:30:19 +020083 """Return true if the variable is uppercased."""
Armin Ronacher577ad382008-04-16 15:36:49 +020084 return unicode(value).isupper()
Armin Ronacher58875382007-02-27 19:40:14 +010085
86
Armin Ronacher53042292008-04-26 18:30:19 +020087def test_string(value):
88 """Return true if the object is a string."""
89 return isinstance(value, basestring)
90
91
Armin Ronacheree352ec2011-05-24 16:40:23 +020092def test_mapping(value):
93 """Return true if the object is a mapping (dict etc.).
94
95 .. versionadded:: 2.6
96 """
97 return isinstance(value, MappingType)
98
99
Armin Ronacher53042292008-04-26 18:30:19 +0200100def test_number(value):
101 """Return true if the variable is a number."""
102 return isinstance(value, (int, long, float, complex))
Armin Ronacher58875382007-02-27 19:40:14 +0100103
104
Armin Ronacher577ad382008-04-16 15:36:49 +0200105def test_sequence(value):
106 """Return true if the variable is a sequence. Sequences are variables
Armin Ronacher37a88512007-03-02 20:42:18 +0100107 that are iterable.
Armin Ronacher58875382007-02-27 19:40:14 +0100108 """
Armin Ronacher577ad382008-04-16 15:36:49 +0200109 try:
110 len(value)
111 value.__getitem__
112 except:
113 return False
114 return True
Armin Ronacher58875382007-02-27 19:40:14 +0100115
116
Armin Ronacher577ad382008-04-16 15:36:49 +0200117def test_sameas(value, other):
118 """Check if an object points to the same memory address than another
Armin Ronacher69ddc582007-06-24 12:37:13 +0200119 object:
120
121 .. sourcecode:: jinja
122
Armin Ronacherf59bac22008-04-20 13:11:43 +0200123 {% if foo.attribute is sameas false %}
Armin Ronacher69ddc582007-06-24 12:37:13 +0200124 the foo attribute really is the `False` singleton
125 {% endif %}
Armin Ronacher69ddc582007-06-24 12:37:13 +0200126 """
Armin Ronacher577ad382008-04-16 15:36:49 +0200127 return value is other
Armin Ronacher69ddc582007-06-24 12:37:13 +0200128
129
Armin Ronacher53042292008-04-26 18:30:19 +0200130def test_iterable(value):
131 """Check if it's possible to iterate over an object."""
132 try:
133 iter(value)
134 except TypeError:
135 return False
136 return True
137
138
Armin Ronacher3c8b7ad2008-04-28 13:52:21 +0200139def test_escaped(value):
140 """Check if the value is escaped."""
141 return hasattr(value, '__html__')
142
143
Armin Ronacher58875382007-02-27 19:40:14 +0100144TESTS = {
145 'odd': test_odd,
146 'even': test_even,
Armin Ronacherf59bac22008-04-20 13:11:43 +0200147 'divisibleby': test_divisibleby,
Armin Ronacher58875382007-02-27 19:40:14 +0100148 'defined': test_defined,
Armin Ronacher53042292008-04-26 18:30:19 +0200149 'undefined': test_undefined,
150 'none': test_none,
Armin Ronacher58875382007-02-27 19:40:14 +0100151 'lower': test_lower,
152 'upper': test_upper,
Armin Ronacher53042292008-04-26 18:30:19 +0200153 'string': test_string,
Armin Ronacheree352ec2011-05-24 16:40:23 +0200154 'mapping': test_mapping,
Armin Ronacher53042292008-04-26 18:30:19 +0200155 'number': test_number,
Armin Ronacher58875382007-02-27 19:40:14 +0100156 'sequence': test_sequence,
Armin Ronacher53042292008-04-26 18:30:19 +0200157 'iterable': test_iterable,
Armin Ronacher42a19882009-08-05 18:45:39 +0200158 'callable': test_callable,
Armin Ronacher3c8b7ad2008-04-28 13:52:21 +0200159 'sameas': test_sameas,
160 'escaped': test_escaped
Armin Ronacher58875382007-02-27 19:40:14 +0100161}