From f91d7366e066dc5e1edd90c6bde438fae9fe67fb Mon Sep 17 00:00:00 2001
From: Preston Timmons <prestontimmons@gmail.com>
Date: Mon, 15 Dec 2014 08:33:33 -0600
Subject: [PATCH] Fixed #16028 -- Moved defaultfilters tests into
 template_tests.

---
 tests/defaultfilters/__init__.py              |   0
 tests/defaultfilters/tests.py                 | 754 ------------------
 tests/template_tests/filter_tests/test_add.py |   7 +
 .../filter_tests/test_addslashes.py           |  16 +
 .../filter_tests/test_capfirst.py             |   7 +
 .../filter_tests/test_center.py               |  10 +
 tests/template_tests/filter_tests/test_cut.py |  16 +
 .../template_tests/filter_tests/test_date.py  |  11 +
 .../filter_tests/test_default.py              |  13 +
 .../filter_tests/test_default_if_none.py      |  14 +
 .../filter_tests/test_dictsort.py             |  44 +
 .../filter_tests/test_dictsortreversed.py     |  30 +
 .../filter_tests/test_divisibleby.py          |  11 +
 .../filter_tests/test_escape.py               |   7 +
 .../filter_tests/test_escapejs.py             |  33 +
 .../filter_tests/test_filesizeformat.py       |  41 +
 .../template_tests/filter_tests/test_first.py |  13 +
 .../filter_tests/test_floatformat.py          |  91 +++
 .../filter_tests/test_force_escape.py         |  19 +
 .../filter_tests/test_get_digit.py            |  15 +
 .../filter_tests/test_iriencode.py            |  13 +
 .../template_tests/filter_tests/test_join.py  |   7 +
 .../filter_tests/test_length.py               |  13 +
 .../filter_tests/test_length_is.py            |  12 +
 .../filter_tests/test_linebreaks.py           |  19 +
 .../filter_tests/test_linebreaksbr.py         |  16 +
 .../filter_tests/test_linenumbers.py          |  16 +
 .../template_tests/filter_tests/test_ljust.py |  14 +
 .../template_tests/filter_tests/test_lower.py |  17 +
 .../filter_tests/test_make_list.py            |  10 +
 .../filter_tests/test_phone2numeric.py        |   7 +
 .../filter_tests/test_pluralize.py            |  35 +
 .../filter_tests/test_removetags.py           |  20 +
 .../template_tests/filter_tests/test_rjust.py |  13 +
 .../template_tests/filter_tests/test_slice.py |  22 +
 .../filter_tests/test_slugify.py              |  22 +
 .../filter_tests/test_stringformat.py         |  10 +
 .../filter_tests/test_striptags.py            |  13 +
 .../template_tests/filter_tests/test_time.py  |   9 +
 .../filter_tests/test_timesince.py            |  11 +
 .../filter_tests/test_timeuntil.py            |  11 +
 .../template_tests/filter_tests/test_title.py |  16 +
 .../filter_tests/test_truncatechars_html.py   |  35 +
 .../filter_tests/test_truncatewords.py        |  28 +
 .../filter_tests/test_truncatewords_html.py   |  44 +
 .../filter_tests/test_unordered_list.py       |  82 ++
 .../template_tests/filter_tests/test_upper.py |  17 +
 .../filter_tests/test_urlencode.py            |  13 +
 .../filter_tests/test_urlize.py               | 240 ++++++
 .../filter_tests/test_urlizetrunc.py          |  42 +
 .../filter_tests/test_wordcount.py            |  16 +
 .../filter_tests/test_wordwrap.py             |  25 +
 .../template_tests/filter_tests/test_yesno.py |  26 +
 53 files changed, 1292 insertions(+), 754 deletions(-)
 delete mode 100644 tests/defaultfilters/__init__.py
 delete mode 100644 tests/defaultfilters/tests.py
 create mode 100644 tests/template_tests/filter_tests/test_default_if_none.py
 create mode 100644 tests/template_tests/filter_tests/test_dictsort.py
 create mode 100644 tests/template_tests/filter_tests/test_dictsortreversed.py
 create mode 100644 tests/template_tests/filter_tests/test_divisibleby.py
 create mode 100644 tests/template_tests/filter_tests/test_filesizeformat.py
 create mode 100644 tests/template_tests/filter_tests/test_get_digit.py
 create mode 100644 tests/template_tests/filter_tests/test_pluralize.py
 create mode 100644 tests/template_tests/filter_tests/test_truncatechars_html.py
 create mode 100644 tests/template_tests/filter_tests/test_truncatewords_html.py
 create mode 100644 tests/template_tests/filter_tests/test_yesno.py

