1# -*- coding: utf-8 -*- 2""" 3 jinja2.tests 4 ~~~~~~~~~~~~ 5 6 Jinja test functions. Used with the "is" operator. 7 8 :copyright: (c) 2017 by the Jinja Team. 9 :license: BSD, see LICENSE for more details. 10""" 11import re 12from collections import Mapping 13from jinja2.runtime import Undefined 14from jinja2._compat import text_type, string_types, integer_types 15import decimal 16 17number_re = re.compile(r'^-?\d+(\.\d+)?$') 18regex_type = type(number_re) 19 20 21test_callable = callable 22 23 24def test_odd(value): 25 """Return true if the variable is odd.""" 26 return value % 2 == 1 27 28 29def test_even(value): 30 """Return true if the variable is even.""" 31 return value % 2 == 0 32 33 34def test_divisibleby(value, num): 35 """Check if a variable is divisible by a number.""" 36 return value % num == 0 37 38 39def test_defined(value): 40 """Return true if the variable is defined: 41 42 .. sourcecode:: jinja 43 44 {% if variable is defined %} 45 value of variable: {{ variable }} 46 {% else %} 47 variable is not defined 48 {% endif %} 49 50 See the :func:`default` filter for a simple way to set undefined 51 variables. 52 """ 53 return not isinstance(value, Undefined) 54 55 56def test_undefined(value): 57 """Like :func:`defined` but the other way round.""" 58 return isinstance(value, Undefined) 59 60 61def test_none(value): 62 """Return true if the variable is none.""" 63 return value is None 64 65 66def test_lower(value): 67 """Return true if the variable is lowercased.""" 68 return text_type(value).islower() 69 70 71def test_upper(value): 72 """Return true if the variable is uppercased.""" 73 return text_type(value).isupper() 74 75 76def test_string(value): 77 """Return true if the object is a string.""" 78 return isinstance(value, string_types) 79 80 81def test_mapping(value): 82 """Return true if the object is a mapping (dict etc.). 83 84 .. versionadded:: 2.6 85 """ 86 return isinstance(value, Mapping) 87 88 89def test_number(value): 90 """Return true if the variable is a number.""" 91 return isinstance(value, integer_types + (float, complex, decimal.Decimal)) 92 93 94def test_sequence(value): 95 """Return true if the variable is a sequence. Sequences are variables 96 that are iterable. 97 """ 98 try: 99 len(value) 100 value.__getitem__ 101 except: 102 return False 103 return True 104 105 106def test_equalto(value, other): 107 """Check if an object has the same value as another object: 108 109 .. sourcecode:: jinja 110 111 {% if foo.expression is equalto 42 %} 112 the foo attribute evaluates to the constant 42 113 {% endif %} 114 115 This appears to be a useless test as it does exactly the same as the 116 ``==`` operator, but it can be useful when used together with the 117 `selectattr` function: 118 119 .. sourcecode:: jinja 120 121 {{ users|selectattr("email", "equalto", "foo@bar.invalid") }} 122 123 .. versionadded:: 2.8 124 """ 125 return value == other 126 127 128def test_sameas(value, other): 129 """Check if an object points to the same memory address than another 130 object: 131 132 .. sourcecode:: jinja 133 134 {% if foo.attribute is sameas false %} 135 the foo attribute really is the `False` singleton 136 {% endif %} 137 """ 138 return value is other 139 140 141def test_iterable(value): 142 """Check if it's possible to iterate over an object.""" 143 try: 144 iter(value) 145 except TypeError: 146 return False 147 return True 148 149 150def test_escaped(value): 151 """Check if the value is escaped.""" 152 return hasattr(value, '__html__') 153 154 155def test_greaterthan(value, other): 156 """Check if value is greater than other.""" 157 return value > other 158 159 160def test_lessthan(value, other): 161 """Check if value is less than other.""" 162 return value < other 163 164 165TESTS = { 166 'odd': test_odd, 167 'even': test_even, 168 'divisibleby': test_divisibleby, 169 'defined': test_defined, 170 'undefined': test_undefined, 171 'none': test_none, 172 'lower': test_lower, 173 'upper': test_upper, 174 'string': test_string, 175 'mapping': test_mapping, 176 'number': test_number, 177 'sequence': test_sequence, 178 'iterable': test_iterable, 179 'callable': test_callable, 180 'sameas': test_sameas, 181 'equalto': test_equalto, 182 'escaped': test_escaped, 183 'greaterthan': test_greaterthan, 184 'lessthan': test_lessthan 185} 186