Fixed #29654 -- Made text truncation an ellipsis character instead of three dots.

Thanks Sudhanshu Mishra for the initial patch and Tim Graham for the review.
This commit is contained in:
Claude Paroz 2018-08-21 15:28:51 +02:00
parent 939dcff24f
commit 201017df30
14 changed files with 65 additions and 60 deletions

View file

@ -346,7 +346,7 @@ class MigrateTests(MigrationTestBase):
self.assertEqual(
'Planned operations:\n'
'migrations.0004_fourth\n'
' Raw SQL operation -> SELECT * FROM migrations_author W...\n',
' Raw SQL operation -> SELECT * FROM migrations_author WHE…\n',
out.getvalue()
)
# Migrate to the fourth migration.

View file

@ -5,10 +5,10 @@ from ..utils import setup
class TruncatecharsTests(SimpleTestCase):
@setup({'truncatechars01': '{{ a|truncatechars:5 }}'})
@setup({'truncatechars01': '{{ a|truncatechars:3 }}'})
def test_truncatechars01(self):
output = self.engine.render_to_string('truncatechars01', {'a': 'Testing, testing'})
self.assertEqual(output, 'Te...')
self.assertEqual(output, 'Te')
@setup({'truncatechars02': '{{ a|truncatechars:7 }}'})
def test_truncatechars02(self):

View file

@ -5,18 +5,18 @@ 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), '...')
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>',
truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 4),
'<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>',
truncatechars_html('<p>one <a href="#">two - three <br>four</a> five</p>', 9),
'<p>one <a href="#">two </a></p>',
)
def test_truncate3(self):
@ -26,7 +26,7 @@ class FunctionTests(SimpleTestCase):
)
def test_truncate_unicode(self):
self.assertEqual(truncatechars_html('<b>\xc5ngstr\xf6m</b> was here', 5), '<b>\xc5n...</b>')
self.assertEqual(truncatechars_html('<b>\xc5ngstr\xf6m</b> was here', 3), '<b>\xc5n…</b>')
def test_truncate_something(self):
self.assertEqual(truncatechars_html('a<b>b</b>c', 3), 'a<b>b</b>c')

View file

@ -14,25 +14,25 @@ class TruncatewordsTests(SimpleTestCase):
output = self.engine.render_to_string(
'truncatewords01', {'a': 'alpha & bravo', 'b': mark_safe('alpha &amp; bravo')}
)
self.assertEqual(output, 'alpha & ... alpha &amp; ...')
self.assertEqual(output, 'alpha & … alpha &amp; …')
@setup({'truncatewords02': '{{ a|truncatewords:"2" }} {{ b|truncatewords:"2"}}'})
def test_truncatewords02(self):
output = self.engine.render_to_string(
'truncatewords02', {'a': 'alpha & bravo', 'b': mark_safe('alpha &amp; bravo')}
)
self.assertEqual(output, 'alpha &amp; ... alpha &amp; ...')
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 ...')
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 ...',
'A sentence with a few ',
)
def test_overtruncate(self):

View file

@ -10,13 +10,13 @@ class FunctionTests(SimpleTestCase):
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>',
'<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>',
'<p>one <a href="#">two - three <br>four </a></p>',
)
def test_truncate3(self):
@ -32,12 +32,12 @@ class FunctionTests(SimpleTestCase):
)
def test_truncate_unicode(self):
self.assertEqual(truncatewords_html('\xc5ngstr\xf6m was here', 1), '\xc5ngstr\xf6m ...')
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>',
'<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo </i>',
)
def test_invalid_arg(self):

View file