diff --git a/tests/defaultfilters/__init__.py b/tests/defaultfilters/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/tests/defaultfilters/tests.py b/tests/defaultfilters/tests.py
deleted file mode 100644
index bf80ccb313..0000000000
--- a/tests/defaultfilters/tests.py
+++ /dev/null
@@ -1,754 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-import datetime
-import decimal
-import unittest
-import warnings
-
-from django.template.defaultfilters import (
-    add, addslashes, capfirst, center, cut, date, default, default_if_none,
-    dictsort, dictsortreversed, divisibleby, escape, escapejs_filter,
-    filesizeformat, first, floatformat, force_escape,
-    get_digit, iriencode, join, length, length_is, linebreaksbr,
-    linebreaks_filter, linenumbers, ljust, lower, make_list,
-    phone2numeric_filter, pluralize, removetags, rjust, slice_filter, slugify,
-    stringformat, striptags, time, timesince_filter, timeuntil_filter, title,
-    truncatechars_html, truncatewords, truncatewords_html, unordered_list,
-    upper, urlencode, urlize, urlizetrunc, wordcount, wordwrap, yesno,
-)
-from django.test import TestCase
-from django.utils import six
-from django.utils import translation
-from django.utils.encoding import python_2_unicode_compatible
-from django.utils.safestring import mark_safe, SafeData
-
-
-class DefaultFiltersTests(TestCase):
-
-    def test_floatformat(self):
-        self.assertEqual(floatformat(7.7), '7.7')
-        self.assertEqual(floatformat(7.0), '7')
-        self.assertEqual(floatformat(0.7), '0.7')
-        self.assertEqual(floatformat(0.07), '0.1')
-        self.assertEqual(floatformat(0.007), '0.0')
-        self.assertEqual(floatformat(0.0), '0')
-        self.assertEqual(floatformat(7.7, 3), '7.700')
-        self.assertEqual(floatformat(6.000000, 3), '6.000')
-        self.assertEqual(floatformat(6.200000, 3), '6.200')
-        self.assertEqual(floatformat(6.200000, -3), '6.200')
-        self.assertEqual(floatformat(13.1031, -3), '13.103')
-        self.assertEqual(floatformat(11.1197, -2), '11.12')
-        self.assertEqual(floatformat(11.0000, -2), '11')
-        self.assertEqual(floatformat(11.000001, -2), '11.00')
-        self.assertEqual(floatformat(8.2798, 3), '8.280')
-        self.assertEqual(floatformat(5555.555, 2), '5555.56')
-        self.assertEqual(floatformat(001.3000, 2), '1.30')
-        self.assertEqual(floatformat(0.12345, 2), '0.12')
-        self.assertEqual(floatformat(decimal.Decimal('555.555'), 2), '555.56')
-        self.assertEqual(floatformat(decimal.Decimal('09.000')), '9')
-        self.assertEqual(floatformat('foo'), '')
-        self.assertEqual(floatformat(13.1031, 'bar'), '13.1031')
-        self.assertEqual(floatformat(18.125, 2), '18.13')
-        self.assertEqual(floatformat('foo', 'bar'), '')
-        self.assertEqual(floatformat('¿Cómo esta usted?'), '')
-        self.assertEqual(floatformat(None), '')
-
-        # Check that we're not converting to scientific notation.
-        self.assertEqual(floatformat(0, 6), '0.000000')
-        self.assertEqual(floatformat(0, 7), '0.0000000')
-        self.assertEqual(floatformat(0, 10), '0.0000000000')
-        self.assertEqual(floatformat(0.000000000000000000015, 20),
-                         '0.00000000000000000002')
-
-        pos_inf = float(1e30000)
-        self.assertEqual(floatformat(pos_inf), six.text_type(pos_inf))
-
-        neg_inf = float(-1e30000)
-        self.assertEqual(floatformat(neg_inf), six.text_type(neg_inf))
-
-        nan = pos_inf / pos_inf
-        self.assertEqual(floatformat(nan), six.text_type(nan))
-
-        class FloatWrapper(object):
-            def __init__(self, value):
-                self.value = value
-
-            def __float__(self):
-                return self.value
-
-        self.assertEqual(floatformat(FloatWrapper(11.000001), -2), '11.00')
-
-        # Regression for #15789
-        decimal_ctx = decimal.getcontext()
-        old_prec, decimal_ctx.prec = decimal_ctx.prec, 2
-        try:
-            self.assertEqual(floatformat(1.2345, 2), '1.23')
-            self.assertEqual(floatformat(15.2042, -3), '15.204')
-            self.assertEqual(floatformat(1.2345, '2'), '1.23')
-            self.assertEqual(floatformat(15.2042, '-3'), '15.204')
-            self.assertEqual(floatformat(decimal.Decimal('1.2345'), 2), '1.23')
-            self.assertEqual(floatformat(decimal.Decimal('15.2042'), -3), '15.204')
-        finally:
-            decimal_ctx.prec = old_prec
-
-    def test_floatformat_py2_fail(self):
-        self.assertEqual(floatformat(1.00000000000000015, 16), '1.0000000000000002')
-
-    # The test above fails because of Python 2's float handling. Floats with
-    # many zeroes after the decimal point should be passed in as another type
-    # such as unicode or Decimal.
-    if six.PY2:
-        test_floatformat_py2_fail = unittest.expectedFailure(test_floatformat_py2_fail)
-
-    def test_addslashes(self):
-        self.assertEqual(addslashes('"double quotes" and \'single quotes\''),
-                         '\\"double quotes\\" and \\\'single quotes\\\'')
-
-        self.assertEqual(addslashes(r'\ : backslashes, too'),
-                         '\\\\ : backslashes, too')
-
-    def test_capfirst(self):
-        self.assertEqual(capfirst('hello world'), 'Hello world')
-
-    def test_escapejs(self):
-        self.assertEqual(escapejs_filter('"double quotes" and \'single quotes\''),
-            '\\u0022double quotes\\u0022 and \\u0027single quotes\\u0027')
-        self.assertEqual(escapejs_filter(r'\ : backslashes, too'),
-            '\\u005C : backslashes, too')
-        self.assertEqual(escapejs_filter('and lots of whitespace: \r\n\t\v\f\b'),
-            'and lots of whitespace: \\u000D\\u000A\\u0009\\u000B\\u000C\\u0008')
-        self.assertEqual(escapejs_filter(r'<script>and this</script>'),
-            '\\u003Cscript\\u003Eand this\\u003C/script\\u003E')
-        self.assertEqual(
-            escapejs_filter('paragraph separator:\u2029and line separator:\u2028'),
-            'paragraph separator:\\u2029and line separator:\\u2028')
-
-    def test_linenumbers(self):
-        self.assertEqual(linenumbers('line 1\nline 2'),
-                         '1. line 1\n2. line 2')
-        self.assertEqual(linenumbers('\n'.join(['x'] * 10)),
-                         '01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. '
-                         'x\n08. x\n09. x\n10. x')
-
-    def test_lower(self):
-        self.assertEqual(lower('TEST'), 'test')
-
-        # uppercase E umlaut
-        self.assertEqual(lower('\xcb'), '\xeb')
-
-    def test_make_list(self):
-        self.assertEqual(make_list('abc'), ['a', 'b', 'c'])
-        self.assertEqual(make_list(1234), ['1', '2', '3', '4'])
-
-    def test_slugify(self):
-        self.assertEqual(slugify(' Jack & Jill like numbers 1,2,3 and 4 and'
-            ' silly characters ?%.$!/'),
-            'jack-jill-like-numbers-123-and-4-and-silly-characters')
-
-        self.assertEqual(slugify("Un \xe9l\xe9phant \xe0 l'or\xe9e du bois"),
-                         'un-elephant-a-loree-du-bois')
-
-    def test_stringformat(self):
-        self.assertEqual(stringformat(1, '03d'), '001')
-        self.assertEqual(stringformat(1, 'z'), '')
-
-    def test_title(self):
-        self.assertEqual(title('a nice title, isn\'t it?'),
-                         "A Nice Title, Isn't It?")
-        self.assertEqual(title('discoth\xe8que'), 'Discoth\xe8que')
-
-    def test_truncatewords(self):
-        self.assertEqual(
-            truncatewords('A sentence with a few words in it', 1), 'A ...')
-        self.assertEqual(
-            truncatewords('A sentence with a few words in it', 5),
-            'A sentence with a few ...')
-        self.assertEqual(
-            truncatewords('A sentence with a few words in it', 100),
-            'A sentence with a few words in it')
-        self.assertEqual(
-            truncatewords('A sentence with a few words in it',
-            'not a number'), 'A sentence with a few words in it')
-
-    def test_truncatewords_html(self):
-        self.assertEqual(truncatewords_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 0), '')
-        self.assertEqual(truncatewords_html('<p>one <a href="#">two - '
-            'three <br>four</a> five</p>', 2),
-            '<p>one <a href="#">two ...</a></p>')
-        self.assertEqual(truncatewords_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 4),
-            '<p>one <a href="#">two - three <br>four ...</a></p>')
-        self.assertEqual(truncatewords_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 5),
-            '<p>one <a href="#">two - three <br>four</a> five</p>')
-        self.assertEqual(truncatewords_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 100),
-            '<p>one <a href="#">two - three <br>four</a> five</p>')
-        self.assertEqual(truncatewords_html(
-            '\xc5ngstr\xf6m was here', 1), '\xc5ngstr\xf6m ...')
-        self.assertEqual(truncatewords_html('<i>Buenos d&iacute;as! '
-            '&#x00bf;C&oacute;mo est&aacute;?</i>', 3),
-            '<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo ...</i>')
-
-    def test_truncatechars_html(self):
-        self.assertEqual(truncatechars_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 0), '...')
-        self.assertEqual(truncatechars_html('<p>one <a href="#">two - '
-            'three <br>four</a> five</p>', 6),
-            '<p>one...</p>')
-        self.assertEqual(truncatechars_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 11),
-            '<p>one <a href="#">two ...</a></p>')
-        self.assertEqual(truncatechars_html(
-            '<p>one <a href="#">two - three <br>four</a> five</p>', 100),
-            '<p>one <a href="#">two - three <br>four</a> five</p>')
-        self.assertEqual(truncatechars_html(
-            '<b>\xc5ngstr\xf6m</b> was here', 5), '<b>\xc5n...</b>')
-        self.assertEqual(truncatechars_html(
-            'a<b>b</b>c', 3), 'a<b>b</b>c')
-
-    def test_upper(self):
-        self.assertEqual(upper('Mixed case input'), 'MIXED CASE INPUT')
-        # lowercase e umlaut
-        self.assertEqual(upper('\xeb'), '\xcb')
-
-    def test_urlencode(self):
-        self.assertEqual(urlencode('fran\xe7ois & jill'),
-                         'fran%C3%A7ois%20%26%20jill')
-        self.assertEqual(urlencode(1), '1')
-
-    def test_iriencode(self):
-        self.assertEqual(iriencode('S\xf8r-Tr\xf8ndelag'),
-                         'S%C3%B8r-Tr%C3%B8ndelag')
-        self.assertEqual(iriencode(urlencode('fran\xe7ois & jill')),
-                         'fran%C3%A7ois%20%26%20jill')
-
-    def test_urlizetrunc(self):
-        self.assertEqual(urlizetrunc('http://short.com/', 20), '<a href='
-            '"http://short.com/" rel="nofollow">http://short.com/</a>')
-
-        self.assertEqual(urlizetrunc('http://www.google.co.uk/search?hl=en'
-            '&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://'
-            'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&'
-            'meta=" rel="nofollow">http://www.google...</a>')
-
-        self.assertEqual(urlizetrunc('http://www.google.co.uk/search?hl=en'
-            '&q=some+long+url&btnG=Search&meta=', 20), '<a href="http://'
-            'www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search'
-            '&meta=" rel="nofollow">http://www.google...</a>')
-
-        # Check truncating of URIs which are the exact length
-        uri = 'http://31characteruri.com/test/'
-        self.assertEqual(len(uri), 31)
-
-        self.assertEqual(urlizetrunc(uri, 31),
-            '<a href="http://31characteruri.com/test/" rel="nofollow">'
-            'http://31characteruri.com/test/</a>')
-
-        self.assertEqual(urlizetrunc(uri, 30),
-            '<a href="http://31characteruri.com/test/" rel="nofollow">'
-            'http://31characteruri.com/t...</a>')
-
-        self.assertEqual(urlizetrunc(uri, 2),
-            '<a href="http://31characteruri.com/test/"'
-            ' rel="nofollow">...</a>')
-
-    def test_urlize(self):
-        # Check normal urlize
-        self.assertEqual(urlize('http://google.com'),
-            '<a href="http://google.com" rel="nofollow">http://google.com</a>')
-        self.assertEqual(urlize('http://google.com/'),
-            '<a href="http://google.com/" rel="nofollow">http://google.com/</a>')
-        self.assertEqual(urlize('www.google.com'),
-            '<a href="http://www.google.com" rel="nofollow">www.google.com</a>')
-        self.assertEqual(urlize('djangoproject.org'),
-            '<a href="http://djangoproject.org" rel="nofollow">djangoproject.org</a>')
-        self.assertEqual(urlize('djangoproject.org/'),
-            '<a href="http://djangoproject.org/" rel="nofollow">djangoproject.org/</a>')
-        self.assertEqual(urlize('info@djangoproject.org'),
-            '<a href="mailto:info@djangoproject.org">info@djangoproject.org</a>')
-        self.assertEqual(urlize('some.organization'),
-            'some.organization'),
-
-        # Check urlize with https addresses
-        self.assertEqual(urlize('https://google.com'),
-            '<a href="https://google.com" rel="nofollow">https://google.com</a>')
-
-        # Check urlize doesn't overquote already quoted urls - see #9655
-        # The teststring is the urlquoted version of 'http://hi.baidu.com/重新开始'
-        self.assertEqual(urlize('http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B'),
-            '<a href="http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B" rel="nofollow">'
-            'http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B</a>')
-        self.assertEqual(urlize('www.mystore.com/30%OffCoupons!'),
-            '<a href="http://www.mystore.com/30%25OffCoupons" rel="nofollow">'
-            'www.mystore.com/30%OffCoupons</a>!')
-        self.assertEqual(urlize('http://en.wikipedia.org/wiki/Caf%C3%A9'),
-            '<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">'
-            'http://en.wikipedia.org/wiki/Caf%C3%A9</a>')
-        self.assertEqual(urlize('http://en.wikipedia.org/wiki/Café'),
-            '<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">'
-            'http://en.wikipedia.org/wiki/Café</a>')
-
-        # Check urlize keeps balanced parentheses - see #11911
-        self.assertEqual(urlize('http://en.wikipedia.org/wiki/Django_(web_framework)'),
-            '<a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">'
-            'http://en.wikipedia.org/wiki/Django_(web_framework)</a>')
-        self.assertEqual(urlize('(see http://en.wikipedia.org/wiki/Django_(web_framework))'),
-            '(see <a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">'
-            'http://en.wikipedia.org/wiki/Django_(web_framework)</a>)')
-
-        # Check urlize adds nofollow properly - see #12183
-        self.assertEqual(urlize('foo@bar.com or www.bar.com'),
-            '<a href="mailto:foo@bar.com">foo@bar.com</a> or '
-            '<a href="http://www.bar.com" rel="nofollow">www.bar.com</a>')
-
-        # Check urlize handles IDN correctly - see #13704
-        self.assertEqual(urlize('http://c✶.ws'),
-            '<a href="http://xn--c-lgq.ws" rel="nofollow">http://c✶.ws</a>')
-        self.assertEqual(urlize('www.c✶.ws'),
-            '<a href="http://www.xn--c-lgq.ws" rel="nofollow">www.c✶.ws</a>')
-        self.assertEqual(urlize('c✶.org'),
-            '<a href="http://xn--c-lgq.org" rel="nofollow">c✶.org</a>')
-        self.assertEqual(urlize('info@c✶.org'),
-            '<a href="mailto:info@xn--c-lgq.org">info@c✶.org</a>')
-
-        # Check urlize doesn't highlight malformed URIs - see #16395
-        self.assertEqual(urlize('http:///www.google.com'),
-           'http:///www.google.com')
-        self.assertEqual(urlize('http://.google.com'),
-            'http://.google.com')
-        self.assertEqual(urlize('http://@foo.com'),
-            'http://@foo.com')
-
-        # Check urlize accepts more TLDs - see #16656
-        self.assertEqual(urlize('usa.gov'),
-            '<a href="http://usa.gov" rel="nofollow">usa.gov</a>')
-
-        # Check urlize don't crash on invalid email with dot-starting domain - see #17592
-        self.assertEqual(urlize('email@.stream.ru'),
-            'email@.stream.ru')
-
-        # Check urlize accepts uppercased URL schemes - see #18071
-        self.assertEqual(urlize('HTTPS://github.com/'),
-            '<a href="https://github.com/" rel="nofollow">HTTPS://github.com/</a>')
-
-        # Check urlize trims trailing period when followed by parenthesis - see #18644
-        self.assertEqual(urlize('(Go to http://www.example.com/foo.)'),
-            '(Go to <a href="http://www.example.com/foo" rel="nofollow">http://www.example.com/foo</a>.)')
-
-        # Check urlize handles brackets properly (#19070)
-        self.assertEqual(urlize('[see www.example.com]'),
-            '[see <a href="http://www.example.com" rel="nofollow">www.example.com</a>]')
-        self.assertEqual(urlize('see test[at[example.com'),
-            'see <a href="http://test[at[example.com" rel="nofollow">test[at[example.com</a>')
-        self.assertEqual(urlize('[http://168.192.0.1](http://168.192.0.1)'),
-            '[<a href="http://168.192.0.1](http://168.192.0.1)" rel="nofollow">http://168.192.0.1](http://168.192.0.1)</a>')
-
-        # Check urlize works with IPv4/IPv6 addresses
-        self.assertEqual(urlize('http://192.168.0.15/api/9'),
-            '<a href="http://192.168.0.15/api/9" rel="nofollow">http://192.168.0.15/api/9</a>')
-        self.assertEqual(urlize('http://[2001:db8:cafe::2]/api/9'),
-            '<a href="http://[2001:db8:cafe::2]/api/9" rel="nofollow">http://[2001:db8:cafe::2]/api/9</a>')
-
-        # Check urlize correctly include quotation marks in links - #20364
-        self.assertEqual(urlize('before "hi@example.com" afterwards'),
-                         'before "<a href="mailto:hi@example.com">hi@example.com</a>" afterwards')
-        self.assertEqual(urlize('before hi@example.com" afterwards'),
-                         'before <a href="mailto:hi@example.com">hi@example.com</a>" afterwards')
-        self.assertEqual(urlize('before "hi@example.com afterwards'),
-                         'before "<a href="mailto:hi@example.com">hi@example.com</a> afterwards')
-        self.assertEqual(urlize('before \'hi@example.com\' afterwards'),
-                         'before \'<a href="mailto:hi@example.com">hi@example.com</a>\' afterwards')
-        self.assertEqual(urlize('before hi@example.com\' afterwards'),
-                         'before <a href="mailto:hi@example.com">hi@example.com</a>\' afterwards')
-        self.assertEqual(urlize('before \'hi@example.com afterwards'),
-                         'before \'<a href="mailto:hi@example.com">hi@example.com</a> afterwards')
-
-        # Check urlize copes with commas following URLs in quotes - see #20364
-        self.assertEqual(urlize('Email us at "hi@example.com", or phone us at +xx.yy'),
-            'Email us at "<a href="mailto:hi@example.com">hi@example.com</a>", or phone us at +xx.yy')
-
-        # Check urlize correctly handles exclamation marks after TLDs or query string - see #23715
-        self.assertEqual(urlize('Go to djangoproject.com! and enjoy.'),
-            'Go to <a href="http://djangoproject.com" rel="nofollow">djangoproject.com</a>! and enjoy.')
-        self.assertEqual(urlize('Search for google.com/?q=! and see.'),
-            'Search for <a href="http://google.com/?q=" rel="nofollow">google.com/?q=</a>! and see.')
-        self.assertEqual(urlize('Search for google.com/?q=dj!`? and see.'),
-            'Search for <a href="http://google.com/?q=dj%21%60%3F" rel="nofollow">google.com/?q=dj!`?</a> and see.')
-        self.assertEqual(urlize('Search for google.com/?q=dj!`?! and see.'),
-            'Search for <a href="http://google.com/?q=dj%21%60%3F" rel="nofollow">google.com/?q=dj!`?</a>! and see.')
-
-    def test_wordcount(self):
-        self.assertEqual(wordcount(''), 0)
-        self.assertEqual(wordcount('oneword'), 1)
-        self.assertEqual(wordcount('lots of words'), 3)
-
-    def test_wordwrap(self):
-        self.assertEqual(wordwrap('this is a long paragraph of text that '
-            "really needs to be wrapped I'm afraid", 14),
-            'this is a long\nparagraph of\ntext that\nreally needs\nto be '
-            "wrapped\nI'm afraid")
-        self.assertEqual(wordwrap('this is a short paragraph of text.\n  '
-            'But this line should be indented', 14),
-            'this is a\nshort\nparagraph of\ntext.\n  But this\nline '
-            'should be\nindented')
-        self.assertEqual(wordwrap('this is a short paragraph of text.\n  '
-            'But this line should be indented', 15), 'this is a short\n'
-            'paragraph of\ntext.\n  But this line\nshould be\nindented')
-
-    def test_rjust(self):
-        self.assertEqual(ljust('test', 10), 'test      ')
-        self.assertEqual(ljust('test', 3), 'test')
-        self.assertEqual(rjust('test', 10), '      test')
-        self.assertEqual(rjust('test', 3), 'test')
-
-    def test_center(self):
-        self.assertEqual(center('test', 6), ' test ')
-
-    def test_cut(self):
-        self.assertEqual(cut('a string to be mangled', 'a'),
-                         ' string to be mngled')
-        self.assertEqual(cut('a string to be mangled', 'ng'),
-                         'a stri to be maled')
-        self.assertEqual(cut('a string to be mangled', 'strings'),
-                         'a string to be mangled')
-
-    def test_force_escape(self):
-        escaped = force_escape('<some html & special characters > here')
-        self.assertEqual(
-            escaped, '&lt;some html &amp; special characters &gt; here')
-        self.assertIsInstance(escaped, SafeData)
-        self.assertEqual(
-            force_escape('<some html & special characters > here ĐÅ€£'),
-            '&lt;some html &amp; special characters &gt; here'
-            ' \u0110\xc5\u20ac\xa3')
-
-    def test_linebreaks(self):
-        self.assertEqual(linebreaks_filter('line 1'), '<p>line 1</p>')
-        self.assertEqual(linebreaks_filter('line 1\nline 2'),
-                         '<p>line 1<br />line 2</p>')
-        self.assertEqual(linebreaks_filter('line 1\rline 2'),
-                         '<p>line 1<br />line 2</p>')
-        self.assertEqual(linebreaks_filter('line 1\r\nline 2'),
-                         '<p>line 1<br />line 2</p>')
-
-    def test_linebreaksbr(self):
-        self.assertEqual(linebreaksbr('line 1\nline 2'),
-                         'line 1<br />line 2')
-        self.assertEqual(linebreaksbr('line 1\rline 2'),
-                         'line 1<br />line 2')
-        self.assertEqual(linebreaksbr('line 1\r\nline 2'),
-                         'line 1<br />line 2')
-
-    def test_removetags(self):
-        with warnings.catch_warnings(record=True):
-            warnings.simplefilter("always")
-            self.assertEqual(removetags('some <b>html</b> with <script>alert'
-                '("You smell")</script> disallowed <img /> tags', 'script img'),
-                'some <b>html</b> with alert("You smell") disallowed  tags')
-
-    def test_striptags(self):
-        self.assertEqual(striptags('some <b>html</b> with <script>alert'
-            '("You smell")</script> disallowed <img /> tags'),
-            'some html with alert("You smell") disallowed  tags')
-
-    def test_dictsort(self):
-        sorted_dicts = dictsort([{'age': 23, 'name': 'Barbara-Ann'},
-                                 {'age': 63, 'name': 'Ra Ra Rasputin'},
-                                 {'name': 'Jonny B Goode', 'age': 18}], 'age')
-
-        self.assertEqual([sorted(dict.items()) for dict in sorted_dicts],
-            [[('age', 18), ('name', 'Jonny B Goode')],
-             [('age', 23), ('name', 'Barbara-Ann')],
-             [('age', 63), ('name', 'Ra Ra Rasputin')]])
-
-        # If it gets passed a list of something else different from
-        # dictionaries it should fail silently
-        self.assertEqual(dictsort([1, 2, 3], 'age'), '')
-        self.assertEqual(dictsort('Hello!', 'age'), '')
-        self.assertEqual(dictsort({'a': 1}, 'age'), '')
-        self.assertEqual(dictsort(1, 'age'), '')
-
-    def test_dictsort_complex_sorting_key(self):
-        """
-        Since dictsort uses template.Variable under the hood, it can sort
-        on keys like 'foo.bar'.
-        """
-        data = [
-            {'foo': {'bar': 1, 'baz': 'c'}},
-            {'foo': {'bar': 2, 'baz': 'b'}},
-            {'foo': {'bar': 3, 'baz': 'a'}},
-        ]
-        sorted_data = dictsort(data, 'foo.baz')
-
-        self.assertEqual([d['foo']['bar'] for d in sorted_data], [3, 2, 1])
-
-    def test_dictsortreversed(self):
-        sorted_dicts = dictsortreversed([{'age': 23, 'name': 'Barbara-Ann'},
-                                         {'age': 63, 'name': 'Ra Ra Rasputin'},
-                                         {'name': 'Jonny B Goode', 'age': 18}],
-                                        'age')
-
-        self.assertEqual([sorted(dict.items()) for dict in sorted_dicts],
-            [[('age', 63), ('name', 'Ra Ra Rasputin')],
-             [('age', 23), ('name', 'Barbara-Ann')],
-             [('age', 18), ('name', 'Jonny B Goode')]])
-
-        # If it gets passed a list of something else different from
-        # dictionaries it should fail silently
-        self.assertEqual(dictsortreversed([1, 2, 3], 'age'), '')
-        self.assertEqual(dictsortreversed('Hello!', 'age'), '')
-        self.assertEqual(dictsortreversed({'a': 1}, 'age'), '')
-        self.assertEqual(dictsortreversed(1, 'age'), '')
-
-    def test_first(self):
-        self.assertEqual(first([0, 1, 2]), 0)
-        self.assertEqual(first(''), '')
-        self.assertEqual(first('test'), 't')
-
-    def test_join(self):
-        self.assertEqual(join([0, 1, 2], 'glue'), '0glue1glue2')
-
-    def test_length(self):
-        self.assertEqual(length('1234'), 4)
-        self.assertEqual(length(mark_safe('1234')), 4)
-        self.assertEqual(length([1, 2, 3, 4]), 4)
-        self.assertEqual(length_is([], 0), True)
-        self.assertEqual(length_is([], 1), False)
-        self.assertEqual(length_is('a', 1), True)
-        self.assertEqual(length_is('a', 10), False)
-
-    def test_slice(self):
-        self.assertEqual(slice_filter('abcdefg', '0'), '')
-        self.assertEqual(slice_filter('abcdefg', '1'), 'a')
-        self.assertEqual(slice_filter('abcdefg', '-1'), 'abcdef')
-        self.assertEqual(slice_filter('abcdefg', '1:2'), 'b')
-        self.assertEqual(slice_filter('abcdefg', '1:3'), 'bc')
-        self.assertEqual(slice_filter('abcdefg', '0::2'), 'aceg')
-
-    def test_unordered_list(self):
-        self.assertEqual(unordered_list(['item 1', 'item 2']),
-            '\t<li>item 1</li>\n\t<li>item 2</li>')
-        self.assertEqual(unordered_list(['item 1', ['item 1.1']]),
-            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>')
-
-        self.assertEqual(
-            unordered_list(['item 1', ['item 1.1', 'item1.2'], 'item 2']),
-            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item1.2'
-            '</li>\n\t</ul>\n\t</li>\n\t<li>item 2</li>')
-
-        self.assertEqual(
-            unordered_list(['item 1', ['item 1.1', ['item 1.1.1', ['item 1.1.1.1']]]]),
-            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1\n\t\t<ul>\n\t\t\t<li>'
-            'item 1.1.1\n\t\t\t<ul>\n\t\t\t\t<li>item 1.1.1.1</li>\n\t\t\t'
-            '</ul>\n\t\t\t</li>\n\t\t</ul>\n\t\t</li>\n\t</ul>\n\t</li>')
-
-        self.assertEqual(unordered_list(
-            ['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]),
-            '\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>'
-            'Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>'
-            '\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>')
-
-        @python_2_unicode_compatible
-        class ULItem(object):
-            def __init__(self, title):
-                self.title = title
-
-            def __str__(self):
-                return 'ulitem-%s' % str(self.title)
-
-        a = ULItem('a')
-        b = ULItem('b')
-        self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
-
-        def item_generator():
-            yield a
-            yield b
-
-        self.assertEqual(unordered_list(item_generator()), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
-
-        # Old format for unordered lists should still work
-        with warnings.catch_warnings(record=True):
-            warnings.simplefilter("always")
-
-            self.assertEqual(unordered_list(['item 1', []]), '\t<li>item 1</li>')
-
-            self.assertEqual(unordered_list(['item 1', [['item 1.1', []]]]),
-                '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>')
-
-            self.assertEqual(unordered_list(['item 1', [['item 1.1', []],
-                ['item 1.2', []]]]), '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1'
-                '</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>')
-
-            self.assertEqual(unordered_list(['States', [['Kansas', [['Lawrence',
-                []], ['Topeka', []]]], ['Illinois', []]]]), '\t<li>States\n\t'
-                '<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>'
-                '\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>'
-                'Illinois</li>\n\t</ul>\n\t</li>')
-
-    def test_add(self):
-        self.assertEqual(add('1', '2'), 3)
-
-    def test_get_digit(self):
-        self.assertEqual(get_digit(123, 1), 3)
-        self.assertEqual(get_digit(123, 2), 2)
-        self.assertEqual(get_digit(123, 3), 1)
-        self.assertEqual(get_digit(123, 4), 0)
-        self.assertEqual(get_digit(123, 0), 123)
-        self.assertEqual(get_digit('xyz', 0), 'xyz')
-
-    def test_date(self):
-        # real testing of date() is in dateformat.py
-        self.assertEqual(date(datetime.datetime(2005, 12, 29), "d F Y"),
-                         '29 December 2005')
-        self.assertEqual(date(datetime.datetime(2005, 12, 29), r'jS \o\f F'),
-                         '29th of December')
-
-    def test_time(self):
-        # real testing of time() is done in dateformat.py
-        self.assertEqual(time(datetime.time(13), "h"), '01')
-        self.assertEqual(time(datetime.time(0), "h"), '12')
-
-    def test_timesince(self):
-        # real testing is done in timesince.py, where we can provide our own 'now'
-        # NOTE: \xa0 avoids wrapping between value and unit
-        self.assertEqual(
-            timesince_filter(datetime.datetime.now() - datetime.timedelta(1)),
-            '1\xa0day')
-
-        self.assertEqual(
-            timesince_filter(datetime.datetime(2005, 12, 29),
-                             datetime.datetime(2005, 12, 30)),
-            '1\xa0day')
-
-    def test_timeuntil(self):
-        # NOTE: \xa0 avoids wrapping between value and unit
-        self.assertEqual(
-            timeuntil_filter(datetime.datetime.now() + datetime.timedelta(1, 1)),
-            '1\xa0day')
-
-        self.assertEqual(
-            timeuntil_filter(datetime.datetime(2005, 12, 30),
-                             datetime.datetime(2005, 12, 29)),
-            '1\xa0day')
-
-    def test_default(self):
-        self.assertEqual(default("val", "default"), 'val')
-        self.assertEqual(default(None, "default"), 'default')
-        self.assertEqual(default('', "default"), 'default')
-
-    def test_if_none(self):
-        self.assertEqual(default_if_none("val", "default"), 'val')
-        self.assertEqual(default_if_none(None, "default"), 'default')
-        self.assertEqual(default_if_none('', "default"), '')
-
-    def test_divisibleby(self):
-        self.assertEqual(divisibleby(4, 2), True)
-        self.assertEqual(divisibleby(4, 3), False)
-
-    def test_yesno(self):
-        self.assertEqual(yesno(True), 'yes')
-        self.assertEqual(yesno(False), 'no')
-        self.assertEqual(yesno(None), 'maybe')
-        self.assertEqual(yesno(True, 'certainly,get out of town,perhaps'),
-                         'certainly')
-        self.assertEqual(yesno(False, 'certainly,get out of town,perhaps'),
-                         'get out of town')
-        self.assertEqual(yesno(None, 'certainly,get out of town,perhaps'),
-                         'perhaps')
-        self.assertEqual(yesno(None, 'certainly,get out of town'),
-                         'get out of town')
-
-    def test_filesizeformat(self):
-        # NOTE: \xa0 avoids wrapping between value and unit
-        self.assertEqual(filesizeformat(1023), '1023\xa0bytes')
-        self.assertEqual(filesizeformat(1024), '1.0\xa0KB')
-        self.assertEqual(filesizeformat(10 * 1024), '10.0\xa0KB')
-        self.assertEqual(filesizeformat(1024 * 1024 - 1), '1024.0\xa0KB')
-        self.assertEqual(filesizeformat(1024 * 1024), '1.0\xa0MB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 50), '50.0\xa0MB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 1024 - 1), '1024.0\xa0MB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 1024), '1.0\xa0GB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024), '1.0\xa0TB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024), '1.0\xa0PB')
-        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024 * 2000), '2000.0\xa0PB')
-        self.assertEqual(filesizeformat(complex(1, -1)), '0\xa0bytes')
-        self.assertEqual(filesizeformat(""), '0\xa0bytes')
-        self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), '0\xa0bytes')
-
-    def test_pluralize(self):
-        self.assertEqual(pluralize(1), '')
-        self.assertEqual(pluralize(0), 's')
-        self.assertEqual(pluralize(2), 's')
-
-        # Ticket #22798
-        self.assertEqual(pluralize(0.5), 's')
-        self.assertEqual(pluralize(1.5), 's')
-
-        self.assertEqual(pluralize(decimal.Decimal(1)), '')
-        self.assertEqual(pluralize(decimal.Decimal(0)), 's')
-        self.assertEqual(pluralize(decimal.Decimal(2)), 's')
-        self.assertEqual(pluralize([1]), '')
-        self.assertEqual(pluralize([]), 's')
-        self.assertEqual(pluralize([1, 2, 3]), 's')
-        self.assertEqual(pluralize(1, 'es'), '')
-        self.assertEqual(pluralize(0, 'es'), 'es')
-        self.assertEqual(pluralize(2, 'es'), 'es')
-        self.assertEqual(pluralize(1, 'y,ies'), 'y')
-        self.assertEqual(pluralize(0, 'y,ies'), 'ies')
-        self.assertEqual(pluralize(2, 'y,ies'), 'ies')
-        self.assertEqual(pluralize(0, 'y,ies,error'), '')
-
-    def test_phone2numeric(self):
-        self.assertEqual(phone2numeric_filter('0800 flowers'), '0800 3569377')
-
-    def test_non_string_input(self):
-        # Filters shouldn't break if passed non-strings
-        self.assertEqual(addslashes(123), '123')
-        self.assertEqual(linenumbers(123), '1. 123')
-        self.assertEqual(lower(123), '123')
-        self.assertEqual(make_list(123), ['1', '2', '3'])
-        self.assertEqual(slugify(123), '123')
-        self.assertEqual(title(123), '123')
-        self.assertEqual(truncatewords(123, 2), '123')
-        self.assertEqual(upper(123), '123')
-        self.assertEqual(urlencode(123), '123')
-        self.assertEqual(urlize(123), '123')
-        self.assertEqual(urlizetrunc(123, 1), '123')
-        self.assertEqual(wordcount(123), 1)
-        self.assertEqual(wordwrap(123, 2), '123')
-        self.assertEqual(ljust('123', 4), '123 ')
-        self.assertEqual(rjust('123', 4), ' 123')
-        self.assertEqual(center('123', 5), ' 123 ')
-        self.assertEqual(center('123', 6), ' 123  ')
-        self.assertEqual(cut(123, '2'), '13')
-        self.assertEqual(escape(123), '123')
-        self.assertEqual(linebreaks_filter(123), '<p>123</p>')
-        self.assertEqual(linebreaksbr(123), '123')
-        with warnings.catch_warnings(record=True):
-            warnings.simplefilter("always")
-            self.assertEqual(removetags(123, 'a'), '123')
-        self.assertEqual(striptags(123), '123')
-
-
-class DefaultFiltersI18NTests(TestCase):
-
-    def test_localized_filesizeformat(self):
-        # NOTE: \xa0 avoids wrapping between value and unit
-        with self.settings(USE_L10N=True), translation.override('de'):
-            self.assertEqual(filesizeformat(1023), '1023\xa0Bytes')
-            self.assertEqual(filesizeformat(1024), '1,0\xa0KB')
-            self.assertEqual(filesizeformat(10 * 1024), '10,0\xa0KB')
-            self.assertEqual(filesizeformat(1024 * 1024 - 1), '1024,0\xa0KB')
-            self.assertEqual(filesizeformat(1024 * 1024), '1,0\xa0MB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 50), '50,0\xa0MB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 1024 - 1), '1024,0\xa0MB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 1024), '1,0\xa0GB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024), '1,0\xa0TB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024), '1,0\xa0PB')
-            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024 * 2000), '2000,0\xa0PB')
-            self.assertEqual(filesizeformat(complex(1, -1)), '0\xa0Bytes')
-            self.assertEqual(filesizeformat(""), '0\xa0Bytes')
-            self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), '0\xa0Bytes')
diff --git a/tests/template_tests/filter_tests/test_add.py b/tests/template_tests/filter_tests/test_add.py
index 9faf81dfa5..802c1cfe19 100644
--- a/tests/template_tests/filter_tests/test_add.py
+++ b/tests/template_tests/filter_tests/test_add.py
@@ -1,5 +1,6 @@
 from datetime import date, timedelta
 
