/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: Canonical.com Patch Queue Manager
  • Date: 2009-07-20 08:56:45 UTC
  • mfrom: (4526.9.23 apply-inventory-delta)
  • Revision ID: pqm@pqm.ubuntu.com-20090720085645-54mtgybxua0yx6hw
(robertc) Add checks for inventory deltas which try to ensure that
        deltas that are not an exact fit are not applied. (Robert
        Collins, bug 397705, bug 367633)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2007 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 osutils
 
21
from bzrlib.tests import (
 
22
    Feature,
 
23
    TestCase,
 
24
    TestCaseInTempDir,
 
25
    TestSkipped,
 
26
    UnicodeFilenameFeature,
 
27
    )
 
28
from bzrlib.win32utils import glob_expand, get_app_path
 
29
from bzrlib import win32utils
 
30
 
 
31
 
 
32
# Features
 
33
# --------
 
34
 
 
35
class _NeedsGlobExpansionFeature(Feature):
 
36
 
 
37
    def _probe(self):
 
38
        return sys.platform == 'win32'
 
39
 
 
40
    def feature_name(self):
 
41
        return 'Internally performed glob expansion'
 
42
 
 
43
NeedsGlobExpansionFeature = _NeedsGlobExpansionFeature()
 
44
 
 
45
 
 
46
class _RequiredModuleFeature(Feature):
 
47
 
 
48
    def __init__(self, mod_name):
 
49
        self.mod_name = mod_name
 
50
        super(_RequiredModuleFeature, self).__init__()
 
51
 
 
52
    def _probe(self):
 
53
        try:
 
54
            __import__(self.mod_name)
 
55
            return True
 
56
        except ImportError:
 
57
            return False
 
58
 
 
59
    def feature_name(self):
 
60
        return self.mod_name
 
61
 
 
62
Win32RegistryFeature = _RequiredModuleFeature('_winreg')
 
63
CtypesFeature = _RequiredModuleFeature('ctypes')
 
64
Win32comShellFeature = _RequiredModuleFeature('win32com.shell')
 
65
 
 
66
 
 
67
# Tests
 
68
# -----
 
69
 
 
70
class TestNeedsGlobExpansionFeature(TestCase):
 
71
 
 
72
    def test_available(self):
 
73
        self.assertEqual(sys.platform == 'win32',
 
74
                         NeedsGlobExpansionFeature.available())
 
75
 
 
76
    def test_str(self):
 
77
        self.assertTrue("performed" in str(NeedsGlobExpansionFeature))
 
78
 
 
79
 
 
80
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
 
81
 
 
82
    _test_needs_features = [NeedsGlobExpansionFeature]
 
83
 
 
84
    def test_empty_tree(self):
 
85
        self.build_tree([])
 
86
        self._run_testset([
 
87
            [['a'], ['a']],
 
88
            [['?'], ['?']],
 
89
            [['*'], ['*']],
 
90
            [['a', 'a'], ['a', 'a']]])
 
91
 
 
92
    def test_tree_ascii(self):
 
93
        """Checks the glob expansion and path separation char
 
94
        normalization"""
 
95
        self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
 
96
                         'b', 'b1', 'b2', 'b3',
 
97
                         'c/', 'c/c1', 'c/c2',
 
98
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
 
