~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_osutils_encodings.py

- improved handling of non-ascii branch names and test
  patch from Joel Rosdahl

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
 
import bzrlib
25
 
from bzrlib import (
26
 
    errors,
27
 
    osutils,
28
 
    )
29
 
from bzrlib.tests import (
30
 
        StringIOWrapper,
31
 
        TestCase, 
32
 
        TestSkipped,
33
 
        )
34
 
 
35
 
 
36
 
class FakeCodec(object):
37
 
    """Special class that helps testing over several non-existed encodings.
38
 
    
39
 
    Clients can add new encoding names, but because of how codecs is
40
 
    implemented they cannot be removed. Be careful with naming to avoid
41
 
    collisions between tests.
42
 
    """
43
 
    _registered = False
44
 
    _enabled_encodings = set()
45
 
 
46
 
    def add(self, encoding_name):
47
 
        """Adding encoding name to fake.
48
 
 
49
 
        :type   encoding_name:  lowercase plain string
50
 
        """
51
 
        if not self._registered:
52
 
            codecs.register(self)
53
 
            self._registered = True
54
 
        if encoding_name is not None:
55
 
            self._enabled_encodings.add(encoding_name)
56
 
        
57
 
    def __call__(self, encoding_name):
58
 
        """Called indirectly by codecs module during lookup"""
59
 
        if encoding_name in self._enabled_encodings:
60
 
            return codecs.lookup('latin-1')
61
 
 
62
 
 
63
 
fake_codec = FakeCodec()
64
 
 
65
 
 
66
 
class TestFakeCodec(TestCase):
67
 
    
68
 
    def test_fake_codec(self):
69
 
        self.assertRaises(LookupError, codecs.lookup, 'fake')
70
 
 
71
 
        fake_codec.add('fake')
72
 
        codecs.lookup('fake')
73
 
 
74
 
 
75
 
class TestTerminalEncoding(TestCase):
76
 
    """Test the auto-detection of proper terminal encoding."""
77
 
 
78
 
    def setUp(self):
79
 
        self._stdout = sys.stdout
80
 
        self._stderr = sys.stderr
81
 
        self._stdin = sys.stdin
82
 
        self._user_encoding = bzrlib.user_encoding
83
 
 
84
 
        self.addCleanup(self._reset)
85
 
 
86
 
    def make_wrapped_streams(self, 
87
 
                             stdout_encoding,
88
 
                             stderr_encoding,
89
 
                             stdin_encoding,
90
 
                             user_encoding='user_encoding',
91
 
                             enable_fake_encodings=True):
92
 
        sys.stdout = StringIOWrapper()
93
 
        sys.stdout.encoding = stdout_encoding
94
 
        sys.stderr = StringIOWrapper()
95
 
        sys.stderr.encoding = stderr_encoding
96
 
        sys.stdin = StringIOWrapper()
97
 
        sys.stdin.encoding = stdin_encoding
98
 
        bzrlib.user_encoding = user_encoding
99
 
        if enable_fake_encodings:
100
 
            fake_codec.add(stdout_encoding)
101
 
            fake_codec.add(stderr_encoding)
102
 
            fake_codec.add(stdin_encoding)
103
 
 
104
 
    def _reset(self):
105
 
        sys.stdout = self._stdout
106
 
        sys.stderr = self._stderr
107
 
        sys.stdin = self._stdin
108
 
        bzrlib.user_encoding = self._user_encoding
109
 
 
110
 
    def test_get_terminal_encoding(self):
111
 
        self.make_wrapped_streams('stdout_encoding',
112
 
                                  'stderr_encoding',
113
 
                                  'stdin_encoding')
114
 
 
115
 
        # first preference is stdout encoding
116
 
        self.assertEqual('stdout_encoding', osutils.get_terminal_encoding())
117
 
 
118
 
        sys.stdout.encoding = None
119
 
        # if sys.stdout is None, fall back to sys.stdin
120
 
        self.assertEqual('stdin_encoding', osutils.get_terminal_encoding())
121
 
 
122
 
        sys.stdin.encoding = None
123
 
        # and in the worst case, use bzrlib.user_encoding
124
 
        self.assertEqual('user_encoding', osutils.get_terminal_encoding())
125
 
 
126
 
    def test_terminal_cp0(self):
127
 
        # test cp0 encoding (Windows returns cp0 when there is no encoding)
128
 
        self.make_wrapped_streams('cp0',
129
 
                                  'cp0',
130
 
                                  'cp0',
131
 
                                  user_encoding='latin-1',
132
 
                                  enable_fake_encodings=False)
133
 
 
134
 
        # cp0 is invalid encoding. We should fall back to user_encoding
135
 
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
136
 
 
137
 
        # check stderr
138
 
        self.assertEquals('', sys.stderr.getvalue())
139
 
 
140
 
    def test_terminal_cp_unknown(self):
141
 
        # test against really unknown encoding
142
 
        # catch warning at stderr
143
 
        self.make_wrapped_streams('cp-unknown',
144
 
                                  'cp-unknown',
145
 
                                  'cp-unknown',
146
 
                                  user_encoding='latin-1',
147
 
                                  enable_fake_encodings=False)
148
 
        
149
 
        self.assertEqual('latin-1', osutils.get_terminal_encoding())
150
 
 
151
 
        # check stderr
152
 
        self.assertEquals('bzr: warning: unknown terminal encoding cp-unknown.\n'
153
 
                          '  Using encoding latin-1 instead.\n', 
154
 
                          sys.stderr.getvalue())
155
 
 
156
 
 
157
 
class TestUserEncoding(TestCase):
158
 
    """Test detection of default user encoding."""
159
 
    
160
 
    def setUp(self):
161
 
        self._stderr = sys.stderr
162
 
        self._getpreferredencoding = locale.getpreferredencoding
163
 
        self.addCleanup(self._reset)
164
 
        sys.stderr = StringIOWrapper()
165
 
        # save $LANG
166
 
        self._LANG = os.environ.get('LANG')
167
 
 
168
 
    def _reset(self):
169
 
        locale.getpreferredencoding = self._getpreferredencoding
170
 
        sys.stderr = self._stderr
171
 
        # restore $LANG
172
 
        osutils.set_or_unset_env('LANG', self._LANG)
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
 
 
191
 
    def test_user_cp_unknown(self):
192
 
        def f():
193
 
            return 'cp-unknown'
194
 
 
195
 
        locale.getpreferredencoding = f
196
 
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
197
 
        self.assertEquals('bzr: warning: unknown encoding cp-unknown.'
198
 
                          ' Continuing with ascii encoding.\n',
199
 
                          sys.stderr.getvalue())
200
 
 
201
 
    def test_user_locale_error(self):
202
 
        def f():
203
 
            raise locale.Error, 'unsupported locale'
204
 
 
205
 
        locale.getpreferredencoding = f
206
 
        os.environ['LANG'] = 'BOGUS'
207
 
        self.assertEquals('ascii', osutils.get_user_encoding(use_cache=False))
208
 
        self.assertEquals('bzr: warning: unsupported locale\n'
209
 
                          '  Could not determine what text encoding to use.\n'
210
 
                          '  This error usually means your Python interpreter\n'
211
 
                          '  doesn\'t support the locale set by $LANG (BOGUS)\n'
212
 
                          '  Continuing with ascii encoding.\n',
213
 
                          sys.stderr.getvalue())