~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils_encodings.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-10-31 04:39:04 UTC
  • mfrom: (3565.6.16 switch_nick)
  • Revision ID: pqm@pqm.ubuntu.com-20081031043904-52fnbfrloojemvcc
(mbp) branch nickname documentation

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the osutils wrapper."""
 
18
 
 
19
import codecs
 
20
import locale
 
21
import os
 
22
import sys
 
23
 
 
24
from bzrlib import (
 
25
    errors,
 
26
    osutils,
 
27
    )
 
28
from bzrlib.tests import (
 
29
        StringIOWrapper,
 
30
        TestCase, 
 
31
        )
 
32
 
 
33
 
 
34
class FakeCodec(object):
 
35
    """Special class that helps testing over several non-existed encodings.
 
36
    
 
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.
 
40
    """
 
41
    _registered = False
 
42
    _enabled_encodings = set()
 
43
 
 
44
    def add(self, encoding_name):
 
45
        """Adding encoding name to fake.
 
46
 
 
47
        :type   encoding_name:  lowercase plain string
 
48
        """
 
49
        if not self._registered:
 
50
            codecs.register(self)
 
51
            self._registered = True
 
52
        if encoding_name is not None:
 
53
            self._enabled_encodings.add(encoding_name)
 
54
        
 
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')
 
59
 
 
60
 
 
61
fake_codec = FakeCodec()
 
62
 
 
63
 
 
64
class TestFakeCodec(TestCase):
 
65
    
 
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):
 
77
        self._stdout = sys.stdout
 
78
        self._stderr = sys.stderr
 
79
        self._stdin = sys.stdin
 
80
        self._user_encoding = osutils._cached_user_encoding
 
81
 
 
82
        self.addCleanup(self._reset)
 
83
 
 
84
    def make_wrapped_streams(self, 
 
85
                             stdout_encoding,
 
86
                             stderr_encoding,
 
87
                             stdin_encoding,
 
88
                             user_encoding='user_encoding',
 
89
                             enable_fake_encodings=True):
 
90
        sys.stdout = StringIOWrapper()
 
91
        sys.stdout.encoding = stdout_encoding
 
92
        sys.stderr = StringIOWrapper()
 
93
        sys.stderr.encoding = stderr_encoding
 
94
        sys.stdin = StringIOWrapper()
 
95
        sys.stdin.encoding = stdin_encoding
 
96
        osutils._cached_user_encoding = user_encoding
 
97
        if enable_fake_encodings:
 
98
            fake_codec.add(stdout_encoding)
 
99
            fake_codec.add(stderr_encoding)
 
100
            fake_codec.add(stdin_encoding)
 
101
 
 
102
    def _reset(self):
 
103
        sys.stdout = self._stdout
 
104
        sys.stderr = self._stderr
 
105
        sys.stdin = self._stdin
 
106
        osutils._cached_user_encoding = self._user_encoding
 
107
 
 
108
    def test_get_terminal_encoding(self):
 
109
        self.make_wrapped_streams('stdout_encoding',
 
110
                                  'stderr_encoding',
 
111
                                  'stdin_encoding')
 
112
 
 
113
        # first preference is stdout encoding
 
114
        self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
 
115
 
 
116
        sys.stdout.encoding = None
 
117
        # if sys.stdout is None, fall back to sys.stdin
 
118
        self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
 
119
 
 
120
        sys.stdin.encoding = None
 
121
        # and in the worst case, use osutils.get_user_encoding()
 
122
        self.assertEqual('user_encoding', osutils.get_terminal_encoding())
 
123
 
 
124
    def test_terminal_cp0(self):
 
125
        # test cp0 encoding (Windows returns cp0 when there is no encoding)
 
126
        self.make_wrapped_streams('cp0',
 
127
                                  'cp0',
 
128
                                  'cp0',
 
129
                                  user_encoding='latin-1',
 
130
                                  enable_fake_encodings=False)
 
131
 
 
132
        # cp0 is invalid encoding. We should fall back to user_encoding
 
133
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
 
134
 
 
135
        # check stderr
 
136
        self.assertEquals('', sys.stderr.getvalue())
 
137
 
 
138
    def test_terminal_cp_unknown(self):
 
139
        # test against really unknown encoding
 
140
        # catch warning at stderr
 
141
        self.make_wrapped_streams('cp-unknown',
 
142
                                  'cp-unknown',
 
143
                                  'cp-unknown',
 
144
                                  user_encoding='latin-1',
 
145
                                  enable_fake_encodings=False)
 
146
        
 
147
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
 
148
 
 
149
        # check stderr
 
150
        self.assertEquals('bzr: warning: unknown terminal encoding cp-unknown.\n'
 
151
                          '  Using encoding latin-1 instead.\n', 
 
152
                          sys.stderr.getvalue())
 
153
 
 
154
 
 
155
class TestUserEncoding(TestCase):
 
156
    """Test detection of default user encoding."""
 
157
    
 
158
    def setUp(self):
 
159
        self._stderr = sys.stderr
 
160
        self._getpreferredencoding = locale.getpreferredencoding
 
161
        self.addCleanup(self._reset)
 
162
        sys.stderr = StringIOWrapper()
 
163
        # save $LANG
 
164
        self._LANG = os.environ.get('LANG')
 
165
 
 
166
    def _reset(self):
 
167
        locale.getpreferredencoding = self._getpreferredencoding
 
168
        sys.stderr = self._stderr
 
169
        # restore $LANG
 
170
        osutils.set_or_unset_env('LANG', self._LANG)
 
171
 
 
172
    def test_get_user_encoding(self):
 
173
        def f():
 
174
            return 'user_encoding'
 
175
 
 
176
        locale.getpreferredencoding = f
 
177
        fake_codec.add('user_encoding')
 
178
        self.assertEquals('user_encoding', osutils.get_user_encoding(use_cache=False))
 
179
        self.assertEquals('', sys.stderr.getvalue())
 
180
 
 
181
    def test_user_cp0(self):
 
182
        def f():
 
183
            return 'cp0'
 
184
 
 
185
        locale.getpreferredencoding = f
 
186
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
 
187
        self.assertEquals('', sys.stderr.getvalue())
 
188
 
 
189
    def test_user_cp_unknown(self):
 
190
        def f():
 
191
            return 'cp-unknown'
 
192
 
 
193
        locale.getpreferredencoding = f
 
194
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
 
195
        self.assertEquals('bzr: warning: unknown encoding cp-unknown.'
 
196
                          ' Continuing with ascii encoding.\n',
 
197
                          sys.stderr.getvalue())
 
198
 
 
199
    def test_user_empty(self):
 
200
        """Running bzr from a vim script gives '' for a preferred locale"""
 
201
        def f():
 
202
            return ''
 
203
 
 
204
        locale.getpreferredencoding = f
 
205
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
 
206
        self.assertEquals('', sys.stderr.getvalue())
 
207
 
 
208
    def test_user_locale_error(self):
 
209
        def f():
 
210
            raise locale.Error, 'unsupported locale'
 
211
 
 
212
        locale.getpreferredencoding = f
 
213
        os.environ['LANG'] = 'BOGUS'
 
214
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
 
215
        self.assertEquals('bzr: warning: unsupported locale\n'
 
216
                          '  Could not determine what text encoding to use.\n'
 
217
                          '  This error usually means your Python interpreter\n'
 
218
                          '  doesn\'t support the locale set by $LANG (BOGUS)\n'
 
219
                          '  Continuing with ascii encoding.\n',
 
220
                          sys.stderr.getvalue())