tests.py 4.7 KB

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