+from django.template.defaultfilters import add
 from django.test import SimpleTestCase
 
 from ..utils import render, setup
@@ -44,3 +45,9 @@ class AddTests(SimpleTestCase):
     def test_add07(self):
         output = render('add07', {'d': date(2000, 1, 1), 't': timedelta(10)})
         self.assertEqual(output, 'Jan. 11, 2000')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_add(self):
+        self.assertEqual(add('1', '2'), 3)
diff --git a/tests/template_tests/filter_tests/test_addslashes.py b/tests/template_tests/filter_tests/test_addslashes.py
index 4d712b4bd4..7be84c0220 100644
--- a/tests/template_tests/filter_tests/test_addslashes.py
+++ b/tests/template_tests/filter_tests/test_addslashes.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import addslashes
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,18 @@ class AddslashesTests(SimpleTestCase):
     def test_addslashes02(self):
         output = render('addslashes02', {"a": "<a>'", "b": mark_safe("<a>'")})
         self.assertEqual(output, r"&lt;a&gt;\&#39; <a>\'")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_quotes(self):
+        self.assertEqual(
+            addslashes('"double quotes" and \'single quotes\''),
+            '\\"double quotes\\" and \\\'single quotes\\\'',
+        )
+
+    def test_backslashes(self):
+        self.assertEqual(addslashes(r'\ : backslashes, too'), '\\\\ : backslashes, too')
+
+    def test_non_string_input(self):
+        self.assertEqual(addslashes(123), '123')
diff --git a/tests/template_tests/filter_tests/test_capfirst.py b/tests/template_tests/filter_tests/test_capfirst.py
index 07546ad6c7..d7a28130f9 100644
--- a/tests/template_tests/filter_tests/test_capfirst.py
+++ b/tests/template_tests/filter_tests/test_capfirst.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import capfirst
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,9 @@ class CapfirstTests(SimpleTestCase):
     def test_capfirst02(self):
         output = render('capfirst02', {'a': 'fred>', 'b': mark_safe('fred&gt;')})
         self.assertEqual(output, 'Fred&gt; Fred&gt;')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_capfirst(self):
