File: test_console.py

package info (click to toggle)
python-astropy 1.3-8~bpo8%2B2
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 44,292 kB
  • sloc: ansic: 160,360; python: 137,322; sh: 11,493; lex: 7,638; yacc: 4,956; xml: 1,796; makefile: 474; cpp: 364
file content (220 lines) | stat: -rw-r--r-- 6,316 bytes parent folder | download | duplicates (2)
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
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-

# TEST_UNICODE_LITERALS

from __future__ import (absolute_import, division, print_function,
                        unicode_literals)

from ...extern import six  # pylint: disable=W0611
from ...extern.six import next
from ...extern.six.moves import range

import io
import locale

from ...tests.helper import pytest
from .. import console
from ... import units as u


class FakeTTY(io.StringIO):
    """IOStream that fakes a TTY; provide an encoding to emulate an output
    stream with a specific encoding.
    """

    def __new__(cls, encoding=None):
        # Return a new subclass of FakeTTY with the requested encoding
        if encoding is None:
            return super(FakeTTY, cls).__new__(cls)

        # Since we're using unicode_literals in this module ensure that this is
        # a 'str' object (since a class name can't be unicode in Python 2.7)
        encoding = str(encoding)
        cls = type(encoding.title() + cls.__name__, (cls,),
                   {'encoding': encoding})

        return cls.__new__(cls)

    def __init__(self, encoding=None):
        super(FakeTTY, self).__init__()

    def write(self, s):
        if isinstance(s, bytes):
            # Just allow this case to work
            s = s.decode('latin-1')
        elif self.encoding is not None:
            s.encode(self.encoding)

        return super(FakeTTY, self).write(s)

    def isatty(self):
        return True


def test_fake_tty():
    # First test without a specified encoding; we should be able to write
    # arbitrary unicode strings
    f1 = FakeTTY()
    assert f1.isatty()
    f1.write('☃')
    assert f1.getvalue() == '☃'

    # Now test an ASCII-only TTY--it should raise a UnicodeEncodeError when
    # trying to write a string containing non-ASCII characters
    f2 = FakeTTY('ascii')
    assert f2.isatty()
    assert f2.__class__.__name__ == 'AsciiFakeTTY'
    assert pytest.raises(UnicodeEncodeError, f2.write, '☃')
    assert f2.getvalue() == ''


@pytest.mark.skipif(str("sys.platform.startswith('win')"))
def test_color_text():
    assert console._color_text("foo", "green") == '\033[0;32mfoo\033[0m'


def test_color_print():
    # This stuff is hard to test, at least smoke test it
    console.color_print("foo", "green")

    console.color_print("foo", "green", "bar", "red")


def test_color_print2():
    # Test that this automatically detects that io.StringIO is
    # not a tty
    stream = io.StringIO()
    console.color_print("foo", "green", file=stream)
    assert stream.getvalue() == 'foo\n'

    stream = io.StringIO()
    console.color_print("foo", "green", "bar", "red", "baz", file=stream)
    assert stream.getvalue() == 'foobarbaz\n'


@pytest.mark.skipif(str("sys.platform.startswith('win')"))
def test_color_print3():
    # Test that this thinks the FakeTTY is a tty and applies colors.

    stream = FakeTTY()
    console.color_print("foo", "green", file=stream)
    assert stream.getvalue() == '\x1b[0;32mfoo\x1b[0m\n'

    stream = FakeTTY()
    console.color_print("foo", "green", "bar", "red", "baz", file=stream)
    assert stream.getvalue() == '\x1b[0;32mfoo\x1b[0m\x1b[0;31mbar\x1b[0mbaz\n'


def test_color_print_unicode():
    console.color_print("überbær", "red")


def test_color_print_invalid_color():
    console.color_print("foo", "unknown")


@pytest.mark.skipif(str('not six.PY2'))
def test_color_print_no_default_encoding():
    """Regression test for #1244

    In some environments `locale.getpreferredencoding` can return ``''``;
    make sure there are some reasonable fallbacks.
    """

    # Not sure of a reliable way to force getpreferredencoding() to return
    # an empty string other than to temporarily patch it
    orig_func = locale.getpreferredencoding
    locale.getpreferredencoding = lambda: ''
    try:
        # Try printing a string that can be utf-8 decoded (the default)
        stream = io.StringIO()
        console.color_print(b'\xe2\x98\x83', 'white', file=stream)
        assert stream.getvalue() == '☃\n'

        # Test the latin-1 fallback
        stream = io.StringIO()
        console.color_print(b'\xcd\xef', 'red', file=stream)
        assert stream.getvalue() == 'Íï\n'
    finally:
        locale.getpreferredencoding = orig_func


def test_spinner_non_unicode_console():
    """Regression test for #1760

    Ensures that the spinner can fall go into fallback mode when using the
    unicode spinner on a terminal whose default encoding cannot encode the
    unicode characters.
    """

    stream = FakeTTY('ascii')
    chars = console.Spinner._default_unicode_chars

    with console.Spinner("Reticulating splines", file=stream,
                         chars=chars) as s:
        next(s)


def test_progress_bar():
    # This stuff is hard to test, at least smoke test it
    with console.ProgressBar(50) as bar:
        for i in range(50):
            bar.update()


def test_progress_bar2():
    for x in console.ProgressBar(range(50)):
        pass


def test_progress_bar3():
    def do_nothing(*args, **kwargs):
        pass

    console.ProgressBar.map(do_nothing, range(50))


def test_zero_progress_bar():
    with console.ProgressBar(0) as bar:
        pass


def test_progress_bar_as_generator():
    sum = 0
    for x in console.ProgressBar(range(50)):
        sum += x
    assert sum == 1225

    sum = 0
    for x in console.ProgressBar(50):
        sum += x
    assert sum == 1225

@pytest.mark.parametrize(("seconds","string"),
       [(864088," 1w 3d"),
       (187213, " 2d 4h"),
       (3905,   " 1h 5m"),
       (64,     " 1m 4s"),
       (15,     "   15s"),
       (2,      "    2s")]
)
def test_human_time(seconds, string):
    human_time = console.human_time(seconds)
    assert human_time == string

@pytest.mark.parametrize(("size","string"),
       [(8640882,"8.6M"),
       (187213, "187k"),
       (3905,   "3.9k"),
       (64,     " 64 "),
       (2,      "  2 "),
       (10*u.GB,  " 10G")]
)
def test_human_file_size(size, string):
    human_time = console.human_file_size(size)
    assert human_time == string

@pytest.mark.parametrize("size", (50*u.km, 100*u.g))
def test_bad_human_file_size(size):
    assert pytest.raises(u.UnitConversionError, console.human_file_size, size)