~bzr-pqm/bzr/bzr.dev

2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
1
# Copyright (C) 2005, 2006 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
16
17
"""Tests for the osutils wrapper."""
18
19
import codecs
2192.1.9 by Alexander Belchenko
final fix suggested by John Meinel
20
import locale
2192.1.7 by Alexander Belchenko
get_user_encoding: if locale.Error raised we need to set user_encoding to 'ascii' as warning says
21
import os
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
22
import sys
23
24
from bzrlib import (
25
    errors,
26
    osutils,
27
    )
28
from bzrlib.tests import (
29
        StringIOWrapper,
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
30
        TestCase,
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
31
        )
32
33
34
class FakeCodec(object):
2192.1.8 by Alexander Belchenko
Rework tests after John's review
35
    """Special class that helps testing over several non-existed encodings.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
36
2192.1.8 by Alexander Belchenko
Rework tests after John's review
37
    Clients can add new encoding names, but because of how codecs is
38
    implemented they cannot be removed. Be careful with naming to avoid
39
    collisions between tests.
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
40
    """
41
    _registered = False
42
    _enabled_encodings = set()
43
44
    def add(self, encoding_name):
2192.1.8 by Alexander Belchenko
Rework tests after John's review
45
        """Adding encoding name to fake.
46
47
        :type   encoding_name:  lowercase plain string
48
        """
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
49
        if not self._registered:
50
            codecs.register(self)
51
            self._registered = True
2192.1.8 by Alexander Belchenko
Rework tests after John's review
52
        if encoding_name is not None:
53
            self._enabled_encodings.add(encoding_name)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
54
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
55
    def __call__(self, encoding_name):
56
        """Called indirectly by codecs module during lookup"""
57
        if encoding_name in self._enabled_encodings:
58
            return codecs.lookup('latin-1')
2192.1.6 by Alexander Belchenko
Fixes after Aaron's review
59
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
60
61
fake_codec = FakeCodec()
62
63
64
class TestFakeCodec(TestCase):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
65
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
66
    def test_fake_codec(self):
67
        self.assertRaises(LookupError, codecs.lookup, 'fake')
68
69
        fake_codec.add('fake')
70
        codecs.lookup('fake')
71
72
73
class TestTerminalEncoding(TestCase):
74
    """Test the auto-detection of proper terminal encoding."""
75
76
    def setUp(self):
4153.1.2 by Andrew Bennetts
Add missing TestCase.setUp upcalls.
77
        TestCase.setUp(self)
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
78
        self._stdout = sys.stdout
79
        self._stderr = sys.stderr
80
        self._stdin = sys.stdin
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
81
        self._user_encoding = osutils._cached_user_encoding
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
82
83
        self.addCleanup(self._reset)
84
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
85
    def make_wrapped_streams(self,
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
86
                             stdout_encoding,
87
                             stderr_encoding,
88
                             stdin_encoding,
89
                             user_encoding='user_encoding',
90
                             enable_fake_encodings=True):
91
        sys.stdout = StringIOWrapper()
92
        sys.stdout.encoding = stdout_encoding
93
        sys.stderr = StringIOWrapper()
94
        sys.stderr.encoding = stderr_encoding
95
        sys.stdin = StringIOWrapper()
96
        sys.stdin.encoding = stdin_encoding
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
97
        osutils._cached_user_encoding = user_encoding
2192.1.8 by Alexander Belchenko
Rework tests after John's review
98
        if enable_fake_encodings:
99
            fake_codec.add(stdout_encoding)
100
            fake_codec.add(stderr_encoding)
101
            fake_codec.add(stdin_encoding)
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
102
103
    def _reset(self):
104
        sys.stdout = self._stdout
105
        sys.stderr = self._stderr
106
        sys.stdin = self._stdin
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
107
        osutils._cached_user_encoding = self._user_encoding
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
108
109
    def test_get_terminal_encoding(self):
110
        self.make_wrapped_streams('stdout_encoding',
111
                                  'stderr_encoding',
112
                                  'stdin_encoding')
113
114
        # first preference is stdout encoding
115
        self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
116
117
        sys.stdout.encoding = None
118
        # if sys.stdout is None, fall back to sys.stdin
119
        self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
120
121
        sys.stdin.encoding = None
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
122
        # and in the worst case, use osutils.get_user_encoding()
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
123
        self.assertEqual('user_encoding', osutils.get_terminal_encoding())
124
125
    def test_terminal_cp0(self):
2192.1.6 by Alexander Belchenko
Fixes after Aaron's review
126
        # test cp0 encoding (Windows returns cp0 when there is no encoding)
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
127
        self.make_wrapped_streams('cp0',
2192.1.8 by Alexander Belchenko
Rework tests after John's review
128
                                  'cp0',
129
                                  'cp0',
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
130
                                  user_encoding='latin-1',
131
                                  enable_fake_encodings=False)
