~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_win32utils.py

merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
 
17
import os
17
18
import sys
18
19
 
19
20
from bzrlib import osutils
20
 
from bzrlib.tests import TestCase, TestCaseInTempDir, Feature
21
 
from bzrlib.win32utils import glob_expand
 
21
from bzrlib.tests import TestCase, TestCaseInTempDir, TestSkipped, Feature
 
22
from bzrlib.win32utils import glob_expand, get_app_path
 
23
from bzrlib import win32utils
22
24
 
23
25
 
24
26
# Features
35
37
NeedsGlobExpansionFeature = _NeedsGlobExpansionFeature()
36
38
 
37
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
 
38
61
# Tests
39
62
# -----
40
63
 
41
64
class TestNeedsGlobExpansionFeature(TestCase):
42
 
    
 
65
 
43
66
    def test_available(self):
44
 
        self.assertEqual(sys.platform == 'win32', 
 
67
        self.assertEqual(sys.platform == 'win32',
45
68
                         NeedsGlobExpansionFeature.available())
46
 
        
 
69
 
47
70
    def test_str(self):
48
71
        self.assertTrue("performed" in str(NeedsGlobExpansionFeature))
49
72
 
51
74
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
52
75
 
53
76
    _test_needs_features = [NeedsGlobExpansionFeature]
54
 
   
 
77
 
55
78
    def test_empty_tree(self):
56
79
        self.build_tree([])
57
80
        self._run_testset([
59
82
            [['?'], ['?']],
60
83
            [['*'], ['*']],
61
84
            [['a', 'a'], ['a', 'a']]])
62
 
        
 
85
 
63
86
    def test_tree_ascii(self):
64
87
        """Checks the glob expansion and path separation char
65
88
        normalization"""
66
89
        self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
67
90
                         'b', 'b1', 'b2', 'b3',
68
 
                         'c/', 'c/c1', 'c/c2', 
 
91
                         'c/', 'c/c1', 'c/c2',
69
92
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
70
93
        self._run_testset([
71
94
            # no wildcards
72
95
            [[u'a'], [u'a']],
73
96
            [[u'a', u'a' ], [u'a', u'a']],
74
97
            [[u'A'], [u'A']],
75
 
                
 
98
 
76
99
            [[u'd'], [u'd']],
77
100
            [[u'd/'], [u'd/']],
78
101
            [[u'd\\'], [u'd/']],
79
 
            
 
102
 
80
103
            # wildcards
81
104
            [[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
82
105
            [[u'?'], [u'a', u'b', u'c', u'd']],
84
107
            [[u'a??'], [u'a11', u'a.1']],
85
108
            [[u'b[1-2]'], [u'b1', u'b2']],
86
109
            [[u'A?'], [u'a1', u'a2']],
87
 
               
 
110
 
88
111
            [[u'd/*'], [u'd/d1', u'd/d2', u'd/e']],
89
112
            [[u'd\\*'], [u'd/d1', u'd/d2', u'd/e']],
90
113
            [[u'?\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
91
114
            [[u'*\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
92
115
            [[u'*/'], [u'c/', u'd/']],
93
116
            [[u'*\\'], [u'c/', u'd/']]])
94
 
        
 
117
 
95
118
    def test_tree_unicode(self):
96
119
        """Checks behaviour with non-ascii filenames"""
97
120
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/', u'\u1235/\u1235'])
99
122
            # no wildcards
100
123
            [[u'\u1234'], [u'\u1234']],
101
124
            [[u'\u1235'], [u'\u1235']],
102
 
         
 
125
 
103
126
            [[u'\u1235/'], [u'\u1235/']],
104
127
            [[u'\u1235/\u1235'], [u'\u1235/\u1235']],
105
 
            
 
128
 
106
129
            # wildcards
107
130
            [[u'?'], [u'\u1234', u'\u1235']],
108
131
            [[u'*'], [u'\u1234', u'\u1234\u1234', u'\u1235']],
109
132
            [[u'\u1234*'], [u'\u1234', u'\u1234\u1234']],
110
 
            
 
133
 
111
134
            [[u'\u1235/?'], [u'\u1235/\u1235']],
112
135
            [[u'\u1235/*'], [u'\u1235/\u1235']],
113
136
            [[u'\u1235\\?'], [u'\u1235/\u1235']],
128
151
            result.sort()
129
152
            self.assertEqual(expected, result, 'pattern %s' % pattern)
130
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