99
        self._run_testset([
 
100
            # no wildcards
 
101
            [[u'a'], [u'a']],
 
102
            [[u'a', u'a' ], [u'a', u'a']],
 
103
            [[u'A'], [u'A']],
 
104
 
 
105
            [[u'd'], [u'd']],
 
106
            [[u'd/'], [u'd/']],
 
107
            [[u'd\\'], [u'd/']],
 
108
 
 
109
            # wildcards
 
110
            [[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
 
111
            [[u'?'], [u'a', u'b', u'c', u'd']],
 
112
            [[u'a?'], [u'a1', u'a2']],
 
113
            [[u'a??'], [u'a11', u'a.1']],
 
114
            [[u'b[1-2]'], [u'b1', u'b2']],
 
115
            [[u'A?'], [u'a1', u'a2']],
 
116
 
 
117
            [[u'd/*'], [u'd/d1', u'd/d2', u'd/e']],
 
118
            [[u'd\\*'], [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/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
 
121
            [[u'*/'], [u'c/', u'd/']],
 
122
            [[u'*\\'], [u'c/', u'd/']]])
 
123
 
 
124
    def test_tree_unicode(self):
 
125
        """Checks behaviour with non-ascii filenames"""
 
126
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/', u'\u1235/\u1235'])
 
127
        self._run_testset([
 
128
            # no wildcards
 
129
            [[u'\u1234'], [u'\u1234']],
 
130
            [[u'\u1235'], [u'\u1235']],
 
131
 
 
132
            [[u'\u1235/'], [u'\u1235/']],
 
133
            [[u'\u1235/\u1235'], [u'\u1235/\u1235']],
 
134
 
 
135
            # wildcards
 
136
            [[u'?'], [u'\u1234', u'\u1235']],
 
137
            [[u'*'], [u'\u1234', u'\u1234\u1234', u'\u1235']],
 
138
            [[u'\u1234*'], [u'\u1234', u'\u1234\u1234']],
 
139
 
 
140
            [[u'\u1235/?'], [u'\u1235/\u1235']],
 
141
            [[u'\u1235/*'], [u'\u1235/\u1235']],
 
142
            [[u'\u1235\\?'], [u'\u1235/\u1235']],
 
143
            [[u'\u1235\\*'], [u'\u1235/\u1235']],
 
144
            [[u'?/'], [u'\u1235/']],
 
145
            [[u'*/'], [u'\u1235/']],
 
146
            [[u'?\\'], [u'\u1235/']],
 
147
            [[u'*\\'], [u'\u1235/']],
 
148
            [[u'?/?'], [u'\u1235/\u1235']],
 
149
            [[u'*/*'], [u'\u1235/\u1235']],
 
150
            [[u'?\\?'], [u'\u1235/\u1235']],
 
151
            [[u'*\\*'], [u'\u1235/\u1235']]])
 
152
 
 
153
    def _run_testset(self, testset):
 
154
        for pattern, expected in testset:
 
155
            result = glob_expand(pattern)
 
156
            expected.sort()
 
157
            result.sort()
 
158
            self.assertEqual(expected, result, 'pattern %s' % pattern)
 
159
 
 
160
 
 
161
class TestAppPaths(TestCase):
 
162
 
 
163
    _test_needs_features = [Win32RegistryFeature]
 
164
 
 
165
    def test_iexplore(self):
 
166
        # typical windows users should have IE installed
 
167
        for a in ('iexplore', 'iexplore.exe'):
 
168
            p = get_app_path(a)
 
169
            d, b = os.path.split(p)
 
170
            self.assertEquals('iexplore.exe', b.lower())
 
171
            self.assertNotEquals('', d)
 
172
 
 
173
    def test_wordpad(self):
 
174
        # typical windows users should have wordpad in the system
 
175
        # but there is problem: its path has the format REG_EXPAND_SZ
 
176
        # so naive attempt to get the path is not working
 
177
        for a in ('wordpad', 'wordpad.exe'):
 
178
            p = get_app_path(a)
 
179
            d, b = os.path.split(p)
 
180
            self.assertEquals('wordpad.exe', b.lower())
 
181
            self.assertNotEquals('', d)
 
182
 
 
183
    def test_not_existing(self):
 
184
        p = get_app_path('not-existing')
 
185
        self.assertEquals('not-existing', p)
 
186
 
 
187
 
 
188
class TestLocationsCtypes(TestCase):
 
189
 
 
190
    _test_needs_features = [CtypesFeature]
 
191
 
 
192
    def assertPathsEqual(self, p1, p2):
 
193
        # TODO: The env var values in particular might return the "short"
 
194
        # version (ie, "C:\DOCUME~1\...").  Its even possible the returned
 
195
        # values will differ only by case - handle these situations as we
 
196
        # come across them.
 
197
        self.assertEquals(p1, p2)
 
198
 
 
199
    def test_appdata_not_using_environment(self):
 
200
        # Test that we aren't falling back to the environment
 
201
        first = win32utils.get_appdata_location()
 
202
        self._captureVar("APPDATA", None)
 
203
        self.assertPathsEqual(first, win32utils.get_appdata_location())
 
204
 
 
205
    def test_appdata_matches_environment(self):
 
206
        # Typically the APPDATA environment variable will match
 
207
        # get_appdata_location
 
208
        # XXX - See bug 262874, which asserts the correct encoding is 'mbcs',
 
209
        encoding = osutils.get_user_encoding()
 
210
        env_val = os.environ.get("APPDATA", None)
 
211
        if not env_val:
 
212
            raise TestSkipped("No APPDATA environment variable exists")
 
213
        self.assertPathsEqual(win32utils.get_appdata_location(),
 
214
                              env_val.decode(encoding))
 
215
 
 
216
    def test_local_appdata_not_using_environment(self):
 
217
        # Test that we aren't falling back to the environment
 
218
        first = win32utils.get_local_appdata_location()
 
219
        self._captureVar("LOCALAPPDATA", None)
 
220
        self.assertPathsEqual(first, win32utils.get_local_appdata_location())
 
221
 
 
222
    def test_local_appdata_matches_environment(self):
 
223
        # LOCALAPPDATA typically only exists on Vista, so we only attempt to
 
224
        # compare when it exists.
 
225
        lad = win32utils.get_local_appdata_location()
 
226
        env = os.environ.get("LOCALAPPDATA")
 
227
        if env:
 
228
            # XXX - See bug 262874, which asserts the correct encoding is 'mbcs'
 
229
            encoding = osutils.get_user_encoding()
 
230
            self.assertPathsEqual(lad, env.decode(encoding))
 
231
 
 
232
 
 
233
class TestLocationsPywin32(TestLocationsCtypes):
 
234
 
 
235
    _test_needs_features = [Win32comShellFeature]
 
236
 
 
237
    def setUp(self):
 
238
        super(TestLocationsPywin32, self).setUp()
 
239
        # We perform the exact same tests after disabling the use of ctypes.
 
240
        # This causes the implementation to fall back to pywin32.
 
241
        self.old_ctypes = win32utils.has_ctypes
 
242
        win32utils.has_ctypes = False
 
243
        self.addCleanup(self.restoreCtypes)
 
244
 
 
245
    def restoreCtypes(self):
 
246
        win32utils.has_ctypes = self.old_ctypes
 
247
 
 
248
 
 
249
class TestSetHidden(TestCaseInTempDir):
 
250
 
 
251
    def test_unicode_dir(self):
 
252
        # we should handle unicode paths without errors
 
253
        self.requireFeature(UnicodeFilenameFeature)
 
254
        os.mkdir(u'\u1234')
 
255
        win32utils.set_file_attr_hidden(u'\u1234')
 
256
 
 
257
    def test_dot_bzr_in_unicode_dir(self):
 
258
        # we should not raise traceback if we try to set hidden attribute
 
259
        # on .bzr directory below unicode path
 
260
        self.requireFeature(UnicodeFilenameFeature)
 
261
        os.makedirs(u'\u1234\\.bzr')
 
262
        path = osutils.abspath(u'\u1234\\.bzr')
 
263
        win32utils.set_file_attr_hidden(path)