1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
"""Tests for Terminal.wrap()"""
# coding: utf-8
# std imports
import textwrap
# 3rd party
import pytest
# local
from .accessories import TestTerminal, as_subprocess
from .conftest import TEST_QUICK
TEXTWRAP_KEYWORD_COMBINATIONS = [
{'break_long_words': False, 'drop_whitespace': False, 'subsequent_indent': ''},
{'break_long_words': False, 'drop_whitespace': True, 'subsequent_indent': ''},
{'break_long_words': False, 'drop_whitespace': False, 'subsequent_indent': ' '},
{'break_long_words': False, 'drop_whitespace': True, 'subsequent_indent': ' '},
{'break_long_words': True, 'drop_whitespace': False, 'subsequent_indent': ''},
{'break_long_words': True, 'drop_whitespace': True, 'subsequent_indent': ''},
{'break_long_words': True, 'drop_whitespace': False, 'subsequent_indent': ' '},
{'break_long_words': True, 'drop_whitespace': True, 'subsequent_indent': ' '},
]
if TEST_QUICK:
# test only one feature: everything on
TEXTWRAP_KEYWORD_COMBINATIONS = [
{'break_long_words': True, 'drop_whitespace': True, 'subsequent_indent': ' '}
]
def test_SequenceWrapper_invalid_width():
"""Test exception thrown from invalid width."""
WIDTH = -3
@as_subprocess
def child():
term = TestTerminal()
try:
my_wrapped = term.wrap(u'------- -------------', WIDTH)
except ValueError as err:
assert err.args[0] == (
"invalid width %r(%s) (must be integer > 0)" % (
WIDTH, type(WIDTH)))
else:
assert False, 'Previous stmt should have raised exception.'
del my_wrapped # assigned but never used
child()
@pytest.mark.parametrize("kwargs", TEXTWRAP_KEYWORD_COMBINATIONS)
def test_SequenceWrapper(many_columns, kwargs):
"""Test that text wrapping matches internal extra options."""
@as_subprocess
def child(width, pgraph, kwargs):
# build a test paragraph, along with a very colorful version
term = TestTerminal()
attributes = ('bright_red', 'on_bright_blue', 'underline', 'reverse',
'red_reverse', 'red_on_white', 'on_bright_white')
term.bright_red('x')
term.on_bright_blue('x')
term.underline('x')
term.reverse('x')
term.red_reverse('x')
term.red_on_white('x')
term.on_bright_white('x')
pgraph_colored = u''.join(
getattr(term, (attributes[idx % len(attributes)]))(char)
if char != u' ' else u' '
for idx, char in enumerate(pgraph))
internal_wrapped = textwrap.wrap(pgraph, width=width, **kwargs)
my_wrapped = term.wrap(pgraph, width=width, **kwargs)
my_wrapped_colored = term.wrap(pgraph_colored, width=width, **kwargs)
# ensure we textwrap ascii the same as python
assert internal_wrapped == my_wrapped
# ensure content matches for each line, when the sequences are
# stripped back off of each line
for left, right in zip(internal_wrapped, my_wrapped_colored):
assert left == term.strip_seqs(right)
# ensure our colored textwrap is the same paragraph length
assert (len(internal_wrapped) == len(my_wrapped_colored))
child(width=many_columns, kwargs=kwargs,
pgraph=u' Z! a bc defghij klmnopqrstuvw<<>>xyz012345678900 ' * 2)
child(width=many_columns, kwargs=kwargs, pgraph=u'a bb ccc')
def test_multiline():
"""Test that text wrapping matches internal extra options."""
@as_subprocess
def child():
# build a test paragraph, along with a very colorful version
term = TestTerminal()
given_string = ('\n' + (32 * 'A') + '\n' +
(32 * 'B') + '\n' +
(32 * 'C') + '\n\n')
expected = [
'',
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
'AA',
'BBBBBBBBBBBBBBBBBBBBBBBBBBBBBB',
'BB',
'CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
'CC',
'',
]
result = term.wrap(given_string, width=30)
assert expected == result
child()
def test_east_asian_emojis_width_1():
"""Tests edge-case of east-asian and emoji characters split into single columns."""
@as_subprocess
def child():
term = TestTerminal()
# by @grayjk from https://github.com/jquast/blessed/issues/273
result = term.wrap(u'\u5973', 1)
assert result == [u'\u5973']
# much like test_length_with_zwj_is_wrong(), blessed gets ZWJ wrong when wrapping, also.
# In this case, each character gets its own line--even though '\u200D' is considered
# a width of 0, the next emoji is "too large to fit".
# RGI_Emoji_ZWJ_Sequence ; family: woman, woman, girl, boy
given = u'\U0001F469\u200D\U0001F469\u200D\U0001F467\u200D\U0001F466'
result = term.wrap(given, 1)
assert result == list(given)
# in another example, two *narrow* characters, \u1100, "ᄀ" HANGUL
# CHOSEONG KIYEOK (consonant) is joined with \u1161, "ᅡ" HANGUL
# JUNGSEONG A (vowel), to form a single *wide* character "가" HANGUL
# SYLLABLE GA. Ideally, a native speaker would rather have the cojoined
# wide character, and word-wrapping to a column width of '1' for any
# language that includes wide characters or emoji is a bit foolish!
given = u'\u1100\u1161'
result = term.wrap(given, 1)
assert result == list(given)
child()
def test_emojis_width_2_and_greater():
"""Tests emoji characters split into multiple columns."""
@as_subprocess
def child():
term = TestTerminal()
given = u'\U0001F469\U0001F467\U0001F466' # woman, girl, boy
result = term.wrap(given, 2)
assert result == list(given)
result = term.wrap(given, 3)
assert result == list(given)
result = term.wrap(given, 4)
assert result == [u'\U0001F469\U0001F467', u'\U0001F466']
result = term.wrap(given, 5)
assert result == [u'\U0001F469\U0001F467', u'\U0001F466']
result = term.wrap(given, 6)
assert result == [u'\U0001F469\U0001F467\U0001F466']
result = term.wrap(given, 7)
assert result == [u'\U0001F469\U0001F467\U0001F466']
child()
def test_greedy_join_with_cojoining():
"""Test that a word with trailing combining (café) wraps correctly."""
@as_subprocess
def child():
term = TestTerminal()
given = u'cafe\u0301-latte'
result = term.wrap(given, 5)
assert result == [u'cafe\u0301-', u'latte']
result = term.wrap(given, 4)
assert result == [u'cafe\u0301', u'-lat', u'te']
result = term.wrap(given, 3)
assert result == [u'caf', u'e\u0301-l', u'att', u'e']
result = term.wrap(given, 2)
assert result == [u'ca', u'fe\u0301', u'-l', u'at', u'te']
child()
|