1
# Copyright (C) 2006-2010 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
"""Tests for the osutils wrapper."""
28
from bzrlib.tests import (
34
class FakeCodec(object):
35
"""Special class that helps testing over several non-existed encodings.
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.
42
_enabled_encodings = set()
44
def add(self, encoding_name):
45
"""Adding encoding name to fake.
47
:type encoding_name: lowercase plain string
49
if not self._registered:
51
self._registered = True
52
if encoding_name is not None:
53
self._enabled_encodings.add(encoding_name)
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')
61
fake_codec = FakeCodec()
64
class TestFakeCodec(TestCase):
66
def test_fake_codec(self):
67
self.assertRaises(LookupError, codecs.lookup, 'fake')
69
fake_codec.add('fake')
73
class TestTerminalEncoding(TestCase):
74
"""Test the auto-detection of proper terminal encoding."""
78
self.overrideAttr(sys, 'stdin')
79
self.overrideAttr(sys, 'stdout')
80
self.overrideAttr(sys, 'stderr')
81
self.overrideAttr(osutils, '_cached_user_encoding')
83
def make_wrapped_streams(self,
87
user_encoding='user_encoding',
88
enable_fake_encodings=True):
89
sys.stdout = StringIOWrapper()
90
sys.stdout.encoding = stdout_encoding
91
sys.stderr = StringIOWrapper()
92
sys.stderr.encoding = stderr_encoding
93
sys.stdin = StringIOWrapper()
94
sys.stdin.encoding = stdin_encoding
95
osutils._cached_user_encoding = user_encoding
96
if enable_fake_encodings:
97
fake_codec.add(stdout_encoding)
98
fake_codec.add(stderr_encoding)
99
fake_codec.add(stdin_encoding)
101
def test_get_terminal_encoding(self):
102
self.make_wrapped_streams('stdout_encoding',
106
# first preference is stdout encoding
107
self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
109
sys.stdout.encoding = None
110
# if sys.stdout is None, fall back to sys.stdin
111
self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
113
sys.stdin.encoding = None
114
# and in the worst case, use osutils.get_user_encoding()
115
self.assertEqual('user_encoding', osutils.get_terminal_encoding())
117
def test_get_terminal_encoding_silent(self):
118
self.make_wrapped_streams('stdout_encoding',
121
# Calling get_terminal_encoding should not mutter when silent=True is
124
osutils.get_terminal_encoding()
125
self.assertEqual(log, self.get_log())
127
def test_get_terminal_encoding_trace(self):
128
self.make_wrapped_streams('stdout_encoding',
131
# Calling get_terminal_encoding should not mutter when silent=True is
134
osutils.get_terminal_encoding(trace=True)
135
self.assertNotEqual(log, self.get_log())
137
def test_terminal_cp0(self):
138
# test cp0 encoding (Windows returns cp0 when there is no encoding)
139
self.make_wrapped_streams('cp0',
142
user_encoding='latin-1',
143
enable_fake_encodings=False)
145
# cp0 is invalid encoding. We should fall back to user_encoding
146
self.assertEqual('latin-1', osutils.get_terminal_encoding())
149
self.assertEquals('', sys.stderr.getvalue())
151
def test_terminal_cp_unknown(self):
152
# test against really unknown encoding
153
# catch warning at stderr
154
self.make_wrapped_streams('cp-unknown',
157
user_encoding='latin-1',
158
enable_fake_encodings=False)
160
self.assertEqual('latin-1', osutils.get_terminal_encoding())
163
self.assertEquals('bzr: warning: unknown terminal encoding cp-unknown.\n'
164
' Using encoding latin-1 instead.\n',
165
sys.stderr.getvalue())
168
class TestUserEncoding(TestCase):
169
"""Test detection of default user encoding."""
173
self.overrideAttr(locale, 'getpreferredencoding')
174
self.addCleanup(osutils.set_or_unset_env,
175
'LANG', os.environ.get('LANG'))
176
self.overrideAttr(sys, 'stderr', StringIOWrapper())
178
def test_get_user_encoding(self):
180
return 'user_encoding'
182
locale.getpreferredencoding = f
183
fake_codec.add('user_encoding')
184
self.assertEquals('user_encoding', osutils.get_user_encoding(use_cache=False))
185
self.assertEquals('', sys.stderr.getvalue())
187
def test_user_cp0(self):
191
locale.getpreferredencoding = f
192
self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
193
self.assertEquals('', sys.stderr.getvalue())
195
def test_user_cp_unknown(self):
199
locale.getpreferredencoding = f
200
self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
201
self.assertEquals('bzr: warning: unknown encoding cp-unknown.'
202
' Continuing with ascii encoding.\n',
203
sys.stderr.getvalue())
205
def test_user_empty(self):
206
"""Running bzr from a vim script gives '' for a preferred locale"""
210
locale.getpreferredencoding = f
211
self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
212
self.assertEquals('', sys.stderr.getvalue())
214
def test_user_locale_error(self):
216
raise locale.Error, 'unsupported locale'
218
locale.getpreferredencoding = f
219
os.environ['LANG'] = 'BOGUS'
220
self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
221
self.assertEquals('bzr: warning: unsupported locale\n'
222
' Could not determine what text encoding to use.\n'
223
' This error usually means your Python interpreter\n'
224
' doesn\'t support the locale set by $LANG (BOGUS)\n'
225
' Continuing with ascii encoding.\n',
226
sys.stderr.getvalue())