File: test_wrap.py

package info (click to toggle)
python-blessed 1.21.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,296 kB
  • sloc: python: 7,215; makefile: 13; sh: 7
file content (186 lines) | stat: -rw-r--r-- 6,980 bytes parent folder | download
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()