1# -*- coding: utf-8 -*-
2"""
3    jinja2.tests
4    ~~~~~~~~~~~~
5
6    Jinja test functions. Used with the "is" operator.
7
8    :copyright: (c) 2010 by the Jinja Team.
9    :license: BSD, see LICENSE for more details.
10"""
11import re
12from jinja2.runtime import Undefined
13
14# nose, nothing here to test
15__test__ = False
16
17
18number_re = re.compile(r'^-?\d+(\.\d+)?$')
19regex_type = type(number_re)
20
21
22try:
23    test_callable = callable
24except NameError:
25    def test_callable(x):
26        return hasattr(x, '__call__')
27
28
29def test_odd(value):
30    """Return true if the variable is odd."""
31    return value % 2 == 1
32
33
34def test_even(value):
35    """Return true if the variable is even."""
36    return value % 2 == 0
37
38
39def test_divisibleby(value, num):
40    """Check if a variable is divisible by a number."""
41    return value % num == 0
42
43
44def test_defined(value):
45    """Return true if the variable is defined:
46
47    .. sourcecode:: jinja
48
49        {% if variable is defined %}
50            value of variable: {{ variable }}
51        {% else %}
52            variable is not defined
53        {% endif %}
54
55    See the :func:`default` filter for a simple way to set undefined
56    variables.
57    """
58    return not isinstance(value, Undefined)
59
60
61def test_undefined(value):
62    """Like :func:`defined` but the other way round."""
63    return isinstance(value, Undefined)
64
65
66def test_none(value):
67    """Return true if the variable is none."""
68    return value is None
69
70
71def test_lower(value):
72    """Return true if the variable is lowercased."""
73    return unicode(value).islower()
74
75
76def test_upper(value):
77    """Return true if the variable is uppercased."""
78    return unicode(value).isupper()
79
80
81def test_string(value):
82    """Return true if the object is a string."""
83    return isinstance(value, basestring)
84
85
86def test_number(value):
87    """Return true if the variable is a number."""
88    return isinstance(value, (int, long, float, complex))
89
90
91def test_sequence(value):
92    """Return true if the variable is a sequence. Sequences are variables
93    that are iterable.
94    """
95    try:
96        len(value)
97        value.__getitem__
98    except:
99        return False
100    return True
101
102
103def test_sameas(value, other):
104    """Check if an object points to the same memory address than another
105    object:
106
107    .. sourcecode:: jinja
108
109        {% if foo.attribute is sameas false %}
110            the foo attribute really is the `False` singleton
111        {% endif %}
112    """
113    return value is other
114
115
116def test_iterable(value):
117    """Check if it's possible to iterate over an object."""
118    try:
119        iter(value)
120    except TypeError:
121        return False
122    return True
123
124
125def test_escaped(value):
126    """Check if the value is escaped."""
127    return hasattr(value, '__html__')
128
129
130TESTS = {
131    'odd':              test_odd,
132    'even':             test_even,
133    'divisibleby':      test_divisibleby,
134    'defined':          test_defined,
135    'undefined':        test_undefined,
136    'none':             test_none,
137    'lower':            test_lower,
138    'upper':            test_upper,
139    'string':           test_string,
140    'number':           test_number,
141    'sequence':         test_sequence,
142    'iterable':         test_iterable,
143    'callable':         test_callable,
144    'sameas':           test_sameas,
145    'escaped':          test_escaped
146}
147