132
133
        # cp0 is invalid encoding. We should fall back to user_encoding
134
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
135
136
        # check stderr
137
        self.assertEquals('', sys.stderr.getvalue())
138
2192.1.8 by Alexander Belchenko
Rework tests after John's review
139
    def test_terminal_cp_unknown(self):
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
140
        # test against really unknown encoding
141
        # catch warning at stderr
2192.1.8 by Alexander Belchenko
Rework tests after John's review
142
        self.make_wrapped_streams('cp-unknown',
143
                                  'cp-unknown',
144
                                  'cp-unknown',
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
145
                                  user_encoding='latin-1',
146
                                  enable_fake_encodings=False)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
147
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
148
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
149
150
        # check stderr
2192.1.10 by Alexander Belchenko
merge bzr.dev
151
        self.assertEquals('bzr: warning: unknown terminal encoding cp-unknown.\n'
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
152
                          '  Using encoding latin-1 instead.\n',
2192.1.2 by Alexander Belchenko
Tests for osutils.get_terminal_encoding()
153
                          sys.stderr.getvalue())
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
154
155
156
class TestUserEncoding(TestCase):
157
    """Test detection of default user encoding."""
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
158
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
159
    def setUp(self):
4153.1.2 by Andrew Bennetts
Add missing TestCase.setUp upcalls.
160
        TestCase.setUp(self)
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
161
        self._stderr = sys.stderr
162
        self._getpreferredencoding = locale.getpreferredencoding
163
        self.addCleanup(self._reset)
164
        sys.stderr = StringIOWrapper()
2192.1.7 by Alexander Belchenko
get_user_encoding: if locale.Error raised we need to set user_encoding to 'ascii' as warning says
165
        # save $LANG
166
        self._LANG = os.environ.get('LANG')
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
167
168
    def _reset(self):
169
        locale.getpreferredencoding = self._getpreferredencoding
170
        sys.stderr = self._stderr
2192.1.7 by Alexander Belchenko
get_user_encoding: if locale.Error raised we need to set user_encoding to 'ascii' as warning says
171
        # restore $LANG
2192.1.8 by Alexander Belchenko
Rework tests after John's review
172
        osutils.set_or_unset_env('LANG', self._LANG)
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
173
174
    def test_get_user_encoding(self):
175
        def f():
176
            return 'user_encoding'
177
178
        locale.getpreferredencoding = f
179
        fake_codec.add('user_encoding')
180
        self.assertEquals('user_encoding', osutils.get_user_encoding(use_cache=False))
181
        self.assertEquals('', sys.stderr.getvalue())
182
183
    def test_user_cp0(self):
184
        def f():
185
            return 'cp0'
186
187
        locale.getpreferredencoding = f
188
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
189
        self.assertEquals('', sys.stderr.getvalue())
190
2192.1.8 by Alexander Belchenko
Rework tests after John's review
191
    def test_user_cp_unknown(self):
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
192
        def f():
2192.1.8 by Alexander Belchenko
Rework tests after John's review
193
            return 'cp-unknown'
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
194
195
        locale.getpreferredencoding = f
196
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
2192.1.8 by Alexander Belchenko
Rework tests after John's review
197
        self.assertEquals('bzr: warning: unknown encoding cp-unknown.'
2192.1.3 by Alexander Belchenko
Tests for osutils.get_user_encoding
198
                          ' Continuing with ascii encoding.\n',
199
                          sys.stderr.getvalue())
2192.1.7 by Alexander Belchenko
get_user_encoding: if locale.Error raised we need to set user_encoding to 'ascii' as warning says
200
3405.3.1 by Neil Martinsen-Burrell
accept for an encoding to mean ascii
201
    def test_user_empty(self):
202
        """Running bzr from a vim script gives '' for a preferred locale"""
203
        def f():
204
            return ''
205
206
        locale.getpreferredencoding = f
207
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
208
        self.assertEquals('', sys.stderr.getvalue())
209
2192.1.7 by Alexander Belchenko
get_user_encoding: if locale.Error raised we need to set user_encoding to 'ascii' as warning says
210
    def test_user_locale_error(self):
211
        def f():
212
            raise locale.Error, 'unsupported locale'
213
214
        locale.getpreferredencoding = f
215
        os.environ['LANG'] = 'BOGUS'
216
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
217
        self.assertEquals('bzr: warning: unsupported locale\n'
218
                          '  Could not determine what text encoding to use.\n'
219
                          '  This error usually means your Python interpreter\n'
220
                          '  doesn\'t support the locale set by $LANG (BOGUS)\n'
221
                          '  Continuing with ascii encoding.\n',
222
                          sys.stderr.getvalue())