~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_win32utils.py

- add short-form of testaments

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