diff --git a/.travis.yml b/.travis.yml
index 1c90cea60547bf8e2f375e7a7f0d43acc3c97764..34c476c17af9bcc10a789ea221120cd8159feaeb 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,10 @@ sudo: false
 cache:
   - pip
 matrix:
-  allow_failure:
+  include:
+    - python: "3.5"
+      env: TOXENV=docs
+  allow_failures:
     - python: "3.2"
 
 install:
diff --git a/README.rst b/README.rst
index 53af308f5b1084483f358efccb7819b700fade56..1447ebb40278758bb8fe919e1d818c0582cd1b7c 100644
--- a/README.rst
+++ b/README.rst
@@ -47,8 +47,11 @@ The following Jinja filters were added:
 - :code:`combine`: Combine 2 dictionaries.
 - :code:`to_toml`: Convert to toml.
 - :code:`from_toml`: Convert from toml.
+- :code:`jmespath`: Queries data using the `JMESPath <http://jmespath.org/>`_
+  query language.
 
-Example usage can be seen in :code:`tests.sh`.
+Example usage can be seen in :code:`tests.sh` and for specific filters in the
+docstrings in :code:`template/filters.py`.
 
 Testing
 -------
@@ -81,11 +84,8 @@ at: https://www.shore.co.il/git/.
 TODO
 ----
 
