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 13try: 14 from collections.abc import Mapping 15except ImportError: 16 from collections import Mapping 17from jinja2.runtime import Undefined 18from jinja2._compat import text_type, string_types, integer_types 19import decimal 20 21number_re = re.compile(r'^-?\d+(\.\d+)?$') 22regex_type = type(number_re) 23 24 25test_callable = callable 26 27 28def test_odd(value): 29 """Return true if the variable is odd.""" 30 return value % 2 == 1 31 32 33def test_even(value): 34 """Return true if the variable is even.""" 35 return value % 2 == 0 36 37 38def test_divisibleby(value, num): 39 """Check if a variable is divisible by a number.""" 40 return value % num == 0 41 42 43def test_defined(value): 44 """Return true if the variable is defined: 45 46 .. sourcecode:: jinja 47 48 {% if variable is defined %} 49 value of variable: {{ variable }} 50 {% else %} 51 variable is not defined 52 {% endif %} 53 54 See the :func:`default` filter for a simple way to set undefined 55 variables. 56 """ 57 return not isinstance(value, Undefined) 58 59 60def test_undefined(value): 61 """Like :func:`defined` but the other way round.""" 62 return isinstance(value, Undefined) 63 64 65def test_none(value): 66 """Return true if the variable is none.""" 67 return value is None 68 69 70def test_lower(value): 71 """Return true if the variable is lowercased.""" 72 return text_type(value).islower() 73 74 75def test_upper(value): 76 """Return true if the variable is uppercased.""" 77 return text_type(value).isupper() 78 79 80def test_string(value): 81 """Return true if the object is a string.""" 82 return isinstance(value, string_types) 83 84 85def test_mapping(value): 86 """Return true if the object is a mapping (dict etc.). 87 88 .. versionadded:: 2.6 89 """ 90 return isinstance(value, Mapping) 91 92 93def test_number(value): 94 """Return true if the variable is a number.""" 95 return isinstance(value, integer_types + (float, complex, decimal.Decimal)) 96 97 98def test_sequence(value): 99 """Return true if the variable is a sequence. Sequences are variables 100 that are iterable. 101 """ 102 try: 103 len(value) 104 value.__getitem__ 105 except: 106 return False 107 return True 108 109 110def test_sameas(value, other): 111 """Check if an object points to the same memory address than another 112 object: 113 114 .. sourcecode:: jinja 115 116 {% if foo.attribute is sameas false %} 117 the foo attribute really is the `False` singleton 118 {% endif %} 119 """ 120 return value is other 121 122 123def test_iterable(value): 124 """Check if it's possible to iterate over an object.""" 125 try: 126 iter(value) 127 except TypeError: 128 return False 129 return True 130 131 132def test_escaped(value): 133 """Check if the value is escaped.""" 134 return hasattr(value, '__html__') 135 136 137def test_in(value, seq): 138 """Check if value is in seq. 139 140 .. versionadded:: 2.10 141 """ 142 return value in seq 143 144 145TESTS = { 146 'odd': test_odd, 147 'even': test_even, 148 'divisibleby': test_divisibleby, 149 'defined': test_defined, 150 'undefined': test_undefined, 151 'none': test_none, 152 'lower': test_lower, 153 'upper': test_upper, 154 'string': test_string, 155 'mapping': test_mapping, 156 'number': test_number, 157 'sequence': test_sequence, 158 'iterable': test_iterable, 159 'callable': test_callable, 160 'sameas': test_sameas, 161 'escaped': test_escaped, 162 'in': test_in, 163 '==': operator.eq, 164 'eq': operator.eq, 165 'equalto': operator.eq, 166 '!=': operator.ne, 167 'ne': operator.ne, 168 '>': operator.gt, 169 'gt': operator.gt, 170 'greaterthan': operator.gt, 171 'ge': operator.ge, 172 '>=': operator.ge, 173 '<': operator.lt, 174 'lt': operator.lt, 175 'lessthan': operator.lt, 176 '<=': operator.le, 177 'le': operator.le, 178} 179