/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_win32utils.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2011, 2016 Canonical Ltd
 
1
# Copyright (C) 2007-2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
"""Tests for win32utils."""
18
18
 
19
19
import os
 
20
import sys
20
21
 
21
 
from .. import (
 
22
from bzrlib import (
22
23
    osutils,
23
24
    tests,
24
25
    win32utils,
25
26
    )
26
 
from . import (
 
27
from bzrlib.tests import (
 
28
    Feature,
27
29
    TestCase,
28
30
    TestCaseInTempDir,
29
31
    TestSkipped,
30
 
    )
31
 
from .features import backslashdir_feature
32
 
from ..win32utils import glob_expand, get_app_path
33
 
from . import (
34
 
    features,
35
 
    )
36
 
 
37
 
 
38
 
Win32RegistryFeature = features.ModuleAvailableFeature('_winreg')
39
 
 
 
32
    UnicodeFilenameFeature,
 
33
    )
 
34
from bzrlib.tests.features import backslashdir_feature
 
35
from bzrlib.win32utils import glob_expand, get_app_path
 
36
 
 
37
 
 
38
class _RequiredModuleFeature(Feature):
 
39
 
 
40
    def __init__(self, mod_name):
 
41
        self.mod_name = mod_name
 
42
        super(_RequiredModuleFeature, self).__init__()
 
43
 
 
44
    def _probe(self):
 
45
        try:
 
46
            __import__(self.mod_name)
 
47
            return True
 
48
        except ImportError:
 
49
            return False
 
50
 
 
51
    def feature_name(self):
 
52
        return self.mod_name
 
53
 
 
54
Win32RegistryFeature = _RequiredModuleFeature('_winreg')
 
55
CtypesFeature = _RequiredModuleFeature('ctypes')
 
56
Win32comShellFeature = _RequiredModuleFeature('win32com.shell')
 
57
Win32ApiFeature = _RequiredModuleFeature('win32api') 
 
58
 
 
59
 
 
60
# Tests
 
61
# -----
40
62
 
41
63
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
42
64
 
57
79
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
58
80
 
59
81
    def build_unicode_tree(self):
60
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
82
        self.requireFeature(UnicodeFilenameFeature)
61
83
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/',
62
84
                         u'\u1235/\u1235'])
63
85
 
68
90
        self._run_testset([
69
91
            # no wildcards
70
92
            [[u'a'], [u'a']],
71
 
            [[u'a', u'a'], [u'a', u'a']],
 
93
            [[u'a', u'a' ], [u'a', u'a']],
72
94
 
73
95
            [[u'd'], [u'd']],
74
96
            [[u'd/'], [u'd/']],
98
120
            ])
99
121
 
100
122
    def test_case_insensitive_globbing(self):
101
 
        if os.path.normcase("AbC") == "AbC":
102
 
            self.skipTest("Test requires case insensitive globbing function")
 
123
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
103
124
        self.build_ascii_tree()