+        self.assertEqual(capfirst('hello world'), 'Hello world')
diff --git a/tests/template_tests/filter_tests/test_center.py b/tests/template_tests/filter_tests/test_center.py
index 6f10f99a85..0dbb1002b7 100644
--- a/tests/template_tests/filter_tests/test_center.py
+++ b/tests/template_tests/filter_tests/test_center.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import center
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -16,3 +17,12 @@ class CenterTests(SimpleTestCase):
     def test_center02(self):
         output = render('center02', {"a": "a&b", "b": mark_safe("a&b")})
         self.assertEqual(output, ". a&amp;b . . a&b .")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_center(self):
+        self.assertEqual(center('test', 6), ' test ')
+
+    def test_non_string_input(self):
+        self.assertEqual(center(123, 5), ' 123 ')
diff --git a/tests/template_tests/filter_tests/test_cut.py b/tests/template_tests/filter_tests/test_cut.py
index 68568df30c..fde23266ba 100644
--- a/tests/template_tests/filter_tests/test_cut.py
+++ b/tests/template_tests/filter_tests/test_cut.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import cut
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -37,3 +38,18 @@ class CutTests(SimpleTestCase):
     def test_cut06(self):
         output = render('cut06', {"a": "x&y", "b": mark_safe("x&amp;y")})
         self.assertEqual(output, "x&amp;y x&amp;ampy")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_character(self):
+        self.assertEqual(cut('a string to be mangled', 'a'), ' string to be mngled')
+
+    def test_characters(self):
+        self.assertEqual(cut('a string to be mangled', 'ng'), 'a stri to be maled')
+
+    def test_non_matching_string(self):
+        self.assertEqual(cut('a string to be mangled', 'strings'), 'a string to be mangled')
+
+    def test_non_string_input(self):
+        self.assertEqual(cut(123, '2'), '13')
diff --git a/tests/template_tests/filter_tests/test_date.py b/tests/template_tests/filter_tests/test_date.py
index cbec356908..e546dae430 100644
--- a/tests/template_tests/filter_tests/test_date.py
+++ b/tests/template_tests/filter_tests/test_date.py
@@ -1,5 +1,7 @@
 from datetime import datetime, time
 
+from django.template.defaultfilters import date
+from django.test import SimpleTestCase
 from django.utils import timezone
 
 from .timezone_utils import TimezoneTestCase
@@ -58,3 +60,12 @@ class DateTests(TimezoneTestCase):
     def test_date09(self):
         output = render('date09', {'t': time(0, 0)})
         self.assertEqual(output, '00:00')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_date(self):
+        self.assertEqual(date(datetime(2005, 12, 29), "d F Y"), '29 December 2005')
+
+    def test_escape_characters(self):
+        self.assertEqual(date(datetime(2005, 12, 29), r'jS \o\f F'), '29th of December')
diff --git a/tests/template_tests/filter_tests/test_default.py b/tests/template_tests/filter_tests/test_default.py
index 790f60cd3b..766957ba35 100644
--- a/tests/template_tests/filter_tests/test_default.py
+++ b/tests/template_tests/filter_tests/test_default.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import default
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -45,3 +46,15 @@ class DefaultIfNoneTests(SimpleTestCase):
     def test_default_if_none02(self):
         output = render('default_if_none02', {"a": None})
         self.assertEqual(output, "x<")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_value(self):
+        self.assertEqual(default('val', 'default'), 'val')
+
+    def test_none(self):
+        self.assertEqual(default(None, 'default'), 'default')
+
+    def test_empty_string(self):
+        self.assertEqual(default('', 'default'), 'default')
diff --git a/tests/template_tests/filter_tests/test_default_if_none.py b/tests/template_tests/filter_tests/test_default_if_none.py
new file mode 100644
index 0000000000..45bd666913
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_default_if_none.py
@@ -0,0 +1,14 @@
+from django.template.defaultfilters import default_if_none
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_value(self):
+        self.assertEqual(default_if_none("val", 'default'), 'val')
+
+    def test_none(self):
+        self.assertEqual(default_if_none(None, 'default'), 'default')
+
+    def test_empty_string(self):
+        self.assertEqual(default_if_none('', 'default'), '')
diff --git a/tests/template_tests/filter_tests/test_dictsort.py b/tests/template_tests/filter_tests/test_dictsort.py
new file mode 100644
index 0000000000..1d937a2dae
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_dictsort.py
@@ -0,0 +1,44 @@
+from django.template.defaultfilters import dictsort
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_sort(self):
+        sorted_dicts = dictsort(
+            [{'age': 23, 'name': 'Barbara-Ann'},
+             {'age': 63, 'name': 'Ra Ra Rasputin'},
+             {'name': 'Jonny B Goode', 'age': 18}],
+            'age',
+        )
+
+        self.assertEqual(
+            [sorted(dict.items()) for dict in sorted_dicts],
+            [[('age', 18), ('name', 'Jonny B Goode')],
+             [('age', 23), ('name', 'Barbara-Ann')],
+             [('age', 63), ('name', 'Ra Ra Rasputin')]],
+        )
+
+    def test_dictsort_complex_sorting_key(self):
+        """
+        Since dictsort uses template.Variable under the hood, it can sort
+        on keys like 'foo.bar'.
+        """
+        data = [
+            {'foo': {'bar': 1, 'baz': 'c'}},
+            {'foo': {'bar': 2, 'baz': 'b'}},
+            {'foo': {'bar': 3, 'baz': 'a'}},
+        ]
+        sorted_data = dictsort(data, 'foo.baz')
+
+        self.assertEqual([d['foo']['bar'] for d in sorted_data], [3, 2, 1])
+
+    def test_invalid_values(self):
+        """
+        If dictsort is passed something other than a list of dictionaries,
+        fail silently.
+        """
+        self.assertEqual(dictsort([1, 2, 3], 'age'), '')
+        self.assertEqual(dictsort('Hello!', 'age'), '')
+        self.assertEqual(dictsort({'a': 1}, 'age'), '')
+        self.assertEqual(dictsort(1, 'age'), '')
diff --git a/tests/template_tests/filter_tests/test_dictsortreversed.py b/tests/template_tests/filter_tests/test_dictsortreversed.py
new file mode 100644
index 0000000000..92229495fe
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_dictsortreversed.py
@@ -0,0 +1,30 @@
+from django.template.defaultfilters import dictsortreversed
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_sort(self):
+        sorted_dicts = dictsortreversed(
+            [{'age': 23, 'name': 'Barbara-Ann'},
+             {'age': 63, 'name': 'Ra Ra Rasputin'},
+             {'name': 'Jonny B Goode', 'age': 18}],
+            'age',
+        )
+
+        self.assertEqual(
+            [sorted(dict.items()) for dict in sorted_dicts],
+            [[('age', 63), ('name', 'Ra Ra Rasputin')],
+             [('age', 23), ('name', 'Barbara-Ann')],
+             [('age', 18), ('name', 'Jonny B Goode')]],
+        )
+
+    def test_invalid_values(self):
+        """
+        If dictsortreversed is passed something other than a list of
+        dictionaries, fail silently.
+        """
+        self.assertEqual(dictsortreversed([1, 2, 3], 'age'), '')
+        self.assertEqual(dictsortreversed('Hello!', 'age'), '')
+        self.assertEqual(dictsortreversed({'a': 1}, 'age'), '')
+        self.assertEqual(dictsortreversed(1, 'age'), '')
diff --git a/tests/template_tests/filter_tests/test_divisibleby.py b/tests/template_tests/filter_tests/test_divisibleby.py
new file mode 100644
index 0000000000..2b3fe9aa4c
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_divisibleby.py
@@ -0,0 +1,11 @@
+from django.template.defaultfilters import divisibleby
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_true(self):
+        self.assertEqual(divisibleby(4, 2), True)
+
+    def test_false(self):
+        self.assertEqual(divisibleby(4, 3), False)
diff --git a/tests/template_tests/filter_tests/test_escape.py b/tests/template_tests/filter_tests/test_escape.py
index 81f0f4037a..094bf575ce 100644
--- a/tests/template_tests/filter_tests/test_escape.py
+++ b/tests/template_tests/filter_tests/test_escape.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import escape
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -31,3 +32,9 @@ class EscapeTests(SimpleTestCase):
     def test_escape04(self):
         output = render('escape04', {"a": "x&y"})
         self.assertEqual(output, "x&amp;y")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_non_string_input(self):
+        self.assertEqual(escape(123), '123')
diff --git a/tests/template_tests/filter_tests/test_escapejs.py b/tests/template_tests/filter_tests/test_escapejs.py
index 82019022ec..d124be1667 100644
--- a/tests/template_tests/filter_tests/test_escapejs.py
+++ b/tests/template_tests/filter_tests/test_escapejs.py
@@ -1,3 +1,6 @@
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import escapejs_filter
 from django.test import SimpleTestCase
 
 from ..utils import render, setup
@@ -18,3 +21,33 @@ class EscapejsTests(SimpleTestCase):
         self.assertEqual(output, 'testing\\u000D\\u000Ajavascript '
                                  '\\u0027string\\u0022 \\u003Cb\\u003E'
                                  'escaping\\u003C/b\\u003E')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_quotes(self):