@ -20,8 +20,8 @@ class UrlizetruncTests(SimpleTestCase):
)
self.assertEqual(
output,
'"Unsafe" <a href="http://example.com/x=&amp;y=" rel="nofollow">http:...</a> '
'&quot;Safe&quot; <a href="http://example.com?x=&amp;y=" rel="nofollow">http:...</a>'
'"Unsafe" <a href="http://example.com/x=&amp;y=" rel="nofollow">http://…</a> '
'&quot;Safe&quot; <a href="http://example.com?x=&amp;y=" rel="nofollow">http://…</a>'
)
@setup({'urlizetrunc02': '{{ a|urlizetrunc:"8" }} {{ b|urlizetrunc:"8" }}'})
@ -35,8 +35,8 @@ class UrlizetruncTests(SimpleTestCase):
)
self.assertEqual(
output,
'&quot;Unsafe&quot; <a href="http://example.com/x=&amp;y=" rel="nofollow">http:...</a> '
'&quot;Safe&quot; <a href="http://example.com?x=&amp;y=" rel="nofollow">http:...</a>'
'&quot;Unsafe&quot; <a href="http://example.com/x=&amp;y=" rel="nofollow">http://…</a> '
'&quot;Safe&quot; <a href="http://example.com?x=&amp;y=" rel="nofollow">http://…</a>'
)
@ -55,13 +55,13 @@ class FunctionTests(SimpleTestCase):
self.assertEqual(
urlizetrunc(uri, 30),
'<a href="http://31characteruri.com/test/" rel="nofollow">'
'http://31characteruri.com/t...</a>',
'http://31characteruri.com/tes…</a>',
)
self.assertEqual(
urlizetrunc(uri, 2),
urlizetrunc(uri, 1),
'<a href="http://31characteruri.com/test/"'
' rel="nofollow">...</a>',
' rel="nofollow"></a>',
)
def test_overtruncate(self):
@ -74,7 +74,7 @@ class FunctionTests(SimpleTestCase):
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&amp;q=some+long+url&amp;btnG=Search&amp;'
'meta=" rel="nofollow">http://www.google...</a>',
'meta=" rel="nofollow">http://www.google.c…</a>',
)
def test_non_string_input(self):
@ -89,5 +89,5 @@ class FunctionTests(SimpleTestCase):
def test_autoescape_off(self):
self.assertEqual(
urlizetrunc('foo<a href=" google.com ">bar</a>buz', 9, autoescape=False),
'foo<a href=" <a href="http://google.com" rel="nofollow">google...</a> ">bar</a>buz',
'foo<a href=" <a href="http://google.com" rel="nofollow">google.c…</a> ">bar</a>buz',
)

View file