104
125
        self._run_testset([
105
126
            [[u'A'], [u'A']],
162
183
        for a in ('iexplore', 'iexplore.exe'):
163
184
            p = get_app_path(a)
164
185
            d, b = os.path.split(p)
165
 
            self.assertEqual('iexplore.exe', b.lower())
166
 
            self.assertNotEqual('', d)
 
186
            self.assertEquals('iexplore.exe', b.lower())
 
187
            self.assertNotEquals('', d)
167
188
 
168
189
    def test_wordpad(self):
169
190
        # typical windows users should have wordpad in the system
173
194
        for a in ('wordpad', 'wordpad.exe'):
174
195
            p = get_app_path(a)
175
196
            d, b = os.path.split(p)
176
 
            self.assertEqual('wordpad.exe', b.lower())
177
 
            self.assertNotEqual('', d)
 
197
            self.assertEquals('wordpad.exe', b.lower())
 
198
            self.assertNotEquals('', d)
178
199
 
179
200
    def test_not_existing(self):
180
201
        p = get_app_path('not-existing')
181
 
        self.assertEqual('not-existing', p)
182
 
 
183
 
 
184
 
class TestLocations(TestCase):
185
 
 
186
 
    _test_needs_features = [features.win32_feature]
 
202
        self.assertEquals('not-existing', p)
 
203
 
 
204
 
 
205
class TestLocationsCtypes(TestCase):
 
206
 
 
207
    _test_needs_features = [CtypesFeature]
187
208
 
188
209
    def assertPathsEqual(self, p1, p2):
189
210
        # TODO: The env var values in particular might return the "short"
190
211
        # version (ie, "C:\DOCUME~1\...").  Its even possible the returned
191
212
        # values will differ only by case - handle these situations as we
192
213
        # come across them.
193
 
        self.assertEqual(p1, p2)
 
214
        self.assertEquals(p1, p2)
194
215
 
195
216
    def test_appdata_not_using_environment(self):
196
217
        # Test that we aren't falling back to the environment
197
218
        first = win32utils.get_appdata_location()
198
 
        self.overrideEnv("APPDATA", None)
 
219
        self._captureVar("APPDATA", None)
199
220
        self.assertPathsEqual(first, win32utils.get_appdata_location())
200
221
 
201
222
    def test_appdata_matches_environment(self):
212
233
    def test_local_appdata_not_using_environment(self):
213
234
        # Test that we aren't falling back to the environment
214
235
        first = win32utils.get_local_appdata_location()
215
 
        self.overrideEnv("LOCALAPPDATA", None)
 
236
        self._captureVar("LOCALAPPDATA", None)
216
237
        self.assertPathsEqual(first, win32utils.get_local_appdata_location())
217
238
 
218
239
    def test_local_appdata_matches_environment(self):
221
242
        lad = win32utils.get_local_appdata_location()
222
243
        env = os.environ.get("LOCALAPPDATA")
223
244
        if env:
224
 
            # XXX - See bug 262874, which asserts the correct encoding is
225
 
            # 'mbcs'
 
245
            # XXX - See bug 262874, which asserts the correct encoding is 'mbcs'
226
246
            encoding = osutils.get_user_encoding()
227
247
            self.assertPathsEqual(lad, env.decode(encoding))
228
248
 
229
249
 
 
250
class TestLocationsPywin32(TestLocationsCtypes):
 
251
 
 
252
    _test_needs_features = [Win32comShellFeature]
 
253
 
 
254
    def setUp(self):
 
255
        super(TestLocationsPywin32, self).setUp()
 
256
        # We perform the exact same tests after disabling the use of ctypes.
 
257
        # This causes the implementation to fall back to pywin32.
 
258
        self.overrideAttr(win32utils, 'has_ctypes', False)
 
259
        # FIXME: this should be done by parametrization -- vila 100123
 
260
 
 
261
 
230
262
class TestSetHidden(TestCaseInTempDir):
231
263
 
232
 
    _test_needs_features = [features.win32_feature]
233
 
 
234
264
    def test_unicode_dir(self):
235
265
        # we should handle unicode paths without errors
236
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
266
        self.requireFeature(UnicodeFilenameFeature)
237
267
        os.mkdir(u'\u1234')
238
268
        win32utils.set_file_attr_hidden(u'\u1234')
239
269
 
240
270
    def test_dot_bzr_in_unicode_dir(self):
241
271
        # we should not raise traceback if we try to set hidden attribute
242
272
        # on .bzr directory below unicode path
243
 
        self.requireFeature(features.UnicodeFilenameFeature)
 
273
        self.requireFeature(UnicodeFilenameFeature)
244
274
        os.makedirs(u'\u1234\\.bzr')
245
275
        path = osutils.abspath(u'\u1234\\.bzr')
246
276
        win32utils.set_file_attr_hidden(path)
249
279
class Test_CommandLineToArgv(tests.TestCaseInTempDir):
250
280
 
251
281
    def assertCommandLine(self, expected, line, argv=None,
252
 
                          single_quotes_allowed=False):
 
282
            single_quotes_allowed=False):
253
283
        # Strictly speaking we should respect parameter order versus glob
254
284
        # expansions, but it's not really worth the effort here
255
285
        if argv is None:
256
286
            argv = [line]
257
 
        argv = win32utils._command_line_to_argv(
258
 
            line, argv, single_quotes_allowed=single_quotes_allowed)
 
287
        argv = win32utils._command_line_to_argv(line, argv,
 
288
                single_quotes_allowed=single_quotes_allowed)
259
289
        self.assertEqual(expected, sorted(argv))
260
290
 
261
291
    def test_glob_paths(self):
273
303
        self.assertCommandLine([u'a/*.c'], '"a/*.c"')
274
304
        self.assertCommandLine([u"'a/*.c'"], "'a/*.c'")
275
305
        self.assertCommandLine([u'a/*.c'], "'a/*.c'",
276
 
                               single_quotes_allowed=True)
 
306
            single_quotes_allowed=True)
277
307
 
278
308
    def test_slashes_changed(self):
279
309
        # Quoting doesn't change the supplied args
280
310
        self.assertCommandLine([u'a\\*.c'], '"a\\*.c"')
281
311
        self.assertCommandLine([u'a\\*.c'], "'a\\*.c'",
282
 
                               single_quotes_allowed=True)
 