+        self.assertEqual(
+            escapejs_filter('"double quotes" and \'single quotes\''),
+            '\\u0022double quotes\\u0022 and \\u0027single quotes\\u0027',
+        )
+
+    def test_backslashes(self):
+        self.assertEqual(escapejs_filter(r'\ : backslashes, too'), '\\u005C : backslashes, too')
+
+    def test_whitespace(self):
+        self.assertEqual(
+            escapejs_filter('and lots of whitespace: \r\n\t\v\f\b'),
+            'and lots of whitespace: \\u000D\\u000A\\u0009\\u000B\\u000C\\u0008',
+        )
+
+    def test_script(self):
+        self.assertEqual(
+            escapejs_filter(r'<script>and this</script>'),
+            '\\u003Cscript\\u003Eand this\\u003C/script\\u003E',
+        )
+
+    def test_paragraph_separator(self):
+        self.assertEqual(
+            escapejs_filter('paragraph separator:\u2029and line separator:\u2028'),
+            'paragraph separator:\\u2029and line separator:\\u2028',
+        )
diff --git a/tests/template_tests/filter_tests/test_filesizeformat.py b/tests/template_tests/filter_tests/test_filesizeformat.py
new file mode 100644
index 0000000000..c94da8c8d6
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_filesizeformat.py
@@ -0,0 +1,41 @@
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import filesizeformat
+from django.test import SimpleTestCase
+from django.utils import translation
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_formats(self):
+        self.assertEqual(filesizeformat(1023), '1023\xa0bytes')
+        self.assertEqual(filesizeformat(1024), '1.0\xa0KB')
+        self.assertEqual(filesizeformat(10 * 1024), '10.0\xa0KB')
+        self.assertEqual(filesizeformat(1024 * 1024 - 1), '1024.0\xa0KB')
+        self.assertEqual(filesizeformat(1024 * 1024), '1.0\xa0MB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 50), '50.0\xa0MB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 1024 - 1), '1024.0\xa0MB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 1024), '1.0\xa0GB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024), '1.0\xa0TB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024), '1.0\xa0PB')
+        self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024 * 2000), '2000.0\xa0PB')
+        self.assertEqual(filesizeformat(complex(1, -1)), '0\xa0bytes')
+        self.assertEqual(filesizeformat(""), '0\xa0bytes')
+        self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), '0\xa0bytes')
+
+    def test_localized_formats(self):
+        with self.settings(USE_L10N=True), translation.override('de'):
+            self.assertEqual(filesizeformat(1023), '1023\xa0Bytes')
+            self.assertEqual(filesizeformat(1024), '1,0\xa0KB')
+            self.assertEqual(filesizeformat(10 * 1024), '10,0\xa0KB')
+            self.assertEqual(filesizeformat(1024 * 1024 - 1), '1024,0\xa0KB')
+            self.assertEqual(filesizeformat(1024 * 1024), '1,0\xa0MB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 50), '50,0\xa0MB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 1024 - 1), '1024,0\xa0MB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 1024), '1,0\xa0GB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024), '1,0\xa0TB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024), '1,0\xa0PB')
+            self.assertEqual(filesizeformat(1024 * 1024 * 1024 * 1024 * 1024 * 2000), '2000,0\xa0PB')
+            self.assertEqual(filesizeformat(complex(1, -1)), '0\xa0Bytes')
+            self.assertEqual(filesizeformat(""), '0\xa0Bytes')
+            self.assertEqual(filesizeformat("\N{GREEK SMALL LETTER ALPHA}"), '0\xa0Bytes')
diff --git a/tests/template_tests/filter_tests/test_first.py b/tests/template_tests/filter_tests/test_first.py
index 566a70c4ac..c7361dbd12 100644
--- a/tests/template_tests/filter_tests/test_first.py
+++ b/tests/template_tests/filter_tests/test_first.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import first
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,15 @@ class FirstTests(SimpleTestCase):
     def test_first02(self):
         output = render('first02', {"a": ["a&b", "x"], "b": [mark_safe("a&b"), "x"]})
         self.assertEqual(output, "a&b a&b")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_list(self):
+        self.assertEqual(first([0, 1, 2]), 0)
+
+    def test_empty_string(self):
+        self.assertEqual(first(''), '')
+
+    def test_string(self):
+        self.assertEqual(first('test'), 't')
diff --git a/tests/template_tests/filter_tests/test_floatformat.py b/tests/template_tests/filter_tests/test_floatformat.py
index a69278f958..466984b006 100644
--- a/tests/template_tests/filter_tests/test_floatformat.py
+++ b/tests/template_tests/filter_tests/test_floatformat.py
@@ -1,4 +1,12 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from decimal import Decimal, localcontext
+from unittest import expectedFailure
+
+from django.template.defaultfilters import floatformat
 from django.test import SimpleTestCase
+from django.utils import six
 from django.utils.safestring import mark_safe
 
 from ..utils import render, setup
@@ -16,3 +24,86 @@ class FloatformatTests(SimpleTestCase):
     def test_floatformat02(self):
         output = render('floatformat02', {"a": "1.42", "b": mark_safe("1.42")})
         self.assertEqual(output, "1.4 1.4")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_inputs(self):
+        self.assertEqual(floatformat(7.7), '7.7')
+        self.assertEqual(floatformat(7.0), '7')
+        self.assertEqual(floatformat(0.7), '0.7')
+        self.assertEqual(floatformat(0.07), '0.1')
+        self.assertEqual(floatformat(0.007), '0.0')
+        self.assertEqual(floatformat(0.0), '0')
+        self.assertEqual(floatformat(7.7, 3), '7.700')
+        self.assertEqual(floatformat(6.000000, 3), '6.000')
+        self.assertEqual(floatformat(6.200000, 3), '6.200')
+        self.assertEqual(floatformat(6.200000, -3), '6.200')
+        self.assertEqual(floatformat(13.1031, -3), '13.103')
+        self.assertEqual(floatformat(11.1197, -2), '11.12')
+        self.assertEqual(floatformat(11.0000, -2), '11')
+        self.assertEqual(floatformat(11.000001, -2), '11.00')
+        self.assertEqual(floatformat(8.2798, 3), '8.280')
+        self.assertEqual(floatformat(5555.555, 2), '5555.56')
+        self.assertEqual(floatformat(001.3000, 2), '1.30')
+        self.assertEqual(floatformat(0.12345, 2), '0.12')
+        self.assertEqual(floatformat(Decimal('555.555'), 2), '555.56')
+        self.assertEqual(floatformat(Decimal('09.000')), '9')
+        self.assertEqual(floatformat('foo'), '')
+        self.assertEqual(floatformat(13.1031, 'bar'), '13.1031')
+        self.assertEqual(floatformat(18.125, 2), '18.13')
+        self.assertEqual(floatformat('foo', 'bar'), '')
+        self.assertEqual(floatformat('¿Cómo esta usted?'), '')
+        self.assertEqual(floatformat(None), '')
+
+    def test_zero_values(self):
+        """
+        Check that we're not converting to scientific notation.
+        """
+        self.assertEqual(floatformat(0, 6), '0.000000')
+        self.assertEqual(floatformat(0, 7), '0.0000000')
+        self.assertEqual(floatformat(0, 10), '0.0000000000')
+        self.assertEqual(floatformat(0.000000000000000000015, 20),
+                         '0.00000000000000000002')
+
+    def test_infinity(self):
+        pos_inf = float(1e30000)
+        self.assertEqual(floatformat(pos_inf), six.text_type(pos_inf))
+
+        neg_inf = float(-1e30000)
+        self.assertEqual(floatformat(neg_inf), six.text_type(neg_inf))
+
+        nan = pos_inf / pos_inf
+        self.assertEqual(floatformat(nan), six.text_type(nan))
+
+    def test_float_dunder_method(self):
+        class FloatWrapper(object):
+            def __init__(self, value):
+                self.value = value
+
+            def __float__(self):
+                return self.value
+
+        self.assertEqual(floatformat(FloatWrapper(11.000001), -2), '11.00')
+
+    def test_low_decimal_precision(self):
+        """
+        #15789
+        """
+        with localcontext() as ctx:
+            ctx.prec = 2
+            self.assertEqual(floatformat(1.2345, 2), '1.23')
+            self.assertEqual(floatformat(15.2042, -3), '15.204')
+            self.assertEqual(floatformat(1.2345, '2'), '1.23')
+            self.assertEqual(floatformat(15.2042, '-3'), '15.204')
+            self.assertEqual(floatformat(Decimal('1.2345'), 2), '1.23')
+            self.assertEqual(floatformat(Decimal('15.2042'), -3), '15.204')
+
+    def test_many_zeroes(self):
+        self.assertEqual(floatformat(1.00000000000000015, 16), '1.0000000000000002')
+
+    if six.PY2:
+        # The above test fails because of Python 2's float handling. Floats
+        # with many zeroes after the decimal point should be passed in as
+        # another type such as unicode or Decimal.
+        test_many_zeroes = expectedFailure(test_many_zeroes)
diff --git a/tests/template_tests/filter_tests/test_force_escape.py b/tests/template_tests/filter_tests/test_force_escape.py
index 1217e07793..b231d8e374 100644
--- a/tests/template_tests/filter_tests/test_force_escape.py
+++ b/tests/template_tests/filter_tests/test_force_escape.py
@@ -1,4 +1,9 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import force_escape
 from django.test import SimpleTestCase
+from django.utils.safestring import SafeData
 
 from ..utils import render, setup
 
@@ -50,3 +55,17 @@ class ForceEscapeTests(SimpleTestCase):
     def test_force_escape08(self):
         output = render('force-escape08', {"a": "x&y"})
         self.assertEqual(output, "x&amp;y")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_escape(self):
+        escaped = force_escape('<some html & special characters > here')
+        self.assertEqual(escaped, '&lt;some html &amp; special characters &gt; here')
+        self.assertIsInstance(escaped, SafeData)
+
+    def test_unicode(self):
+        self.assertEqual(
+            force_escape('<some html & special characters > here ĐÅ€£'),
+            '&lt;some html &amp; special characters &gt; here \u0110\xc5\u20ac\xa3',
+        )
diff --git a/tests/template_tests/filter_tests/test_get_digit.py b/tests/template_tests/filter_tests/test_get_digit.py
new file mode 100644
index 0000000000..1382408715
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_get_digit.py
@@ -0,0 +1,15 @@
+from django.template.defaultfilters import get_digit
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_values(self):
+        self.assertEqual(get_digit(123, 1), 3)
+        self.assertEqual(get_digit(123, 2), 2)
+        self.assertEqual(get_digit(123, 3), 1)
+        self.assertEqual(get_digit(123, 4), 0)
+        self.assertEqual(get_digit(123, 0), 123)
+
+    def test_string(self):
+        self.assertEqual(get_digit('xyz', 0), 'xyz')
diff --git a/tests/template_tests/filter_tests/test_iriencode.py b/tests/template_tests/filter_tests/test_iriencode.py
index b06f05b909..c44c54eb6a 100644
--- a/tests/template_tests/filter_tests/test_iriencode.py
+++ b/tests/template_tests/filter_tests/test_iriencode.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import iriencode, urlencode
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -28,3 +32,12 @@ class IriencodeTests(SimpleTestCase):
     def test_iriencode04(self):
         output = render('iriencode04', {'url': mark_safe('?test=1&me=2')})
         self.assertEqual(output, '?test=1&me=2')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_unicode(self):
+        self.assertEqual(iriencode('S\xf8r-Tr\xf8ndelag'), 'S%C3%B8r-Tr%C3%B8ndelag')
+
+    def test_urlencoded(self):
+        self.assertEqual(iriencode(urlencode('fran\xe7ois & jill')), 'fran%C3%A7ois%20%26%20jill')
diff --git a/tests/template_tests/filter_tests/test_join.py b/tests/template_tests/filter_tests/test_join.py
index a6c93e7332..87a00d6d18 100644
--- a/tests/template_tests/filter_tests/test_join.py
+++ b/tests/template_tests/filter_tests/test_join.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import join
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -47,3 +48,9 @@ class JoinTests(SimpleTestCase):
     def test_join08(self):
         output = render('join08', {'a': ['Alpha', 'Beta & me'], 'var': mark_safe(' & ')})
         self.assertEqual(output, 'alpha & beta &amp; me')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_list(self):
+        self.assertEqual(join([0, 1, 2], 'glue'), '0glue1glue2')
diff --git a/tests/template_tests/filter_tests/test_length.py b/tests/template_tests/filter_tests/test_length.py
index f81912ce03..cd605aa785 100644
--- a/tests/template_tests/filter_tests/test_length.py
+++ b/tests/template_tests/filter_tests/test_length.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import length
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -41,3 +42,15 @@ class LengthTests(SimpleTestCase):
     def test_length07(self):
         output = render('length07', {'None': None})
         self.assertEqual(output, '0')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_string(self):
+        self.assertEqual(length('1234'), 4)
+
+    def test_safestring(self):
+        self.assertEqual(length(mark_safe('1234')), 4)
+
+    def test_list(self):
+        self.assertEqual(length([1, 2, 3, 4]), 4)
diff --git a/tests/template_tests/filter_tests/test_length_is.py b/tests/template_tests/filter_tests/test_length_is.py
index 5d67d453d7..d0f547a3c2 100644
--- a/tests/template_tests/filter_tests/test_length_is.py
+++ b/tests/template_tests/filter_tests/test_length_is.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import length_is
 from django.test import SimpleTestCase
 
 from ..utils import render, setup
@@ -61,3 +62,14 @@ class LengthIsTests(SimpleTestCase):
     def test_length_is11(self):
         output = render('length_is11', {'none': None})
         self.assertEqual(output, '')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_empty_list(self):
+        self.assertEqual(length_is([], 0), True)
+        self.assertEqual(length_is([], 1), False)
+
+    def test_string(self):
+        self.assertEqual(length_is('a', 1), True)
+        self.assertEqual(length_is('a', 10), False)
diff --git a/tests/template_tests/filter_tests/test_linebreaks.py b/tests/template_tests/filter_tests/test_linebreaks.py
index 924fc0aefa..852617ba7f 100644
--- a/tests/template_tests/filter_tests/test_linebreaks.py
+++ b/tests/template_tests/filter_tests/test_linebreaks.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import linebreaks_filter
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -20,3 +21,21 @@ class LinebreaksTests(SimpleTestCase):
     def test_linebreaks02(self):
         output = render('linebreaks02', {"a": "x&\ny", "b": mark_safe("x&\ny")})
         self.assertEqual(output, "<p>x&<br />y</p> <p>x&<br />y</p>")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_line(self):
+        self.assertEqual(linebreaks_filter('line 1'), '<p>line 1</p>')
+
+    def test_newline(self):
+        self.assertEqual(linebreaks_filter('line 1\nline 2'), '<p>line 1<br />line 2</p>')
+
+    def test_carriage(self):
+        self.assertEqual(linebreaks_filter('line 1\rline 2'), '<p>line 1<br />line 2</p>')
+
+    def test_carriage_newline(self):
+        self.assertEqual(linebreaks_filter('line 1\r\nline 2'), '<p>line 1<br />line 2</p>')
+
+    def test_non_string_input(self):
+        self.assertEqual(linebreaks_filter(123), '<p>123</p>')
diff --git a/tests/template_tests/filter_tests/test_linebreaksbr.py b/tests/template_tests/filter_tests/test_linebreaksbr.py
index c65b0973fb..39905d7fb0 100644
--- a/tests/template_tests/filter_tests/test_linebreaksbr.py
+++ b/tests/template_tests/filter_tests/test_linebreaksbr.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import linebreaksbr
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -20,3 +21,18 @@ class LinebreaksbrTests(SimpleTestCase):
     def test_linebreaksbr02(self):
         output = render('linebreaksbr02', {"a": "x&\ny", "b": mark_safe("x&\ny")})
         self.assertEqual(output, "x&<br />y x&<br />y")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_newline(self):