@ -168,7 +168,7 @@ class FilterSyntaxTests(SimpleTestCase):
Numbers as filter arguments should work
"""
output = self.engine.render_to_string('filter-syntax19', {"var": "hello world"})
self.assertEqual(output, "hello ...")
self.assertEqual(output, "hello ")
@setup({'filter-syntax20': '{{ ""|default_if_none:"was none" }}'})
def test_filter_syntax20(self):

View file

@ -56,22 +56,22 @@ class TestUtilsText(SimpleTestCase):
def test_truncate_chars(self):
truncator = text.Truncator('The quick brown fox jumped over the lazy dog.')
self.assertEqual('The quick brown fox jumped over the lazy dog.', truncator.chars(100)),
self.assertEqual('The quick brown fox ...', truncator.chars(23)),
self.assertEqual('The quick brown fox ', truncator.chars(21)),
self.assertEqual('The quick brown fo.....', truncator.chars(23, '.....')),
nfc = text.Truncator('o\xfco\xfco\xfco\xfc')
nfd = text.Truncator('ou\u0308ou\u0308ou\u0308ou\u0308')
self.assertEqual('oüoüoüoü', nfc.chars(8))
self.assertEqual('oüoüoüoü', nfd.chars(8))
self.assertEqual('...', nfc.chars(5))
self.assertEqual('...', nfd.chars(5))
self.assertEqual('', nfc.chars(3))
self.assertEqual('', nfd.chars(3))
# Ensure the final length is calculated correctly when there are
# combining characters with no precomposed form, and that combining
# characters are not split up.
truncator = text.Truncator('-B\u030AB\u030A----8')
self.assertEqual('-B\u030A...', truncator.chars(5))
self.assertEqual('-B\u030AB\u030A-...', truncator.chars(7))
self.assertEqual('-B\u030A', truncator.chars(3))
self.assertEqual('-B\u030AB\u030A-', truncator.chars(5))
self.assertEqual('-B\u030AB\u030A----8', truncator.chars(8))
# Ensure the length of the end text is correctly calculated when it
@ -82,18 +82,18 @@ class TestUtilsText(SimpleTestCase):
# Make a best effort to shorten to the desired length, but requesting
# a length shorter than the ellipsis shouldn't break
self.assertEqual('...', text.Truncator('asdf').chars(1))
self.assertEqual('', text.Truncator('asdf').chars(0))
# lazy strings are handled correctly
self.assertEqual(text.Truncator(lazystr('The quick brown fox')).chars(12), 'The quick...')
self.assertEqual(text.Truncator(lazystr('The quick brown fox')).chars(10), 'The quick…')
def test_truncate_words(self):
truncator = text.Truncator('The quick brown fox jumped over the lazy dog.')
self.assertEqual('The quick brown fox jumped over the lazy dog.', truncator.words(10))
self.assertEqual('The quick brown fox...', truncator.words(4))
self.assertEqual('The quick brown fox', truncator.words(4))
self.assertEqual('The quick brown fox[snip]', truncator.words(4, '[snip]'))
# lazy strings are handled correctly
truncator = text.Truncator(lazystr('The quick brown fox jumped over the lazy dog.'))
self.assertEqual('The quick brown fox...', truncator.words(4))
self.assertEqual('The quick brown fox', truncator.words(4))
def test_truncate_html_words(self):
truncator = text.Truncator(
@ -104,7 +104,7 @@ class TestUtilsText(SimpleTestCase):
truncator.words(10, html=True)
)
self.assertEqual(
'<p id="par"><strong><em>The quick brown fox...</em></strong></p>',
'<p id="par"><strong><em>The quick brown fox</em></strong></p>',
truncator.words(4, html=True)
)
self.assertEqual(
@ -121,21 +121,21 @@ class TestUtilsText(SimpleTestCase):
'<p>The quick <a href="xyz.html"\n id="mylink">brown fox</a> jumped over the lazy dog.</p>'
)
self.assertEqual(
'<p>The quick <a href="xyz.html"\n id="mylink">brown...</a></p>',
truncator.words(3, '...', html=True)
'<p>The quick <a href="xyz.html"\n id="mylink">brown</a></p>',
truncator.words(3, html=True)
)
# Test self-closing tags
truncator = text.Truncator('<br/>The <hr />quick brown fox jumped over the lazy dog.')
self.assertEqual('<br/>The <hr />quick brown...', truncator.words(3, '...', html=True))
self.assertEqual('<br/>The <hr />quick brown', truncator.words(3, html=True))
truncator = text.Truncator('<br>The <hr/>quick <em>brown fox</em> jumped over the lazy dog.')
self.assertEqual('<br>The <hr/>quick <em>brown...</em>', truncator.words(3, '...', html=True))
self.assertEqual('<br>The <hr/>quick <em>brown</em>', truncator.words(3, html=True))
# Test html entities
truncator = text.Truncator('<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo est&aacute;?</i>')
self.assertEqual('<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo...</i>', truncator.words(3, '...', html=True))
self.assertEqual('<i>Buenos d&iacute;as! &#x00bf;C&oacute;mo</i>', truncator.words(3, html=True))
truncator = text.Truncator('<p>I &lt;3 python, what about you?</p>')
self.assertEqual('<p>I &lt;3 python...</p>', truncator.words(3, '...', html=True))
self.assertEqual('<p>I &lt;3 python</p>', truncator.words(3, html=True))
re_tag_catastrophic_test = ('</a' + '\t' * 50000) + '//>'
truncator = text.Truncator(re_tag_catastrophic_test)