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 operator 12import re 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_number(value): 82 """Return true if the variable is a number.""" 83 return isinstance(value, integer_types + (float, complex, decimal.Decimal)) 84 85 86def test_sequence(value): 87 """Return true if the variable is a sequence. Sequences are variables 88 that are iterable. 89 """ 90 try: 91 len(value) 92 value.__getitem__ 93 except: 94 return False 95 return True 96 97 98def test_sameas(value, other): 99 """Check if an object points to the same memory address than another 100 object: 101 102 .. sourcecode:: jinja 103 104 {% if foo.attribute is sameas false %} 105 the foo attribute really is the `False` singleton 106 {% endif %} 107 """ 108 return value is other 109 110 111def test_iterable(value): 112 """Check if it's possible to iterate over an object.""" 113 try: 114 iter(value) 115 except TypeError: 116 return False 117 return True 118 119 120def test_escaped(value): 121 """Check if the value is escaped.""" 122 return hasattr(value, '__html__') 123 124 125def test_in(value, seq): 126 """Check if value is in seq. 127 128 .. versionadded:: 2.10 129 """ 130 return value in seq 131 132 133TESTS = { 134 'odd': test_odd, 135 'even': test_even, 136 'divisibleby': test_divisibleby, 137 'defined': test_defined, 138 'undefined': test_undefined, 139 'none': test_none, 140 'lower': test_lower, 141 'upper': test_upper, 142 'string': test_string, 143 'number': test_number, 144 'sequence': test_sequence, 145 'iterable': test_iterable, 146 'callable': test_callable, 147 'sameas': test_sameas, 148 'escaped': test_escaped, 149 'in': test_in, 150 '==': operator.eq, 151 'eq': operator.eq, 152 'equalto': operator.eq, 153 '!=': operator.ne, 154 'ne': operator.ne, 155 '>': operator.gt, 156 'gt': operator.gt, 157 'greaterthan': operator.gt, 158 'ge': operator.ge, 159 '>=': operator.ge, 160 '<': operator.lt, 161 'lt': operator.lt, 162 'lessthan': operator.lt, 163 '<=': operator.le, 164 'le': operator.le, 165} 166