+        self.assertEqual(linebreaksbr('line 1\nline 2'), 'line 1<br />line 2')
+
+    def test_carriage(self):
+        self.assertEqual(linebreaksbr('line 1\rline 2'), 'line 1<br />line 2')
+
+    def test_carriage_newline(self):
+        self.assertEqual(linebreaksbr('line 1\r\nline 2'), 'line 1<br />line 2')
+
+    def test_non_string_input(self):
+        self.assertEqual(linebreaksbr(123), '123')
diff --git a/tests/template_tests/filter_tests/test_linenumbers.py b/tests/template_tests/filter_tests/test_linenumbers.py
index d74ce5dcfe..d7e93d9429 100644
--- a/tests/template_tests/filter_tests/test_linenumbers.py
+++ b/tests/template_tests/filter_tests/test_linenumbers.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import linenumbers
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -28,3 +29,18 @@ class LinenumbersTests(SimpleTestCase):
         )
         self.assertEqual(output, '1. one\n2. <two>\n3. three '
                                  '1. one\n2. &lt;two&gt;\n3. three')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_linenumbers(self):
+        self.assertEqual(linenumbers('line 1\nline 2'), '1. line 1\n2. line 2')
+
+    def test_linenumbers2(self):
+        self.assertEqual(
+            linenumbers('\n'.join(['x'] * 10)),
+            '01. x\n02. x\n03. x\n04. x\n05. x\n06. x\n07. x\n08. x\n09. x\n10. x',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(linenumbers(123), '1. 123')
diff --git a/tests/template_tests/filter_tests/test_ljust.py b/tests/template_tests/filter_tests/test_ljust.py
index e5b0f84a8f..a13764d328 100644
--- a/tests/template_tests/filter_tests/test_ljust.py
+++ b/tests/template_tests/filter_tests/test_ljust.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import ljust
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,16 @@ class LjustTests(SimpleTestCase):
     def test_ljust02(self):
         output = render('ljust02', {"a": "a&b", "b": mark_safe("a&b")})
         self.assertEqual(output, ".a&amp;b  . .a&b  .")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_ljust(self):
+        self.assertEqual(ljust('test', 10), 'test      ')
+        self.assertEqual(ljust('test', 3), 'test')
+
+    def test_less_than_string_length(self):
+        self.assertEqual(ljust('test', 3), 'test')
+
+    def test_non_string_input(self):
+        self.assertEqual(ljust(123, 4), '123 ')
diff --git a/tests/template_tests/filter_tests/test_lower.py b/tests/template_tests/filter_tests/test_lower.py
index 1443386062..c6e792bc32 100644
--- a/tests/template_tests/filter_tests/test_lower.py
+++ b/tests/template_tests/filter_tests/test_lower.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import lower
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +19,16 @@ class LowerTests(SimpleTestCase):
     def test_lower02(self):
         output = render('lower02', {"a": "Apple & banana", "b": mark_safe("Apple &amp; banana")})
         self.assertEqual(output, "apple &amp; banana apple &amp; banana")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_lower(self):
+        self.assertEqual(lower('TEST'), 'test')
+
+    def test_unicode(self):
+        # uppercase E umlaut
+        self.assertEqual(lower('\xcb'), '\xeb')
+
+    def test_non_string_input(self):
+        self.assertEqual(lower(123), '123')
diff --git a/tests/template_tests/filter_tests/test_make_list.py b/tests/template_tests/filter_tests/test_make_list.py
index 42cfbfaf56..638893cafe 100644
--- a/tests/template_tests/filter_tests/test_make_list.py
+++ b/tests/template_tests/filter_tests/test_make_list.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import make_list
 from django.test import SimpleTestCase
 from django.test.utils import str_prefix
 from django.utils.safestring import mark_safe
@@ -31,3 +32,12 @@ class MakeListTests(SimpleTestCase):
     def test_make_list04(self):
         output = render('make_list04', {"a": mark_safe("&")})
         self.assertEqual(output, str_prefix("[%(_)s'&']"))
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_string(self):
+        self.assertEqual(make_list('abc'), ['a', 'b', 'c'])
+
+    def test_integer(self):
+        self.assertEqual(make_list(1234), ['1', '2', '3', '4'])
diff --git a/tests/template_tests/filter_tests/test_phone2numeric.py b/tests/template_tests/filter_tests/test_phone2numeric.py
index 8b899d70a3..d684ed9621 100644
--- a/tests/template_tests/filter_tests/test_phone2numeric.py
+++ b/tests/template_tests/filter_tests/test_phone2numeric.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import phone2numeric_filter
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -33,3 +34,9 @@ class Phone2numericTests(SimpleTestCase):
             output,
             '469 729672225-5867464 37647 226 53835 749 747833 49662787!'
         )
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_phone2numeric(self):
+        self.assertEqual(phone2numeric_filter('0800 flowers'), '0800 3569377')
diff --git a/tests/template_tests/filter_tests/test_pluralize.py b/tests/template_tests/filter_tests/test_pluralize.py
new file mode 100644
index 0000000000..16371da8be
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_pluralize.py
@@ -0,0 +1,35 @@
+from decimal import Decimal
+
+from django.template.defaultfilters import pluralize
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_integers(self):
+        self.assertEqual(pluralize(1), '')
+        self.assertEqual(pluralize(0), 's')
+        self.assertEqual(pluralize(2), 's')
+
+    def test_floats(self):
+        self.assertEqual(pluralize(0.5), 's')
+        self.assertEqual(pluralize(1.5), 's')
+
+    def test_decimals(self):
+        self.assertEqual(pluralize(Decimal(1)), '')
+        self.assertEqual(pluralize(Decimal(0)), 's')
+        self.assertEqual(pluralize(Decimal(2)), 's')
+
+    def test_lists(self):
+        self.assertEqual(pluralize([1]), '')
+        self.assertEqual(pluralize([]), 's')
+        self.assertEqual(pluralize([1, 2, 3]), 's')
+
+    def test_suffixes(self):
+        self.assertEqual(pluralize(1, 'es'), '')
+        self.assertEqual(pluralize(0, 'es'), 'es')
+        self.assertEqual(pluralize(2, 'es'), 'es')
+        self.assertEqual(pluralize(1, 'y,ies'), 'y')
+        self.assertEqual(pluralize(0, 'y,ies'), 'ies')
+        self.assertEqual(pluralize(2, 'y,ies'), 'ies')
+        self.assertEqual(pluralize(0, 'y,ies,error'), '')
diff --git a/tests/template_tests/filter_tests/test_removetags.py b/tests/template_tests/filter_tests/test_removetags.py
index 7abe810fd8..3e8842a48d 100644
--- a/tests/template_tests/filter_tests/test_removetags.py
+++ b/tests/template_tests/filter_tests/test_removetags.py
@@ -1,5 +1,6 @@
 import warnings
 
+from django.template.defaultfilters import removetags
 from django.test import SimpleTestCase
 from django.utils.deprecation import RemovedInDjango20Warning
 from django.utils.safestring import mark_safe
@@ -35,3 +36,22 @@ class RemovetagsTests(SimpleTestCase):
                 },
             )
         self.assertEqual(output, 'x <p>y</p> x <p>y</p>')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_removetags(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', RemovedInDjango20Warning)
+            self.assertEqual(
+                removetags(
+                    'some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags',
+                    'script img',
+                ),
+                'some <b>html</b> with alert("You smell") disallowed  tags',
+            )
+
+    def test_non_string_input(self):
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', RemovedInDjango20Warning)
+            self.assertEqual(removetags(123, 'a'), '123')
diff --git a/tests/template_tests/filter_tests/test_rjust.py b/tests/template_tests/filter_tests/test_rjust.py
index e20ce36706..38e8ba0e59 100644
--- a/tests/template_tests/filter_tests/test_rjust.py
+++ b/tests/template_tests/filter_tests/test_rjust.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import rjust
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,15 @@ class RjustTests(SimpleTestCase):
     def test_rjust02(self):
         output = render('rjust02', {"a": "a&b", "b": mark_safe("a&b")})
         self.assertEqual(output, ".  a&amp;b. .  a&b.")
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_rjust(self):
+        self.assertEqual(rjust('test', 10), '      test')
+
+    def test_less_than_string_length(self):
+        self.assertEqual(rjust('test', 3), 'test')
+
+    def test_non_string_input(self):
+        self.assertEqual(rjust(123, 4), ' 123')
diff --git a/tests/template_tests/filter_tests/test_slice.py b/tests/template_tests/filter_tests/test_slice.py
index c66f1f2241..5ceee207b3 100644
--- a/tests/template_tests/filter_tests/test_slice.py
+++ b/tests/template_tests/filter_tests/test_slice.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import slice_filter
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,24 @@ class SliceTests(SimpleTestCase):
     def test_slice02(self):
         output = render('slice02', {'a': 'a&b', 'b': mark_safe('a&b')})
         self.assertEqual(output, '&b &b')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_zero_length(self):
+        self.assertEqual(slice_filter('abcdefg', '0'), '')
+
+    def test_index(self):
+        self.assertEqual(slice_filter('abcdefg', '1'), 'a')
+
+    def test_negative_index(self):
+        self.assertEqual(slice_filter('abcdefg', '-1'), 'abcdef')
+
+    def test_range(self):
+        self.assertEqual(slice_filter('abcdefg', '1:2'), 'b')
+
+    def test_range_multiple(self):
+        self.assertEqual(slice_filter('abcdefg', '1:3'), 'bc')
+
+    def test_range_step(self):
+        self.assertEqual(slice_filter('abcdefg', '0::2'), 'aceg')
diff --git a/tests/template_tests/filter_tests/test_slugify.py b/tests/template_tests/filter_tests/test_slugify.py
index d18502b27c..7761547714 100644
--- a/tests/template_tests/filter_tests/test_slugify.py
+++ b/tests/template_tests/filter_tests/test_slugify.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import slugify
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -19,3 +23,21 @@ class SlugifyTests(SimpleTestCase):
     def test_slugify02(self):
         output = render('slugify02', {'a': 'a & b', 'b': mark_safe('a &amp; b')})
         self.assertEqual(output, 'a-b a-amp-b')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_slugify(self):
+        self.assertEqual(
+            slugify(' Jack & Jill like numbers 1,2,3 and 4 and silly characters ?%.$!/'),
+            'jack-jill-like-numbers-123-and-4-and-silly-characters',
+        )
+
+    def test_unicode(self):
+        self.assertEqual(
+            slugify("Un \xe9l\xe9phant \xe0 l'or\xe9e du bois"),
+            'un-elephant-a-loree-du-bois',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(slugify(123), '123')
diff --git a/tests/template_tests/filter_tests/test_stringformat.py b/tests/template_tests/filter_tests/test_stringformat.py
index ef762f2e0a..b353920354 100644
--- a/tests/template_tests/filter_tests/test_stringformat.py
+++ b/tests/template_tests/filter_tests/test_stringformat.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import stringformat
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -20,3 +21,12 @@ class StringformatTests(SimpleTestCase):
     def test_stringformat02(self):
         output = render('stringformat02', {'a': 'a<b', 'b': mark_safe('a<b')})
         self.assertEqual(output, '.  a&lt;b. .  a<b.')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_format(self):
+        self.assertEqual(stringformat(1, '03d'), '001')
+
+    def test_invalid(self):
+        self.assertEqual(stringformat(1, 'z'), '')
diff --git a/tests/template_tests/filter_tests/test_striptags.py b/tests/template_tests/filter_tests/test_striptags.py
index e2e60c2cab..f45a48cdde 100644
--- a/tests/template_tests/filter_tests/test_striptags.py
+++ b/tests/template_tests/filter_tests/test_striptags.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import striptags
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -27,3 +28,15 @@ class StriptagsTests(SimpleTestCase):
             },
         )
         self.assertEqual(output, 'x y x y')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_strip(self):
