Skip to content

Commit

Permalink
Add more strict type tests
Browse files Browse the repository at this point in the history
This PR adds a few more type-related tests.

- boolean
    Testing of an object is a boolean required 2 tests.

- false
    Make this similar to testing none value

- true
    Make this similar to testing none value

- integer
    The existing 'number' test does not make a distinction between
    integer, float or even booleans

- float
    The existing 'number' test does not make a distinction between
    integer, float or even booleans

- list
    The existing 'sequence' test does not make a distinction between
    strings, lists or mappings. Even 'iterable' does not.

PS Also includes a small doc workaround to fix Travis.
  • Loading branch information
dagwieers committed Mar 17, 2018
1 parent 3d7cfc8 commit ba18cdb
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
2 changes: 1 addition & 1 deletion docs/templates.rst
Expand Up @@ -1311,7 +1311,7 @@ something else>``.
The `else` part is optional. If not provided, the else block implicitly
evaluates into an undefined object::

{{ ('[%s]' % page.title) if page.title }}
{{ ('[' ~ page.title ~ ']') if page.title }}


.. _builtin-filters:
Expand Down
59 changes: 58 additions & 1 deletion jinja2/tests.py
Expand Up @@ -10,7 +10,7 @@
"""
import operator
import re
from collections import Mapping
from collections import Mapping, Sequence
from jinja2.runtime import Undefined
from jinja2._compat import text_type, string_types, integer_types
import decimal
Expand Down Expand Up @@ -64,6 +64,48 @@ def test_none(value):
return value is None


def test_boolean(value):
"""Return true if the object is a boolean value.
.. versionadded:: 2.11
"""
return value is True or value is False


def test_false(value):
"""Return true if the object is False.
.. versionadded:: 2.11
"""
return value is False


def test_true(value):
"""Return true if the object is True.
.. versionadded:: 2.11
"""
return value is True


# NOTE: The existing Jinja2 'number' test matches booleans and floats
def test_integer(value):
"""Return true if the object is an integer.
.. versionadded:: 2.11
"""
return isinstance(value, integer_types) and value is not True and value is not False


# NOTE: The existing Jinja2 'number' test matches booleans and integers
def test_float(value):
"""Return true if the object is a float.
.. versionadded:: 2.11
"""
return isinstance(value, float)


def test_lower(value):
"""Return true if the variable is lowercased."""
return text_type(value).islower()
Expand All @@ -79,6 +121,15 @@ def test_string(value):
return isinstance(value, string_types)


# NOTE: The existing Jinja2 'sequence' test matches strings and dictionaries
def test_list(value):
"""Return true if the object is a list or tuple.
.. versionadded:: 2.11
"""
return isinstance(value, Sequence) and not isinstance(value, string_types)


def test_mapping(value):
"""Return true if the object is a mapping (dict etc.).
Expand Down Expand Up @@ -146,9 +197,15 @@ def test_in(value, seq):
'defined': test_defined,
'undefined': test_undefined,
'none': test_none,
'boolean': test_boolean,
'false': test_false,
'true': test_true,
'integer': test_integer,
'float': test_float,
'lower': test_lower,
'upper': test_upper,
'string': test_string,
'list': test_list,
'mapping': test_mapping,
'number': test_number,
'sequence': test_sequence,
Expand Down
35 changes: 35 additions & 0 deletions tests/test_tests.py
Expand Up @@ -41,6 +41,18 @@ def test_typechecks(self, env):
{{ none is none }}
{{ 42 is number }}
{{ 42 is string }}
{{ 42 is integer }}
{{ 42 is float }}
{{ 4.2 is integer }}
{{ 4.2 is float }}
{{ 0 is false }}
{{ 1 is true }}
{{ false is false }}
{{ true is true }}
{{ "foo" is list }}
{{ [1] is list }}
{{ {} is list }}
{{ {} is sequence }}
{{ "foo" is string }}
{{ "foo" is sequence }}
{{ [1] is sequence }}
Expand All @@ -61,10 +73,25 @@ class MyDict(dict):

assert tmpl.render(mydict=MyDict(), complex=complex(1, 2)).split() == [
'False', 'True', 'False', 'True', 'True', 'False',
'True', 'False', 'False', 'True', 'False', 'False',
'True', 'True', 'False', 'True', 'False', 'True',
'True', 'True', 'True', 'True', 'False', 'True',
'True', 'True', 'False', 'True', 'True', 'True', 'True'
]

def test_booleans(self, env):
tmpl = env.from_string(
'{{ 0 is false }}|'
'{{ 1 is true }}|'
'{{ 0 is boolean }}|'
'{{ 1 is boolean }}|'
'{{ 0.0 is boolean }}|'
'{{ 1.0 is boolean }}|'
'{{ false is boolean }}|'
'{{ true is boolean }}'
)
assert tmpl.render() == 'False|False|False|False|False|False|True|True'

def test_sequence(self, env):
tmpl = env.from_string(
'{{ [1, 2, 3] is sequence }}|'
Expand All @@ -73,6 +100,14 @@ def test_sequence(self, env):
)
assert tmpl.render() == 'True|True|False'

def test_list(self, env):
tmpl = env.from_string(
'{{ [1, 2, 3] is list }}|'
'{{ "foo" is list }}|'
'{{ 42 is list }}'
)
assert tmpl.render() == 'True|False|False'

def test_upper(self, env):
tmpl = env.from_string('{{ "FOO" is upper }}|{{ "foo" is upper }}')
assert tmpl.render() == 'True|False'
Expand Down

0 comments on commit ba18cdb

Please sign in to comment.