/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: Robert Collins
  • Date: 2005-10-16 22:31:25 UTC
  • mto: This revision was merged to the branch mainline in revision 1458.
  • Revision ID: robertc@lifelesslap.robertcollins.net-20051016223125-26d4401cb94b7b82
Branch.relpath has been moved to WorkingTree.relpath.

WorkingTree no no longer takes an inventory, rather it takes an optional branch
parameter, and if None is given will open the branch at basedir implicitly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
import os
18
 
import sys
19
 
 
20
 
from bzrlib import (
21
 
    osutils,
22
 
    tests,
23
 
    win32utils,
24
 
    )
25
 
from bzrlib.tests import (
26
 
    Feature,
27
 
    TestCase,
28
 
    TestCaseInTempDir,
29
 
    TestSkipped,
30
 
    UnicodeFilenameFeature,
31
 
    )
32
 
from bzrlib.win32utils import glob_expand, get_app_path
33
 
 
34
 
 
35
 
class _BackslashDirSeparatorFeature(tests.Feature):
36
 
 
37
 
    def _probe(self):
38
 
        try:
39
 
            os.lstat(os.getcwd() + '\\')
40
 
        except OSError:
41
 
            return False
42
 
        else:
43
 
            return True
44
 
 
45
 
    def feature_name(self):
46
 
        return "Filesystem treats '\\' as a directory separator."
47
 
 
48
 
BackslashDirSeparatorFeature = _BackslashDirSeparatorFeature()
49
 
 
50
 
 
51
 
class _RequiredModuleFeature(Feature):
52
 
 
53
 
    def __init__(self, mod_name):
54
 
        self.mod_name = mod_name
55
 
        super(_RequiredModuleFeature, self).__init__()
56
 
 
57
 
    def _probe(self):
58
 
        try:
59
 
            __import__(self.mod_name)
60
 
            return True
61
 
        except ImportError:
62
 
            return False
63
 
 
64
 
    def feature_name(self):
65
 
        return self.mod_name
66
 
 
67
 
Win32RegistryFeature = _RequiredModuleFeature('_winreg')
68
 
CtypesFeature = _RequiredModuleFeature('ctypes')
69
 
Win32comShellFeature = _RequiredModuleFeature('win32com.shell')
70
 
 
71
 
 
72
 
# Tests
73
 
# -----
74
 
 
75
 
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
76
 
 
77
 
    _test_needs_features = []
78
 
 
79
 
    def test_empty_tree(self):
80
 
        self.build_tree([])
81
 
        self._run_testset([
82
 
            [['a'], ['a']],
83
 
            [['?'], ['?']],
84
 
            [['*'], ['*']],
85
 
            [['a', 'a'], ['a', 'a']]])
86
 
 
87
 
    def build_ascii_tree(self):
88
 
        self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
89
 
                         'b', 'b1', 'b2', 'b3',
90
 
                         'c/', 'c/c1', 'c/c2',
91
 
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
92
 
 
93
 
    def build_unicode_tree(self):
94
 
        self.requireFeature(UnicodeFilenameFeature)
95
 
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/',
96
 
                         u'\u1235/\u1235'])
97
 
 
98
 
    def test_tree_ascii(self):
99
 
        """Checks the glob expansion and path separation char
100
 
        normalization"""
101
 
        self.build_ascii_tree()