+        self.assertEqual(
+            striptags('some <b>html</b> with <script>alert("You smell")</script> disallowed <img /> tags'),
+            'some html with alert("You smell") disallowed  tags',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(striptags(123), '123')
diff --git a/tests/template_tests/filter_tests/test_time.py b/tests/template_tests/filter_tests/test_time.py
index a7fa5026cd..5f6373e4f6 100644
--- a/tests/template_tests/filter_tests/test_time.py
+++ b/tests/template_tests/filter_tests/test_time.py
@@ -1,5 +1,7 @@
 from datetime import time
 
+from django.template.defaultfilters import time as time_filter
+from django.test import SimpleTestCase
 from django.utils import timezone
 
 from .timezone_utils import TimezoneTestCase
@@ -40,3 +42,10 @@ class TimeTests(TimezoneTestCase):
     def test_time06(self):
         output = render('time06', {'obj': 'non-datetime-value'})
         self.assertEqual(output, '')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_inputs(self):
+        self.assertEqual(time_filter(time(13), 'h'), '01')
+        self.assertEqual(time_filter(time(0), 'h'), '12')
diff --git a/tests/template_tests/filter_tests/test_timesince.py b/tests/template_tests/filter_tests/test_timesince.py
index 999358a7f2..12349e6d50 100644
--- a/tests/template_tests/filter_tests/test_timesince.py
+++ b/tests/template_tests/filter_tests/test_timesince.py
@@ -2,6 +2,8 @@ from __future__ import unicode_literals
 
 from datetime import datetime, timedelta
 
+from django.template.defaultfilters import timesince_filter
+from django.test import SimpleTestCase
 from django.test.utils import requires_tz_support
 
 from .timezone_utils import TimezoneTestCase
@@ -116,3 +118,12 @@ class TimesinceTests(TimezoneTestCase):
     def test_timesince18(self):
         output = render('timesince18', {'a': self.today, 'b': self.today + timedelta(hours=24)})
         self.assertEqual(output, '1\xa0day')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_since_now(self):
+        self.assertEqual(timesince_filter(datetime.now() - timedelta(1)), '1\xa0day')
+
+    def test_explicit_date(self):
+        self.assertEqual(timesince_filter(datetime(2005, 12, 29), datetime(2005, 12, 30)), '1\xa0day')
diff --git a/tests/template_tests/filter_tests/test_timeuntil.py b/tests/template_tests/filter_tests/test_timeuntil.py
index 1662bb605c..a723b34e5e 100644
--- a/tests/template_tests/filter_tests/test_timeuntil.py
+++ b/tests/template_tests/filter_tests/test_timeuntil.py
@@ -2,6 +2,8 @@ from __future__ import unicode_literals
 
 from datetime import datetime, timedelta
 
+from django.template.defaultfilters import timeuntil_filter
+from django.test import SimpleTestCase
 from django.test.utils import requires_tz_support
 
 from .timezone_utils import TimezoneTestCase
@@ -92,3 +94,12 @@ class TimeuntilTests(TimezoneTestCase):
     def test_timeuntil14(self):
         output = render('timeuntil14', {'a': self.today, 'b': self.today - timedelta(hours=24)})
         self.assertEqual(output, '1\xa0day')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_until_now(self):
+        self.assertEqual(timeuntil_filter(datetime.now() + timedelta(1, 1)), '1\xa0day')
+
+    def test_explicit_date(self):
+        self.assertEqual(timeuntil_filter(datetime(2005, 12, 30), datetime(2005, 12, 29)), '1\xa0day')
diff --git a/tests/template_tests/filter_tests/test_title.py b/tests/template_tests/filter_tests/test_title.py
index fc14330b67..67aa910733 100644
--- a/tests/template_tests/filter_tests/test_title.py
+++ b/tests/template_tests/filter_tests/test_title.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import title
 from django.test import SimpleTestCase
 
 from ..utils import render, setup
@@ -14,3 +18,15 @@ class TitleTests(SimpleTestCase):
     def test_title2(self):
         output = render('title2', {'a': '555 WEST 53RD STREET'})
         self.assertEqual(output, '555 West 53rd Street')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_title(self):
+        self.assertEqual(title('a nice title, isn\'t it?'), "A Nice Title, Isn't It?")
+
+    def test_unicode(self):
+        self.assertEqual(title('discoth\xe8que'), 'Discoth\xe8que')
+
+    def test_non_string_input(self):
+        self.assertEqual(title(123), '123')
diff --git a/tests/template_tests/filter_tests/test_truncatechars_html.py b/tests/template_tests/filter_tests/test_truncatechars_html.py
new file mode 100644
index 0000000000..cf2623d740
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_truncatechars_html.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import truncatechars_html
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_truncate_zero(self):
+        self.assertEqual(truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 0), '...')
+
+    def test_truncate(self):
+        self.assertEqual(
+            truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 6),
+            '<p>one...</p>',
+        )
+
+    def test_truncate2(self):
+        self.assertEqual(
+            truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 11),
+            '<p>one <a href="#">two ...</a></p>',
+        )
+
+    def test_truncate3(self):
+        self.assertEqual(
+            truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 100),
+            '<p>one <a href="#">two - three <br>four</a> five</p>',
+        )
+
+    def test_truncate_unicode(self):
+        self.assertEqual(truncatechars_html('<b>\xc5ngstr\xf6m</b> was here', 5), '<b>\xc5n...</b>')
+
+    def test_truncate_something(self):
+        self.assertEqual(truncatechars_html('a<b>b</b>c', 3), 'a<b>b</b>c')
diff --git a/tests/template_tests/filter_tests/test_truncatewords.py b/tests/template_tests/filter_tests/test_truncatewords.py
index 6f64d439f3..f9a3647085 100644
--- a/tests/template_tests/filter_tests/test_truncatewords.py
+++ b/tests/template_tests/filter_tests/test_truncatewords.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import truncatewords
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -16,3 +17,30 @@ class TruncatewordsTests(SimpleTestCase):
     def test_truncatewords02(self):
         output = render('truncatewords02', {'a': 'alpha & bravo', 'b': mark_safe('alpha &amp; bravo')})
         self.assertEqual(output, 'alpha &amp; ... alpha &amp; ...')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_truncate(self):
+        self.assertEqual(truncatewords('A sentence with a few words in it', 1), 'A ...')
+
+    def test_truncate2(self):
+        self.assertEqual(
+            truncatewords('A sentence with a few words in it', 5),
+            'A sentence with a few ...',
+        )
+
+    def test_overtruncate(self):
+        self.assertEqual(
+            truncatewords('A sentence with a few words in it', 100),
+            'A sentence with a few words in it',
+        )
+
+    def test_invalid_number(self):
+        self.assertEqual(
+            truncatewords('A sentence with a few words in it', 'not a number'),
+            'A sentence with a few words in it',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(truncatewords(123, 2), '123')
diff --git a/tests/template_tests/filter_tests/test_truncatewords_html.py b/tests/template_tests/filter_tests/test_truncatewords_html.py
new file mode 100644
index 0000000000..aec2abf2d4
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_truncatewords_html.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import truncatewords_html
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_truncate_zero(self):
+        self.assertEqual(truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 0), '')
+
+    def test_truncate(self):
+        self.assertEqual(
+            truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 2),
+            '<p>one <a href="#">two ...</a></p>',
+        )
+
+    def test_truncate2(self):
+        self.assertEqual(
+            truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 4),
+            '<p>one <a href="#">two - three <br>four ...</a></p>',
+        )
+
+    def test_truncate3(self):
+        self.assertEqual(
+            truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 5),
+            '<p>one <a href="#">two - three <br>four</a> five</p>',
+        )
+
+    def test_truncate4(self):
+        self.assertEqual(
+            truncatewords_html('<p>one <a href="#">two - three <br>four</a> five</p>', 100),
+            '<p>one <a href="#">two - three <br>four</a> five</p>',
+        )
+
+    def test_truncate_unicode(self):
+        self.assertEqual(truncatewords_html('\xc5ngstr\xf6m was here', 1), '\xc5ngstr\xf6m ...')
+
+    def test_truncate_complex(self):
+        self.assertEqual(
+            truncatewords_html('<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo est&aacute;?</i>', 3),
+            '<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo ...</i>',
+        )
diff --git a/tests/template_tests/filter_tests/test_unordered_list.py b/tests/template_tests/filter_tests/test_unordered_list.py
index 73eee2fb34..8575551b08 100644
--- a/tests/template_tests/filter_tests/test_unordered_list.py
+++ b/tests/template_tests/filter_tests/test_unordered_list.py
@@ -1,7 +1,9 @@
 import warnings
 
+from django.template.defaultfilters import unordered_list
 from django.test import SimpleTestCase
 from django.utils.deprecation import RemovedInDjango20Warning
+from django.utils.encoding import python_2_unicode_compatible
 from django.utils.safestring import mark_safe
 
 from ..utils import render, setup
@@ -73,3 +75,83 @@ class DeprecatedUnorderedListSyntaxTests(SimpleTestCase):
             warnings.simplefilter('ignore', RemovedInDjango20Warning)
             output = render('unordered_list05', {'a': ['x>', [['<y', []]]]})
         self.assertEqual(output, '\t<li>x>\n\t<ul>\n\t\t<li><y</li>\n\t</ul>\n\t</li>')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_list(self):