312
            single_quotes_allowed=True)
283
313
        # Expands the glob, but nothing matches, swaps slashes
284
314
        self.assertCommandLine([u'a/*.c'], 'a\\*.c')
285
315
        self.assertCommandLine([u'a/?.c'], 'a\\?.c')
288
318
 
289
319
    def test_single_quote_support(self):
290
320
        self.assertCommandLine(["add", "let's-do-it.txt"],
291
 
                               "add let's-do-it.txt",
292
 
                               ["add", "let's-do-it.txt"])
 
321
            "add let's-do-it.txt",
 
322
            ["add", "let's-do-it.txt"])
293
323
        self.expectFailure("Using single quotes breaks trimming from argv",
294
 
                           self.assertCommandLine, ["add", "lets do it.txt"],
295
 
                           "add 'lets do it.txt'", [
296
 
                               "add", "'lets", "do", "it.txt'"],
297
 
                           single_quotes_allowed=True)
 
324
            self.assertCommandLine, ["add", "lets do it.txt"],
 
325
            "add 'lets do it.txt'", ["add", "'lets", "do", "it.txt'"],
 
326
            single_quotes_allowed=True)
298
327
 
299
328
    def test_case_insensitive_globs(self):
300
 
        if os.path.normcase("AbC") == "AbC":
301
 
            self.skipTest("Test requires case insensitive globbing function")
 
329
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
302
330
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
303
331
        self.assertCommandLine([u'A/b.c'], 'A/B*')
304
332
 
313
341
        self.build_tree(['d/', 'd/f1', 'd/f2'])
314
342
        self.assertCommandLine([u"rm", u"x*"], "-m pdb rm x*", ["rm", u"x*"])
315
343
        self.assertCommandLine([u"add", u"d/f1", u"d/f2"], "-m pdb add d/*",
316
 
                               ["add", u"d/*"])
317
 
 
318
 
 
319
 
class TestGetEnvironUnicode(tests.TestCase):
320
 
    """Tests for accessing the environment via the windows wide api"""
321
 
 
322
 
    _test_needs_features = [features.win32_feature]
323
 
 
324
 
    def setUp(self):
325
 
        super(TestGetEnvironUnicode, self).setUp()
326
 
        self.overrideEnv("TEST", "1")
327
 
 
328
 
    def test_get(self):
329
 
        """In the normal case behaves the same as os.environ access"""
330
 
        self.assertEqual("1", win32utils.get_environ_unicode("TEST"))
331
 
 
332
 
    def test_unset(self):
333
 
        """A variable not present in the environment gives None by default"""
334
 
        del os.environ["TEST"]
335
 
        self.assertIs(None, win32utils.get_environ_unicode("TEST"))
336
 
 
337
 
    def test_unset_default(self):
338
 
        """A variable not present in the environment gives passed default"""
339
 
        del os.environ["TEST"]
340
 
        self.assertIs("a", win32utils.get_environ_unicode("TEST", "a"))
341
 
 
342
 
    def test_unicode(self):
343
 
        """A non-ascii variable is returned as unicode"""
344
 
        unicode_val = u"\xa7"  # non-ascii character present in many encodings
345
 
        try:
346
 
            bytes_val = unicode_val.encode(osutils.get_user_encoding())
347
 
        except UnicodeEncodeError:
348
 
            self.skipTest("Couldn't encode non-ascii string for environ")
349
 
        os.environ["TEST"] = bytes_val
350
 
        self.assertEqual(unicode_val, win32utils.get_environ_unicode("TEST"))
351
 
 
352
 
    def test_long(self):
353
 
        """A variable bigger than heuristic buffer size is still accessible"""
354
 
        big_val = "x" * (2 << 10)
355
 
        os.environ["TEST"] = big_val
356
 
        self.assertEqual(big_val, win32utils.get_environ_unicode("TEST"))
357
 
 
358
 
    def test_unexpected_error(self):
359
 
        """An error from the underlying platform function is propogated"""
360
 
        ERROR_INVALID_PARAMETER = 87
361
 
        SetLastError = win32utils.ctypes.windll.kernel32.SetLastError
362
 
 
363
 
        def failer(*args, **kwargs):
364
 
            SetLastError(ERROR_INVALID_PARAMETER)
365
 
            return 0
366
 
        self.overrideAttr(win32utils.get_environ_unicode, "_c_function",
367
 
                          failer)
368
 
        e = self.assertRaises(WindowsError,
369
 
                              win32utils.get_environ_unicode, "TEST")
370
 
        self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)
 
344
            ["add", u"d/*"])