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