+        self.assertEqual(unordered_list(['item 1', 'item 2']), '\t<li>item 1</li>\n\t<li>item 2</li>')
+
+    def test_nested(self):
+        self.assertEqual(
+            unordered_list(['item 1', ['item 1.1']]),
+            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>',
+        )
+
+    def test_nested2(self):
+        self.assertEqual(
+            unordered_list(['item 1', ['item 1.1', 'item1.2'], 'item 2']),
+            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t\t<li>item1.2'
+            '</li>\n\t</ul>\n\t</li>\n\t<li>item 2</li>',
+        )
+
+    def test_nested_multiple(self):
+        self.assertEqual(
+            unordered_list(['item 1', ['item 1.1', ['item 1.1.1', ['item 1.1.1.1']]]]),
+            '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1\n\t\t<ul>\n\t\t\t<li>'
+            'item 1.1.1\n\t\t\t<ul>\n\t\t\t\t<li>item 1.1.1.1</li>\n\t\t\t'
+            '</ul>\n\t\t\t</li>\n\t\t</ul>\n\t\t</li>\n\t</ul>\n\t</li>',
+        )
+
+    def test_nested_multiple2(self):
+        self.assertEqual(
+            unordered_list(['States', ['Kansas', ['Lawrence', 'Topeka'], 'Illinois']]),
+            '\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>'
+            'Lawrence</li>\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>'
+            '\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>',
+        )
+
+    def test_ulitem(self):
+        @python_2_unicode_compatible
+        class ULItem(object):
+            def __init__(self, title):
+                self.title = title
+
+            def __str__(self):
+                return 'ulitem-%s' % str(self.title)
+
+        a = ULItem('a')
+        b = ULItem('b')
+        self.assertEqual(unordered_list([a, b]), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
+
+        def item_generator():
+            yield a
+            yield b
+
+        self.assertEqual(unordered_list(item_generator()), '\t<li>ulitem-a</li>\n\t<li>ulitem-b</li>')
+
+    def test_legacy(self):
+        """
+        Old format for unordered lists should still work
+        """
+        with warnings.catch_warnings():
+            warnings.simplefilter('ignore', RemovedInDjango20Warning)
+
+            self.assertEqual(unordered_list(['item 1', []]), '\t<li>item 1</li>')
+
+            self.assertEqual(
+                unordered_list(['item 1', [['item 1.1', []]]]),
+                '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1</li>\n\t</ul>\n\t</li>',
+            )
+
+            self.assertEqual(
+                unordered_list(['item 1', [['item 1.1', []],
+                ['item 1.2', []]]]), '\t<li>item 1\n\t<ul>\n\t\t<li>item 1.1'
+                '</li>\n\t\t<li>item 1.2</li>\n\t</ul>\n\t</li>',
+            )
+
+            self.assertEqual(
+                unordered_list(['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]),
+                '\t<li>States\n\t<ul>\n\t\t<li>Kansas\n\t\t<ul>\n\t\t\t<li>Lawrence</li>'
+                '\n\t\t\t<li>Topeka</li>\n\t\t</ul>\n\t\t</li>\n\t\t<li>Illinois</li>\n\t</ul>\n\t</li>',
+            )
diff --git a/tests/template_tests/filter_tests/test_upper.py b/tests/template_tests/filter_tests/test_upper.py
index b1fa5fcc06..b1708ce524 100644
--- a/tests/template_tests/filter_tests/test_upper.py
+++ b/tests/template_tests/filter_tests/test_upper.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import upper
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -19,3 +23,16 @@ class UpperTests(SimpleTestCase):
     def test_upper02(self):
         output = render('upper02', {'a': 'a & b', 'b': mark_safe('a &amp; b')})
         self.assertEqual(output, 'A &amp; B A &amp;AMP; B')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_upper(self):
+        self.assertEqual(upper('Mixed case input'), 'MIXED CASE INPUT')
+
+    def test_unicode(self):
+        # lowercase e umlaut
+        self.assertEqual(upper('\xeb'), '\xcb')
+
+    def test_non_string_input(self):
+        self.assertEqual(upper(123), '123')
diff --git a/tests/template_tests/filter_tests/test_urlencode.py b/tests/template_tests/filter_tests/test_urlencode.py
index ea68188c15..eca2b3f405 100644
--- a/tests/template_tests/filter_tests/test_urlencode.py
+++ b/tests/template_tests/filter_tests/test_urlencode.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import urlencode
 from django.test import SimpleTestCase
 
 from ..utils import render, setup
@@ -14,3 +18,12 @@ class UrlencodeTests(SimpleTestCase):
     def test_urlencode02(self):
         output = render('urlencode02', {'urlbit': 'escape/slash'})
         self.assertEqual(output, '/test/escape%2Fslash/')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_urlencode(self):
+        self.assertEqual(urlencode('fran\xe7ois & jill'), 'fran%C3%A7ois%20%26%20jill')
+
+    def test_non_string_input(self):
+        self.assertEqual(urlencode(1), '1')
diff --git a/tests/template_tests/filter_tests/test_urlize.py b/tests/template_tests/filter_tests/test_urlize.py
index 567f38ee4b..ef23e5e5f0 100644
--- a/tests/template_tests/filter_tests/test_urlize.py
+++ b/tests/template_tests/filter_tests/test_urlize.py
@@ -1,3 +1,7 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.template.defaultfilters import urlize
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -68,3 +72,239 @@ class UrlizeTests(SimpleTestCase):
             output,
             'Email me at &lt;<a href="mailto:me@example.com">me@example.com</a>&gt;',
         )
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_urls(self):
+        self.assertEqual(
+            urlize('http://google.com'),
+            '<a href="http://google.com" rel="nofollow">http://google.com</a>',
+        )
+        self.assertEqual(
+            urlize('http://google.com/'),
+            '<a href="http://google.com/" rel="nofollow">http://google.com/</a>',
+        )
+        self.assertEqual(
+            urlize('www.google.com'),
+            '<a href="http://www.google.com" rel="nofollow">www.google.com</a>',
+        )
+        self.assertEqual(
+            urlize('djangoproject.org'),
+            '<a href="http://djangoproject.org" rel="nofollow">djangoproject.org</a>',
+        )
+        self.assertEqual(
+            urlize('djangoproject.org/'),
+            '<a href="http://djangoproject.org/" rel="nofollow">djangoproject.org/</a>',
+        )
+
+    def test_email(self):
+        self.assertEqual(
+            urlize('info@djangoproject.org'),
+            '<a href="mailto:info@djangoproject.org">info@djangoproject.org</a>',
+        )
+
+    def test_word_with_dot(self):
+        self.assertEqual(urlize('some.organization'), 'some.organization'),
+
+    def test_https(self):
+        self.assertEqual(
+            urlize('https://google.com'),
+            '<a href="https://google.com" rel="nofollow">https://google.com</a>',
+        )
+
+    def test_quoting(self):
+        """
+        #9655 - Check urlize doesn't overquote already quoted urls. The
+        teststring is the urlquoted version of 'http://hi.baidu.com/重新开始'
+        """
+        self.assertEqual(
+            urlize('http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B'),
+            '<a href="http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B" rel="nofollow">'
+            'http://hi.baidu.com/%E9%87%8D%E6%96%B0%E5%BC%80%E5%A7%8B</a>',
+        )
+
+    def test_urlencoded(self):
+        self.assertEqual(
+            urlize('www.mystore.com/30%OffCoupons!'),
+            '<a href="http://www.mystore.com/30%25OffCoupons" rel="nofollow">'
+            'www.mystore.com/30%OffCoupons</a>!',
+        )
+        self.assertEqual(
+            urlize('http://en.wikipedia.org/wiki/Caf%C3%A9'),
+            '<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">'
+            'http://en.wikipedia.org/wiki/Caf%C3%A9</a>',
+        )
+
+    def test_unicode(self):
+        self.assertEqual(
+            urlize('http://en.wikipedia.org/wiki/Café'),
+            '<a href="http://en.wikipedia.org/wiki/Caf%C3%A9" rel="nofollow">'
+            'http://en.wikipedia.org/wiki/Café</a>',
+        )
+
+    def test_parenthesis(self):
+        """
+        #11911 - Check urlize keeps balanced parentheses
+        """
+        self.assertEqual(
+            urlize('http://en.wikipedia.org/wiki/Django_(web_framework)'),
+            '<a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">'
+            'http://en.wikipedia.org/wiki/Django_(web_framework)</a>',
+        )
+        self.assertEqual(
+            urlize('(see http://en.wikipedia.org/wiki/Django_(web_framework))'),
+            '(see <a href="http://en.wikipedia.org/wiki/Django_(web_framework)" rel="nofollow">'
+            'http://en.wikipedia.org/wiki/Django_(web_framework)</a>)',
+        )
+
+    def test_nofollow(self):
+        """
+        #12183 - Check urlize adds nofollow properly - see #12183
+        """
+        self.assertEqual(
+            urlize('foo@bar.com or www.bar.com'),
+            '<a href="mailto:foo@bar.com">foo@bar.com</a> or '
+            '<a href="http://www.bar.com" rel="nofollow">www.bar.com</a>',
+        )
+
+    def test_idn(self):
+        """
+        #13704 - Check urlize handles IDN correctly
+        """
+        self.assertEqual(urlize('http://c✶.ws'), '<a href="http://xn--c-lgq.ws" rel="nofollow">http://c✶.ws</a>')
+        self.assertEqual(urlize('www.c✶.ws'), '<a href="http://www.xn--c-lgq.ws" rel="nofollow">www.c✶.ws</a>')
+        self.assertEqual(urlize('c✶.org'), '<a href="http://xn--c-lgq.org" rel="nofollow">c✶.org</a>')
+        self.assertEqual(urlize('info@c✶.org'), '<a href="mailto:info@xn--c-lgq.org">info@c✶.org</a>')
+
+    def test_malformed(self):
+        """
+        #16395 - Check urlize doesn't highlight malformed URIs
+        """
+        self.assertEqual(urlize('http:///www.google.com'), 'http:///www.google.com')
+        self.assertEqual(urlize('http://.google.com'), 'http://.google.com')
+        self.assertEqual(urlize('http://@foo.com'), 'http://@foo.com')
+
+    def test_tlds(self):
+        """
+        #16656 - Check urlize accepts more TLDs
+        """
+        self.assertEqual(urlize('usa.gov'), '<a href="http://usa.gov" rel="nofollow">usa.gov</a>')
+
+    def test_invalid_email(self):
+        """
+        #17592 - Check urlize don't crash on invalid email with dot-starting
+        domain
+        """
+        self.assertEqual(urlize('email@.stream.ru'), 'email@.stream.ru')
+
+    def test_uppercase(self):
+        """
+        #18071 - Check urlize accepts uppercased URL schemes
+        """
+        self.assertEqual(
+            urlize('HTTPS://github.com/'),
+            '<a href="https://github.com/" rel="nofollow">HTTPS://github.com/</a>',
+        )
+
+    def test_trailing_period(self):
+        """
+        #18644 - Check urlize trims trailing period when followed by parenthesis
+        """
+        self.assertEqual(
+            urlize('(Go to http://www.example.com/foo.)'),
+            '(Go to <a href="http://www.example.com/foo" rel="nofollow">http://www.example.com/foo</a>.)',
+        )
+
+    def test_brackets(self):
+        """
+        #19070 - Check urlize handles brackets properly
+        """
+        self.assertEqual(
+            urlize('[see www.example.com]'),
+            '[see <a href="http://www.example.com" rel="nofollow">www.example.com</a>]',
+        )
+        self.assertEqual(
+            urlize('see test[at[example.com'),
+            'see <a href="http://test[at[example.com" rel="nofollow">test[at[example.com</a>',
+        )
+        self.assertEqual(
+            urlize('[http://168.192.0.1](http://168.192.0.1)'),
+            '[<a href="http://168.192.0.1](http://168.192.0.1)" rel="nofollow">'
+            'http://168.192.0.1](http://168.192.0.1)</a>',
+        )
+
+    def test_ipv4(self):
+        self.assertEqual(
+            urlize('http://192.168.0.15/api/9'),
+            '<a href="http://192.168.0.15/api/9" rel="nofollow">http://192.168.0.15/api/9</a>',
+        )
+
+    def test_ipv6(self):
+        self.assertEqual(
+            urlize('http://[2001:db8:cafe::2]/api/9'),
+            '<a href="http://[2001:db8:cafe::2]/api/9" rel="nofollow">http://[2001:db8:cafe::2]/api/9</a>',
+        )
+
+    def test_quotation_marks(self):
+        """
+        #20364 - Check urlize correctly include quotation marks in links
+        """
+        self.assertEqual(
+            urlize('before "hi@example.com" afterwards'),
+            'before "<a href="mailto:hi@example.com">hi@example.com</a>" afterwards',
+        )
+        self.assertEqual(
+            urlize('before hi@example.com" afterwards'),
+            'before <a href="mailto:hi@example.com">hi@example.com</a>" afterwards',
+        )
+        self.assertEqual(
+            urlize('before "hi@example.com afterwards'),
+            'before "<a href="mailto:hi@example.com">hi@example.com</a> afterwards',
+        )
+        self.assertEqual(
+            urlize('before \'hi@example.com\' afterwards'),
+            'before \'<a href="mailto:hi@example.com">hi@example.com</a>\' afterwards',
+        )
+        self.assertEqual(
+            urlize('before hi@example.com\' afterwards'),
+            'before <a href="mailto:hi@example.com">hi@example.com</a>\' afterwards',
+        )
+        self.assertEqual(
+            urlize('before \'hi@example.com afterwards'),
+            'before \'<a href="mailto:hi@example.com">hi@example.com</a> afterwards',
+        )
+
+    def test_quote_commas(self):
+        """
+        #20364 - Check urlize copes with commas following URLs in quotes
+        """
+        self.assertEqual(
+            urlize('Email us at "hi@example.com", or phone us at +xx.yy'),
+            'Email us at "<a href="mailto:hi@example.com">hi@example.com</a>", or phone us at +xx.yy',
+        )
+
+    def test_exclamation_marks(self):
+        """
+        #23715 - Check urlize correctly handles exclamation marks after TLDs
+        or query string
+        """
+        self.assertEqual(
+            urlize('Go to djangoproject.com! and enjoy.'),
+            'Go to <a href="http://djangoproject.com" rel="nofollow">djangoproject.com</a>! and enjoy.',
+        )
+        self.assertEqual(
+            urlize('Search for google.com/?q=! and see.'),
+            'Search for <a href="http://google.com/?q=" rel="nofollow">google.com/?q=</a>! and see.',
+        )
+        self.assertEqual(
+            urlize('Search for google.com/?q=dj!`? and see.'),
+            'Search for <a href="http://google.com/?q=dj%21%60%3F" rel="nofollow">google.com/?q=dj!`?</a> and see.',
+        )
+        self.assertEqual(
+            urlize('Search for google.com/?q=dj!`?! and see.'),
+            'Search for <a href="http://google.com/?q=dj%21%60%3F" rel="nofollow">google.com/?q=dj!`?</a>! and see.',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(urlize(123), '123')
diff --git a/tests/template_tests/filter_tests/test_urlizetrunc.py b/tests/template_tests/filter_tests/test_urlizetrunc.py
index 19f5f1dcae..0190016372 100644
--- a/tests/template_tests/filter_tests/test_urlizetrunc.py
+++ b/tests/template_tests/filter_tests/test_urlizetrunc.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import urlizetrunc
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -36,3 +37,44 @@ class UrlizetruncTests(SimpleTestCase):
             '&quot;Unsafe&quot; <a href="http://example.com/x=&y=" rel="nofollow">http:...</a> '
             '&quot;Safe&quot; <a href="http://example.com?x=&y=" rel="nofollow">http:...</a>'
         )
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_truncate(self):
+        uri = 'http://31characteruri.com/test/'
+        self.assertEqual(len(uri), 31)
+
+        self.assertEqual(
+            urlizetrunc(uri, 31),
+            '<a href="http://31characteruri.com/test/" rel="nofollow">'
+            'http://31characteruri.com/test/</a>',
+        )
+
+        self.assertEqual(
+            urlizetrunc(uri, 30),
+            '<a href="http://31characteruri.com/test/" rel="nofollow">'
+            'http://31characteruri.com/t...</a>',
+        )
+
+        self.assertEqual(
+            urlizetrunc(uri, 2),
+            '<a href="http://31characteruri.com/test/"'
+            ' rel="nofollow">...</a>',
+        )
+
+    def test_overtruncate(self):
+        self.assertEqual(
+            urlizetrunc('http://short.com/', 20), '<a href='
+            '"http://short.com/" rel="nofollow">http://short.com/</a>',
+        )
+
+    def test_query_string(self):
+        self.assertEqual(
+            urlizetrunc('http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&meta=', 20),
+            '<a href="http://www.google.co.uk/search?hl=en&q=some+long+url&btnG=Search&'
+            'meta=" rel="nofollow">http://www.google...</a>',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(urlizetrunc(123, 1), '123')
diff --git a/tests/template_tests/filter_tests/test_wordcount.py b/tests/template_tests/filter_tests/test_wordcount.py
index 8c1e43f539..69a73b976a 100644
--- a/tests/template_tests/filter_tests/test_wordcount.py
+++ b/tests/template_tests/filter_tests/test_wordcount.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import wordcount
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -15,3 +16,18 @@ class WordcountTests(SimpleTestCase):
     def test_wordcount02(self):
         output = render('wordcount02', {'a': 'a & b', 'b': mark_safe('a &amp; b')})
         self.assertEqual(output, '3 3')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_empty_string(self):
+        self.assertEqual(wordcount(''), 0)
+
+    def test_count_one(self):
+        self.assertEqual(wordcount('oneword'), 1)
+
+    def test_count_multiple(self):
+        self.assertEqual(wordcount('lots of words'), 3)
+
+    def test_non_string_input(self):
+        self.assertEqual(wordcount(123), 1)
diff --git a/tests/template_tests/filter_tests/test_wordwrap.py b/tests/template_tests/filter_tests/test_wordwrap.py
index 7b6489ca0f..808d9ee7a0 100644
--- a/tests/template_tests/filter_tests/test_wordwrap.py
+++ b/tests/template_tests/filter_tests/test_wordwrap.py
@@ -1,3 +1,4 @@
+from django.template.defaultfilters import wordwrap
 from django.test import SimpleTestCase
 from django.utils.safestring import mark_safe
 
@@ -16,3 +17,27 @@ class WordwrapTests(SimpleTestCase):
     def test_wordwrap02(self):
         output = render('wordwrap02', {'a': 'a & b', 'b': mark_safe('a & b')})
         self.assertEqual(output, 'a &amp;\nb a &\nb')
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_wrap(self):
+        self.assertEqual(
+            wordwrap('this is a long paragraph of text that really needs to be wrapped I\'m afraid', 14),
+            'this is a long\nparagraph of\ntext that\nreally needs\nto be wrapped\nI\'m afraid',
+        )
+
+    def test_indent(self):
+        self.assertEqual(
+            wordwrap('this is a short paragraph of text.\n  But this line should be indented', 14),
+            'this is a\nshort\nparagraph of\ntext.\n  But this\nline should be\nindented',
+        )
+
+    def test_indent2(self):
+        self.assertEqual(
+            wordwrap('this is a short paragraph of text.\n  But this line should be indented', 15),
+            'this is a short\nparagraph of\ntext.\n  But this line\nshould be\nindented',
+        )
+
+    def test_non_string_input(self):
+        self.assertEqual(wordwrap(123, 2), '123')
diff --git a/tests/template_tests/filter_tests/test_yesno.py b/tests/template_tests/filter_tests/test_yesno.py
new file mode 100644
index 0000000000..43ea447caa
--- /dev/null
+++ b/tests/template_tests/filter_tests/test_yesno.py
@@ -0,0 +1,26 @@
+from django.template.defaultfilters import yesno
+from django.test import SimpleTestCase
+
+
+class FunctionTests(SimpleTestCase):
+
+    def test_true(self):
+        self.assertEqual(yesno(True), 'yes')
+
+    def test_false(self):
+        self.assertEqual(yesno(False), 'no')
+
+    def test_none(self):
+        self.assertEqual(yesno(None), 'maybe')
+
+    def test_true_arguments(self):
+        self.assertEqual(yesno(True, 'certainly,get out of town,perhaps'), 'certainly')
+
+    def test_false_arguments(self):
+        self.assertEqual(yesno(False, 'certainly,get out of town,perhaps'), 'get out of town')
+
+    def test_none_two_arguments(self):
+        self.assertEqual(yesno(None, 'certainly,get out of town'), 'get out of town')
+
+    def test_none_three_arguments(self):
+        self.assertEqual(yesno(None, 'certainly,get out of town,perhaps'), 'perhaps')