102
 
        self._run_testset([
103
 
            # no wildcards
104
 
            [[u'a'], [u'a']],
105
 
            [[u'a', u'a' ], [u'a', u'a']],
106
 
 
107
 
            [[u'd'], [u'd']],
108
 
            [[u'd/'], [u'd/']],
109
 
 
110
 
            # wildcards
111
 
            [[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
112
 
            [[u'?'], [u'a', u'b', u'c', u'd']],
113
 
            [[u'a?'], [u'a1', u'a2']],
114
 
            [[u'a??'], [u'a11', u'a.1']],
115
 
            [[u'b[1-2]'], [u'b1', u'b2']],
116
 
 
117
 
            [[u'd/*'], [u'd/d1', u'd/d2', u'd/e']],
118
 
            [[u'?/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
119
 
            [[u'*/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
120
 
            [[u'*/'], [u'c/', u'd/']],
121
 
            ])
122
 
 
123
 
    def test_backslash_globbing(self):
124
 
        self.requireFeature(BackslashDirSeparatorFeature)
125
 
        self.build_ascii_tree()
126
 
        self._run_testset([
127
 
            [[u'd\\'], [u'd/']],
128
 
            [[u'd\\*'], [u'd/d1', u'd/d2', u'd/e']],
129
 
            [[u'?\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
130
 
            [[u'*\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
131
 
            [[u'*\\'], [u'c/', u'd/']],
132
 
            ])
133
 
 
134
 
    def test_case_insensitive_globbing(self):
135
 
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
136
 
        self.build_ascii_tree()
137
 
        self._run_testset([
138
 
            [[u'A'], [u'A']],
139
 
            [[u'A?'], [u'a1', u'a2']],
140
 
            ])
141
 
 
142
 
    def test_tree_unicode(self):
143
 
        """Checks behaviour with non-ascii filenames"""
144
 
        self.build_unicode_tree()
145
 
        self._run_testset([
146
 
            # no wildcards
147
 
            [[u'\u1234'], [u'\u1234']],
148
 
            [[u'\u1235'], [u'\u1235']],
149
 
 
150
 
            [[u'\u1235/'], [u'\u1235/']],
151
 
            [[u'\u1235/\u1235'], [u'\u1235/\u1235']],
152
 
 
153
 
            # wildcards
154
 
            [[u'?'], [u'\u1234', u'\u1235']],
155
 
            [[u'*'], [u'\u1234', u'\u1234\u1234', u'\u1235']],
156
 
            [[u'\u1234*'], [u'\u1234', u'\u1234\u1234']],
157
 
 
158
 
            [[u'\u1235/?'], [u'\u1235/\u1235']],
159
 
            [[u'\u1235/*'], [u'\u1235/\u1235']],
160
 
            [[u'?/'], [u'\u1235/']],
161
 
            [[u'*/'], [u'\u1235/']],
162
 
            [[u'?/?'], [u'\u1235/\u1235']],
163
 
            [[u'*/*'], [u'\u1235/\u1235']],
164
 
            ])
165
 
 
166
 
    def test_unicode_backslashes(self):
167
 
        self.requireFeature(BackslashDirSeparatorFeature)
168
 
        self.build_unicode_tree()
169
 
        self._run_testset([
170
 
            # no wildcards
171
 
            [[u'\u1235\\'], [u'\u1235/']],
172
 
            [[u'\u1235\\\u1235'], [u'\u1235/\u1235']],
173
 
            [[u'\u1235\\?'], [u'\u1235/\u1235']],
174
 
            [[u'\u1235\\*'], [u'\u1235/\u1235']],
175
 
            [[u'?\\'], [u'\u1235/']],
176
 
            [[u'*\\'], [u'\u1235/']],
177
 
            [[u'?\\?'], [u'\u1235/\u1235']],
178
 
            [[u'*\\*'], [u'\u1235/\u1235']],
179
 
            ])
180
 
 
181
 
    def _run_testset(self, testset):
182
 
        for pattern, expected in testset:
183
 
            result = glob_expand(pattern)
184
 
            expected.sort()
185
 
            result.sort()
186
 
            self.assertEqual(expected, result, 'pattern %s' % pattern)
187
 
 
188
 
 
189
 
class TestAppPaths(TestCase):
190
 
 
191
 
    _test_needs_features = [Win32RegistryFeature]
192
 
 
193
 
    def test_iexplore(self):
194
 
        # typical windows users should have IE installed
195
 
        for a in ('iexplore', 'iexplore.exe'):
196
 
            p = get_app_path(a)
197
 
            d, b = os.path.split(p)
198
 
            self.assertEquals('iexplore.exe', b.lower())
199
 
            self.assertNotEquals('', d)
200
 
 
201
 
    def test_wordpad(self):
202
 
        # typical windows users should have wordpad in the system
203
 
        # but there is problem: its path has the format REG_EXPAND_SZ
204
 
        # so naive attempt to get the path is not working
205
 
        for a in ('wordpad', 'wordpad.exe'):
206
 
            p = get_app_path(a)
207
 
            d, b = os.path.split(p)
208
 
            self.assertEquals('wordpad.exe', b.lower())
209
 
            self.assertNotEquals('', d)
210
 
 
211
 
    def test_not_existing(self):
212
 
        p = get_app_path('not-existing')
213
 
        self.assertEquals('not-existing', p)
214
 
 
215
 
 
216
 
class TestLocationsCtypes(TestCase):
217
 
 
218
 
    _test_needs_features = [CtypesFeature]
219
 
 
220
 
    def assertPathsEqual(self, p1, p2):
221
 
        # TODO: The env var values in particular might return the "short"
222
 
        # version (ie, "C:\DOCUME~1\...").  Its even possible the returned
223
 
        # values will differ only by case - handle these situations as we
224
 
        # come across them.
225
 
        self.assertEquals(p1, p2)
226
 
 
227
 
    def test_appdata_not_using_environment(self):
228
 
        # Test that we aren't falling back to the environment
229
 
        first = win32utils.get_appdata_location()
230
 
        self._captureVar("APPDATA", None)
231
 
        self.assertPathsEqual(first, win32utils.get_appdata_location())
232
 
 
233
 
    def test_appdata_matches_environment(self):
234
 
        # Typically the APPDATA environment variable will match
235
 
        # get_appdata_location
236
 
        # XXX - See bug 262874, which asserts the correct encoding is 'mbcs',
237
 
        encoding = osutils.get_user_encoding()
238
 
        env_val = os.environ.get("APPDATA", None)
239
 
        if not env_val:
240
 
            raise TestSkipped("No APPDATA environment variable exists")
241
 
        self.assertPathsEqual(win32utils.get_appdata_location(),
242
 
                              env_val.decode(encoding))
243
 
 
244
 
    def test_local_appdata_not_using_environment(self):
245
 
        # Test that we aren't falling back to the environment
246
 
        first = win32utils.get_local_appdata_location()
247
 
        self._captureVar("LOCALAPPDATA", None)
248
 
        self.assertPathsEqual(first, win32utils.get_local_appdata_location())
249
 
 
250
 
    def test_local_appdata_matches_environment(self):
251
 
        # LOCALAPPDATA typically only exists on Vista, so we only attempt to
252
 
        # compare when it exists.
253
 
        lad = win32utils.get_local_appdata_location()
254
 
        env = os.environ.get("LOCALAPPDATA")
255
 
        if env:
256
 
            # XXX - See bug 262874, which asserts the correct encoding is 'mbcs'
257
 
            encoding = osutils.get_user_encoding()
258
 
            self.assertPathsEqual(lad, env.decode(encoding))
259
 
 
260
 
 
261
 
class TestLocationsPywin32(TestLocationsCtypes):
262
 
 
263
 
    _test_needs_features = [Win32comShellFeature]
264
 
 
265
 
    def setUp(self):
266
 
        super(TestLocationsPywin32, self).setUp()
267
 
        # We perform the exact same tests after disabling the use of ctypes.
268
 
        # This causes the implementation to fall back to pywin32.
269
 
        self.overrideAttr(win32utils, 'has_ctypes', False)
270
 
        # FIXME: this should be done by parametrization -- vila 100123
271
 
 
272
 
 
273
 
class TestSetHidden(TestCaseInTempDir):
274
 
 
275
 
    def test_unicode_dir(self):
276
 
        # we should handle unicode paths without errors
277
 
        self.requireFeature(UnicodeFilenameFeature)
278
 
        os.mkdir(u'\u1234')
279
 
        win32utils.set_file_attr_hidden(u'\u1234')
280
 
 
281
 
    def test_dot_bzr_in_unicode_dir(self):
282
 
        # we should not raise traceback if we try to set hidden attribute
283
 
        # on .bzr directory below unicode path
284
 
        self.requireFeature(UnicodeFilenameFeature)
285
 
        os.makedirs(u'\u1234\\.bzr')
286
 
        path = osutils.abspath(u'\u1234\\.bzr')
287
 
        win32utils.set_file_attr_hidden(path)
288
 
 
289
 
 
290
 
 
291
 
 
292
 
class Test_CommandLineToArgv(tests.TestCaseInTempDir):
293
 
 
294
 
    def assertCommandLine(self, expected, line, single_quotes_allowed=False):
295
 
        # Strictly speaking we should respect parameter order versus glob
296
 
        # expansions, but it's not really worth the effort here
297
 
        argv = win32utils._command_line_to_argv(line,
298
 
                single_quotes_allowed=single_quotes_allowed)
299
 
        self.assertEqual(expected, sorted(argv))
300
 
 
301
 
    def test_glob_paths(self):
302
 
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
303
 
        self.assertCommandLine([u'a/b.c', u'a/c.c'], 'a/*.c')
304
 
        self.build_tree(['b/', 'b/b.c', 'b/d.c', 'b/d.h'])
305
 
        self.assertCommandLine([u'a/b.c', u'b/b.c'], '*/b.c')
306
 
        self.assertCommandLine([u'a/b.c', u'a/c.c', u'b/b.c', u'b/d.c'],
307
 
                               '*/*.c')
308
 
        # Bash style, just pass through the argument if nothing matches
309
 
        self.assertCommandLine([u'*/*.qqq'], '*/*.qqq')
310
 
 
311
 
    def test_quoted_globs(self):
312
 
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
313
 
        self.assertCommandLine([u'a/*.c'], '"a/*.c"')
314
 
        self.assertCommandLine([u"'a/*.c'"], "'a/*.c'")
315
 
        self.assertCommandLine([u'a/*.c'], "'a/*.c'",
316
 
            single_quotes_allowed=True)
317
 
 
318
 
    def test_slashes_changed(self):
319
 
        # Quoting doesn't change the supplied args
320
 
        self.assertCommandLine([u'a\\*.c'], '"a\\*.c"')
321
 
        self.assertCommandLine([u'a\\*.c'], "'a\\*.c'",
322
 
            single_quotes_allowed=True)
323
 
        # Expands the glob, but nothing matches, swaps slashes
324
 
        self.assertCommandLine([u'a/*.c'], 'a\\*.c')
325
 
        self.assertCommandLine([u'a/?.c'], 'a\\?.c')
326
 
        # No glob, doesn't touch slashes
327
 
        self.assertCommandLine([u'a\\foo.c'], 'a\\foo.c')
328
 
 
329
 
    def test_single_quote_support(self):
330
 
        self.assertCommandLine(["add", "let's-do-it.txt"],
331
 
            "add let's-do-it.txt")
332
 
        self.assertCommandLine(["add", "lets do it.txt"],
333
 
            "add 'lets do it.txt'", single_quotes_allowed=True)
334
 
 
335
 
    def test_case_insensitive_globs(self):
336
 
        self.requireFeature(tests.CaseInsCasePresFilenameFeature)
337
 
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
338
 
        self.assertCommandLine([u'A/b.c'], 'A/B*')
339
 
 
340
 
    def test_backslashes(self):
341
 
        self.requireFeature(BackslashDirSeparatorFeature)
342
 
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
343
 
        self.assertCommandLine([u'a/b.c'], 'a\\b*')