diff --git a/tests/regressiontests/utils/checksums.py b/tests/regressiontests/utils/checksums.py new file mode 100644 index 0000000000..bb73576a80 --- /dev/null +++ b/tests/regressiontests/utils/checksums.py @@ -0,0 +1,29 @@ +from django.test import TestCase + +from django.utils import checksums + +class TestUtilsChecksums(TestCase): + + def check_output(self, function, value, output=None): + """ + Check that function(value) equals output. If output is None, + check that function(value) equals value. + """ + if output is None: + output = value + self.assertEqual(function(value), output) + + def test_luhn(self): + f = checksums.luhn + items = ( + (4111111111111111, True), ('4111111111111111', True), + (4222222222222, True), (378734493671000, True), + (5424000000000015, True), (5555555555554444, True), + (1008, True), ('0000001008', True), ('000000001008', True), + (4012888888881881, True), (1234567890123456789012345678909, True), + (4111111111211111, False), (42222222222224, False), + (100, False), ('100', False), ('0000100', False), + ('abc', False), (None, False), (object(), False), + ) + for value, output in items: + self.check_output(f, value, output) diff --git a/tests/regressiontests/utils/html.py b/tests/regressiontests/utils/html.py new file mode 100644 index 0000000000..61ca6f4c53 --- /dev/null +++ b/tests/regressiontests/utils/html.py @@ -0,0 +1,111 @@ +from django.test import TestCase + +from django.utils import html + +class TestUtilsHtml(TestCase): + + def check_output(self, function, value, output=None): + """ + Check that function(value) equals output. If output is None, + check that function(value) equals value. + """ + if output is None: + output = value + self.assertEqual(function(value), output) + + def test_escape(self): + f = html.escape + items = ( + ('&','&'), + ('<', '<'), + ('>', '>'), + ('"', '"'), + ("'", '''), + ) + # Substitution patterns for testing the above items. + patterns = ("%s", "asdf%sfdsa", "%s1", "1%sb") + for value, output in items: + for pattern in patterns: + self.check_output(f, pattern % value, pattern % output) + # Check repeated values. + self.check_output(f, value * 2, output * 2) + # Verify it doesn't double replace &. + self.check_output(f, '<&', '<&') + + def test_linebreaks(self): + f = html.linebreaks + items = ( + ("para1\n\npara2\r\rpara3", "
para1
\n\npara2
\n\npara3
"), + ("para1\nsub1\rsub2\n\npara2", "para1
sub1
sub2
para2
"), + ("para1\r\n\r\npara2\rsub1\r\rpara4", "para1
\n\npara2
sub1
para4
"), + ("para1\tmore\n\npara2", "para1\tmore
\n\npara2
"), + ) + for value, output in items: + self.check_output(f, value, output) + + def test_strip_tags(self): + f = html.strip_tags + items = ( + ('hello
\nworld
', 'hello
world
'), + ('\n\t
\n\n', '\n\n'), + ) + for value, output in items: + self.check_output(f, value, output) + + def test_strip_entities(self): + f = html.strip_entities + # Strings that should come out untouched. + values = ("&", "&a", "&a", "aa") + for value in values: + self.check_output(f, value) + # Valid entities that should be stripped from the patterns. + entities = ("", "", "&a;", "&fdasdfasdfasdf;") + patterns = ( + ("asdf %(entity)s ", "asdf "), + ("%(entity)s%(entity)s", ""), + ("&%(entity)s%(entity)s", "&"), + ("%(entity)s3", "3"), + ) + for entity in entities: + for in_pattern, output in patterns: + self.check_output(f, in_pattern % {'entity': entity}, output) + + def test_fix_ampersands(self): + f = html.fix_ampersands + # Strings without ampersands or with ampersands already encoded. + values = ("a", "b", "&a;", "& &x; ", "asdf") + patterns = ( + ("%s", "%s"), + ("&%s", "&%s"), + ("&%s&", "&%s&"), + ) + for value in values: + for in_pattern, out_pattern in patterns: + self.check_output(f, in_pattern % value, out_pattern % value) + # Strings with ampersands that need encoding. + items = ( + ("", "&#;"), + ("ͫ ;", "ͫ ;"), + ("abc;", "abc;"), + ) + for value, output in items: + self.check_output(f, value, output) diff --git a/tests/regressiontests/utils/simplelazyobject.py b/tests/regressiontests/utils/simplelazyobject.py new file mode 100644 index 0000000000..1df55aa885 --- /dev/null +++ b/tests/regressiontests/utils/simplelazyobject.py @@ -0,0 +1,77 @@ +from django.test import TestCase + +from django.utils.functional import SimpleLazyObject + +class _ComplexObject(object): + def __init__(self, name): + self.name = name + + def __eq__(self, other): + return self.name == other.name + + def __hash__(self): + return hash(self.name) + + def __str__(self): + return "I am _ComplexObject(%r)" % self.name + + def __unicode__(self): + return unicode(self.name) + + def __repr__(self): + return "_ComplexObject(%r)" % self.name + +complex_object = lambda: _ComplexObject("joe") + +class TestUtilsSimpleLazyObject(TestCase): + """ + Tests for SimpleLazyObject + """ + # Note that concrete use cases for SimpleLazyObject are also found in the + # auth context processor tests (unless the implementation of that function + # is changed). + + def test_equality(self): + self.assertEqual(complex_object(), SimpleLazyObject(complex_object)) + self.assertEqual(SimpleLazyObject(complex_object), complex_object()) + + def test_hash(self): + # hash() equality would not be true for many objects, but it should be + # for _ComplexObject + self.assertEqual(hash(complex_object()), + hash(SimpleLazyObject(complex_object))) + + def test_repr(self): + # For debugging, it will really confuse things if there is no clue that + # SimpleLazyObject is actually a proxy object. So we don't + # proxy __repr__ + self.assert_("SimpleLazyObject" in repr(SimpleLazyObject(complex_object))) + + def test_str(self): + self.assertEqual("I am _ComplexObject('joe')", str(SimpleLazyObject(complex_object))) + + def test_unicode(self): + self.assertEqual(u"joe", unicode(SimpleLazyObject(complex_object))) + + def test_class(self): + # This is important for classes that use __class__ in things like + # equality tests. + self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) + + def test_deepcopy(self): + import django.utils.copycompat as copy + # Check that we *can* do deep copy, and that it returns the right + # objects. + + # First, for an unevaluated SimpleLazyObject + s = SimpleLazyObject(complex_object) + assert s._wrapped is None + s2 = copy.deepcopy(s) + assert s._wrapped is None # something has gone wrong is s is evaluated + self.assertEqual(s2, complex_object()) + + # Second, for an evaluated SimpleLazyObject + name = s.name # evaluate + assert s._wrapped is not None + s3 = copy.deepcopy(s) + self.assertEqual(s3, complex_object()) diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py index cfefc6139a..05a3253b9c 100644 --- a/tests/regressiontests/utils/tests.py +++ b/tests/regressiontests/utils/tests.py @@ -2,258 +2,14 @@ Tests for django.utils. """ -from unittest import TestCase - -from django.utils import html, checksums, text -from django.utils.functional import SimpleLazyObject - -import timesince -import datastructures -import datetime_safe -import tzinfo - -from decorators import DecoratorFromMiddlewareTests -from functional import FunctionalTestCase - -# Extra tests -__test__ = { - 'timesince': timesince, - 'datastructures': datastructures, - 'datetime_safe': datetime_safe, - 'tzinfo': tzinfo, -} - from dateformat import * from feedgenerator import * from module_loading import * from termcolors import * +from html import * +from checksums import * +from text import * +from simplelazyobject import * +from decorators import * +from functional import * -class TestUtilsHtml(TestCase): - - def check_output(self, function, value, output=None): - """ - Check that function(value) equals output. If output is None, - check that function(value) equals value. - """ - if output is None: - output = value - self.assertEqual(function(value), output) - - def test_escape(self): - f = html.escape - items = ( - ('&','&'), - ('<', '<'), - ('>', '>'), - ('"', '"'), - ("'", '''), - ) - # Substitution patterns for testing the above items. - patterns = ("%s", "asdf%sfdsa", "%s1", "1%sb") - for value, output in items: - for pattern in patterns: - self.check_output(f, pattern % value, pattern % output) - # Check repeated values. - self.check_output(f, value * 2, output * 2) - # Verify it doesn't double replace &. - self.check_output(f, '<&', '<&') - - def test_linebreaks(self): - f = html.linebreaks - items = ( - ("para1\n\npara2\r\rpara3", "
para1
\n\npara2
\n\npara3
"), - ("para1\nsub1\rsub2\n\npara2", "para1
sub1
sub2
para2
"), - ("para1\r\n\r\npara2\rsub1\r\rpara4", "para1
\n\npara2
sub1
para4
"), - ("para1\tmore\n\npara2", "para1\tmore
\n\npara2
"), - ) - for value, output in items: - self.check_output(f, value, output) - - def test_strip_tags(self): - f = html.strip_tags - items = ( - ('hello
\nworld
', 'hello
world
'), - ('\n\t
\n\n', '\n\n'), - ) - for value, output in items: - self.check_output(f, value, output) - - def test_strip_entities(self): - f = html.strip_entities - # Strings that should come out untouched. - values = ("&", "&a", "&a", "aa") - for value in values: - self.check_output(f, value) - # Valid entities that should be stripped from the patterns. - entities = ("", "", "&a;", "&fdasdfasdfasdf;") - patterns = ( - ("asdf %(entity)s ", "asdf "), - ("%(entity)s%(entity)s", ""), - ("&%(entity)s%(entity)s", "&"), - ("%(entity)s3", "3"), - ) - for entity in entities: - for in_pattern, output in patterns: - self.check_output(f, in_pattern % {'entity': entity}, output) - - def test_fix_ampersands(self): - f = html.fix_ampersands - # Strings without ampersands or with ampersands already encoded. - values = ("a", "b", "&a;", "& &x; ", "asdf") - patterns = ( - ("%s", "%s"), - ("&%s", "&%s"), - ("&%s&", "&%s&"), - ) - for value in values: - for in_pattern, out_pattern in patterns: - self.check_output(f, in_pattern % value, out_pattern % value) - # Strings with ampersands that need encoding. - items = ( - ("", "&#;"), - ("ͫ ;", "ͫ ;"), - ("abc;", "abc;"), - ) - for value, output in items: - self.check_output(f, value, output) - -class TestUtilsChecksums(TestCase): - - def check_output(self, function, value, output=None): - """ - Check that function(value) equals output. If output is None, - check that function(value) equals value. - """ - if output is None: - output = value - self.assertEqual(function(value), output) - - def test_luhn(self): - f = checksums.luhn - items = ( - (4111111111111111, True), ('4111111111111111', True), - (4222222222222, True), (378734493671000, True), - (5424000000000015, True), (5555555555554444, True), - (1008, True), ('0000001008', True), ('000000001008', True), - (4012888888881881, True), (1234567890123456789012345678909, True), - (4111111111211111, False), (42222222222224, False), - (100, False), ('100', False), ('0000100', False), - ('abc', False), (None, False), (object(), False), - ) - for value, output in items: - self.check_output(f, value, output) - -class _ComplexObject(object): - def __init__(self, name): - self.name = name - - def __eq__(self, other): - return self.name == other.name - - def __hash__(self): - return hash(self.name) - - def __str__(self): - return "I am _ComplexObject(%r)" % self.name - - def __unicode__(self): - return unicode(self.name) - - def __repr__(self): - return "_ComplexObject(%r)" % self.name - -complex_object = lambda: _ComplexObject("joe") - -class TestUtilsSimpleLazyObject(TestCase): - """ - Tests for SimpleLazyObject - """ - # Note that concrete use cases for SimpleLazyObject are also found in the - # auth context processor tests (unless the implementation of that function - # is changed). - - def test_equality(self): - self.assertEqual(complex_object(), SimpleLazyObject(complex_object)) - self.assertEqual(SimpleLazyObject(complex_object), complex_object()) - - def test_hash(self): - # hash() equality would not be true for many objects, but it should be - # for _ComplexObject - self.assertEqual(hash(complex_object()), - hash(SimpleLazyObject(complex_object))) - - def test_repr(self): - # For debugging, it will really confuse things if there is no clue that - # SimpleLazyObject is actually a proxy object. So we don't - # proxy __repr__ - self.assert_("SimpleLazyObject" in repr(SimpleLazyObject(complex_object))) - - def test_str(self): - self.assertEqual("I am _ComplexObject('joe')", str(SimpleLazyObject(complex_object))) - - def test_unicode(self): - self.assertEqual(u"joe", unicode(SimpleLazyObject(complex_object))) - - def test_class(self): - # This is important for classes that use __class__ in things like - # equality tests. - self.assertEqual(_ComplexObject, SimpleLazyObject(complex_object).__class__) - - def test_deepcopy(self): - import django.utils.copycompat as copy - # Check that we *can* do deep copy, and that it returns the right - # objects. - - # First, for an unevaluated SimpleLazyObject - s = SimpleLazyObject(complex_object) - assert s._wrapped is None - s2 = copy.deepcopy(s) - assert s._wrapped is None # something has gone wrong is s is evaluated - self.assertEqual(s2, complex_object()) - - # Second, for an evaluated SimpleLazyObject - name = s.name # evaluate - assert s._wrapped is not None - s3 = copy.deepcopy(s) - self.assertEqual(s3, complex_object()) - -class TestUtilsText(TestCase): - - def test_truncate_words(self): - self.assertEqual(u'The quick brown fox jumped over the lazy dog.', - text.truncate_words(u'The quick brown fox jumped over the lazy dog.', 10)) - self.assertEqual(u'The quick brown fox ...', - text.truncate_words('The quick brown fox jumped over the lazy dog.', 4)) - self.assertEqual(u'The quick brown fox ....', - text.truncate_words('The quick brown fox jumped over the lazy dog.', 4, '....')) - self.assertEqual(u'
The quick brown fox jumped over the lazy dog.
', - text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 10)) - self.assertEqual(u'The quick brown fox ...
', - text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4)) - self.assertEqual(u'The quick brown fox ....
', - text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4, '....')) - self.assertEqual(u'The quick brown fox
', - text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4, None)) - -if __name__ == "__main__": - import doctest - doctest.testmod() diff --git a/tests/regressiontests/utils/text.py b/tests/regressiontests/utils/text.py new file mode 100644 index 0000000000..7cf52ca92c --- /dev/null +++ b/tests/regressiontests/utils/text.py @@ -0,0 +1,20 @@ +from django.test import TestCase + +from django.utils import text + +class TestUtilsText(TestCase): + def test_truncate_words(self): + self.assertEqual(u'The quick brown fox jumped over the lazy dog.', + text.truncate_words(u'The quick brown fox jumped over the lazy dog.', 10)) + self.assertEqual(u'The quick brown fox ...', + text.truncate_words('The quick brown fox jumped over the lazy dog.', 4)) + self.assertEqual(u'The quick brown fox ....', + text.truncate_words('The quick brown fox jumped over the lazy dog.', 4, '....')) + self.assertEqual(u'The quick brown fox jumped over the lazy dog.
', + text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 10)) + self.assertEqual(u'The quick brown fox ...
', + text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4)) + self.assertEqual(u'The quick brown fox ....
', + text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4, '....')) + self.assertEqual(u'The quick brown fox
', + text.truncate_html_words('The quick brown fox jumped over the lazy dog.
', 4, None))