-- Add unit tests of filters using doctest.
-- Fix combining dictionaries test.
-- Fix Travis CI test on Python 3.2 (https://travis-ci.org/adarnimrod/template/jobs/187388235).
+- Fix test failure on Python 3.2
+  (https://travis-ci.org/adarnimrod/template/jobs/194581463).
 - Release on tagged commits to PyPI in Travis CI
   (https://docs.travis-ci.com/user/deployment/pypi/ and
   https://docs.travis-ci.com/user/encryption-keys/).
-- Add JMESPath support.
-- Add TOML support?
diff --git a/setup.py b/setup.py
index de9bd4e97030c70463a97c7ee37bd6651fb01de1..c39c646fa2d92a1bce7447e1ebd125c152a53a78 100644
--- a/setup.py
+++ b/setup.py
@@ -21,7 +21,7 @@ setup(
     ],
     keywords='config configuration jinja template environment',
     packages=find_packages(),
-    install_requires=['Jinja2', 'PyYAML', 'toml'],
+    install_requires=['Jinja2', 'PyYAML', 'jmespath', 'toml'],
     extras_require={
         'dev': ['tox'], },
     entry_points={
diff --git a/template/filters.py b/template/filters.py
index bac6b5b5162ebdf61f096b78f6efe2f796d88027..c2b99563f6ddd5d5f3755cc567ce97691051fcba 100644
--- a/template/filters.py
+++ b/template/filters.py
@@ -1,42 +1,149 @@
 #!/usr/bin/env python
+from __future__ import (absolute_import, division,
+                        print_function, unicode_literals)
 
 
 def to_yaml(value):
+    '''
+    Converts given data structure to YAML form.
+    Examples:
+
+    >>> to_yaml([1,2,3])
+    '[1, 2, 3]\\n'
+    >>> to_yaml({'a': 1, 'b': 2})
+    '{a: 1, b: 2}\\n'
+    >>> to_yaml({1: {'a': [1,2,3]}})
+    '1:\\n  a: [1, 2, 3]\\n'
+    >>> to_yaml("abc")
+    'abc\\n...\\n'
+    '''
     from yaml import safe_dump
     return safe_dump(value)
 
 
 def to_json(value):
+    '''
+    Converts given data structure to JSON form.
+    Examples:
+
+    >>> to_json([1,2,3])
+    '[1, 2, 3]'
+    >>> to_json({'b':2})
+    '{"b": 2}'
+    >>> to_json(2)
+    '2'
+    >>> to_json({1: {'a': [1,2,3]}})
+    '{"1": {"a": [1, 2, 3]}}'
+    '''
     from json import dumps
     return dumps(value)
 
 
 def from_json(value):
+    '''
+    Returns native data structure from the given JSON string.
+    Examples:
+
+    >>> import six
+    >>> from_json('[1, 2, 3]')
+    [1, 2, 3]
+    >>> from_json('"a"') == six.text_type('a')
+    True
+    >>> from_json('{"1": {"a": [1, 2, 3]}}') == {'1': {'a': [1, 2, 3]}}
+    True
+    '''
     from json import loads
     return loads(value)
 
 
 def from_yaml(value):
+    '''
+    Returns native data structure from the given YAML string.
+    Examples:
+
+    >>> from_yaml('a')
+    'a'
+    >>> from_yaml('[1, 2, 3]')
+    [1, 2, 3]
+    >>> from_yaml('{"1": {"a": [1, 2, 3]}}')
+    {'1': {'a': [1, 2, 3]}}
+    '''
     from yaml import safe_load
     return safe_load(value)
 
 
 def pprint(value):
+    '''
+    Returns a pretty string representation of the data structure given.
+    Examples:
+    >>> pprint(1)
+    '1'
+    >>> import six
+    >>> output = pprint([{'first_name': 'John', 'last_name': 'Doe'}, {'first_name': 'Jane', 'last_name': 'Doe'}])  # noqa: E501
+    >>> if six.PY3:
+    ...  output == "[{'first_name': 'John', 'last_name': 'Doe'},\\n {'first_name': 'Jane', 'last_name': 'Doe'}]"
+    ... elif six.PY2:
+    ...  output == "[{u'first_name': u'John', u'last_name': u'Doe'},\\n {u'first_name': u'Jane', u'last_name': u'Doe'}]"
+    ...
+    True
+    '''
     from pprint import pformat
     return pformat(value)
 
 
 def combine(default, override):
+    '''
+    Returns a combined dictionary of the 2 dictionaries given (with the 2nd
+    overriding the 1st).
+    Examples:
+    >>> combine({'a': 1, 'b': 2}, {'b': 3, 'c': 4}) == {'a': 1, 'b': 3, 'c': 4}
+    True
+    '''
     combined = default.copy()
     combined.update(override)
     return combined
 
 
 def from_toml(value):
+    '''
+    Returns a data structure from the TOML string given.
+    Examples:
+    >>> from_toml('[table]\\nkey = "value"\\n') == {'table': {'key': 'value'}}
+    True
+    '''
     from toml import loads
     return loads(value)
 
 
 def to_toml(value):
+    '''
+    Returns a string of the TOML representation for the data structure given.
+    Examples:
+    >>> import six
+    >>> to_toml({'key': [1, 2]}) == six.text_type("key = [ 1, 2,]\\n")
+    True
+    '''
     from toml import dumps
     return dumps(value)
+
+
+def jmespath(value, query):
+    '''
+    Queries the data using the JMESPath query language.
+    Examples:
+    >>> import six
+    >>> locations = [{'name': 'Seattle', 'state': 'WA'},
+    ... {"name": "New York", "state": "NY"},
+    ... {"name": "Bellevue", "state": "WA"},
+    ... {"name": "Olympia", "state": "WA"}]
+    >>> query = "[?state == 'WA'].name | sort(@) | {WashingtonCities: join(', ', @)}"  # noqa: E501
+    >>> WACities = jmespath(locations, query)
+    >>> if six.PY2:
+    ...  WACities == {u'WashingtonCities': u'Bellevue, Olympia, Seattle'}
+    ... elif six.PY3:
+    ...  WACities == {'WashingtonCities': 'Bellevue, Olympia, Seattle'}
+    ...
+    True
+    '''
+    import jmespath
+    return jmespath.search(query, value)
diff --git a/tests.sh b/tests.sh
index a2797ea2b433296cee19de948f4687b5a47401ff..d329d33f939fd7cfe4975a21a033357c9b3c433b 100755
--- a/tests.sh
+++ b/tests.sh
@@ -14,39 +14,4 @@ export name='John'
 template --output "$outfile" "$infile"
 test "$(cat $outfile)" = "$name"
 
-echo Testing JSON parsing.
-export json='{"a": 1, "b": 2}'
-echo '{{ (json|from_json)["a"] }}' > "$infile"
-test "$(template $infile)" = "1"
-
-echo Testing JSON output.
-echo '{{ [1, 1+2, 3] | to_json }}' > "$infile"
-test "$(template $infile)" = '[1, 3, 3]'
-
-echo Testing YAML parsing.
-export yaml='a: 1
-b: 2'
-echo '{{ (yaml|from_yaml)["a"] }}' > "$infile"
-test "$(template $infile)" = "1"
-
-echo Testing YAML output.
-echo '{{ [1, 1+2, 3] | to_yaml }}' > "$infile"
-test "$(template $infile)" = '[1, 3, 3]'
-
-echo Testing pprint.
-echo '{{ [1, ] + [2, ] }}' > "$infile"
-test "$(template $infile)" = "[1, 2]"
-
-# echo Testing combining dictionaries.
-# echo '{{ {"a": 1, "b": 2}|combine({"a": 11, "c": 33}) }}' > "$infile"
-# test "$(template $infile)" = "{'a': 11, 'c': 33, 'b': 2}"
-
-echo Testing TOML parsing.
-echo '{{ "[table]\n key = value" | from_toml }}' > "$infile"
-test "$(template $infile)" = "table = {'key': 'value'}"
-
-echo Testing TOML output.
-echo "{{ {'key': [1, 2]} | to_toml }}" > "$infile"
-test "$(template $infile)" = "key = [ 1, 2,]"
-
 rm "$infile" "$outfile"
diff --git a/tox.ini b/tox.ini
index 719a30a718fdc97aa0bcfb6d9ec7e9bfb9820fa7..772e7c959ff9ff451888b69dcb978d573d9a8b95 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
 [tox]
-envlist = py{2,3}
+envlist = py{2,3},docs
 
 [travis]
 python =
@@ -17,12 +17,18 @@ deps =
     check-manifest
     readme_renderer
     flake8
+    six
 commands =
     check-manifest --ignore tox.ini,tests*
-    python setup.py check -m -r -s
     flake8 .
+    python -m doctest template/filters.py template/__init__.py
     ./tests.sh
 
+[testenv:docs]
+basepython = python
+deps = readme_renderer
+commands = python setup.py check -m -r -s
+
 [testenv:release]
 basepython = python
 whitelist_externals =