~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2007-2011 Canonical Ltd
2617.5.1 by Kuno Meyer
Added direct unit tests for win32utils.glob_expand().
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2617.5.1 by Kuno Meyer
Added direct unit tests for win32utils.glob_expand().
16
5241.2.1 by Robert Collins
Merge up from 2.0/2.1:
17
"""Tests for win32utils."""
18
2681.4.2 by Alexander Belchenko
test for get_app_path
19
import os
2617.5.4 by Kuno Meyer
Included feedback on initial patch.
20
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
21
from bzrlib import (
22
    osutils,
6362.2.6 by Martin Packman
Add tests for deprecated unicode wrapper functions in win32utils
23
    symbol_versioning,
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
24
    tests,
25
    win32utils,
26
    )
4505.2.4 by Alexander Belchenko
guard tests with UnicodeFilenameFeature.
27
from bzrlib.tests import (
28
    TestCase,
29
    TestCaseInTempDir,
30
    TestSkipped,
31
    )
5241.2.1 by Robert Collins
Merge up from 2.0/2.1:
32
from bzrlib.tests.features import backslashdir_feature
2681.4.2 by Alexander Belchenko
test for get_app_path
33
from bzrlib.win32utils import glob_expand, get_app_path
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
34
from bzrlib.tests import (
35
    features,
36
    )
37
38
39
Win32RegistryFeature = features.ModuleAvailableFeature('_winreg')
40
CtypesFeature = features.ModuleAvailableFeature('ctypes')
41
Win32comShellFeature = features.ModuleAvailableFeature('win32com.shell')
42
Win32ApiFeature = features.ModuleAvailableFeature('win32api') 
2681.4.4 by Alexander Belchenko
test use Feature instead of TestSkipped
43
5314.1.2 by Jason Spashett
Adition of blank line for formatting.
44
2617.5.4 by Kuno Meyer
Included feedback on initial patch.
45
# Tests
46
# -----
2617.5.6 by Kuno Meyer
Incorporated feedback from the mailinglist.
47
2617.5.4 by Kuno Meyer
Included feedback on initial patch.
48
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
2617.5.2 by Kuno Meyer
just reformatting
49
4789.20.1 by John Arbash Meinel
Updates to tests that were exercising filesystem globbing.
50
    _test_needs_features = []
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
51
2617.5.1 by Kuno Meyer
Added direct unit tests for win32utils.glob_expand().
52
    def test_empty_tree(self):
53
        self.build_tree([])
2617.5.2 by Kuno Meyer
just reformatting
54
        self._run_testset([
55
            [['a'], ['a']],
56
            [['?'], ['?']],
57
            [['*'], ['*']],
58
            [['a', 'a'], ['a', 'a']]])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
59
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
60
    def build_ascii_tree(self):
2617.5.1 by Kuno Meyer
Added direct unit tests for win32utils.glob_expand().
61
        self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
62
                         'b', 'b1', 'b2', 'b3',
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
63
                         'c/', 'c/c1', 'c/c2',
2617.5.4 by Kuno Meyer
Included feedback on initial patch.
64
                         'd/', 'd/d1', 'd/d2', 'd/e/', 'd/e/e1'])
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
65
66
    def build_unicode_tree(self):
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
67
        self.requireFeature(features.UnicodeFilenameFeature)
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
68
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/',
69
                         u'\u1235/\u1235'])
70
71
    def test_tree_ascii(self):
72
        """Checks the glob expansion and path separation char
73
        normalization"""
74
        self.build_ascii_tree()
2617.5.2 by Kuno Meyer
just reformatting
75
        self._run_testset([
76
            # no wildcards
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
77
            [[u'a'], [u'a']],
78
            [[u'a', u'a' ], [u'a', u'a']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
79
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
80
            [[u'd'], [u'd']],
81
            [[u'd/'], [u'd/']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
82
2617.5.2 by Kuno Meyer
just reformatting
83
            # wildcards
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
84
            [[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
85
            [[u'?'], [u'a', u'b', u'c', u'd']],
86
            [[u'a?'], [u'a1', u'a2']],
87
            [[u'a??'], [u'a11', u'a.1']],
88
            [[u'b[1-2]'], [u'b1', u'b2']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
89
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
90
            [[u'd/*'], [u'd/d1', u'd/d2', u'd/e']],
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
91
            [[u'?/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
92
            [[u'*/*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
93
            [[u'*/'], [u'c/', u'd/']],
94
            ])
95
96
    def test_backslash_globbing(self):
5241.2.1 by Robert Collins
Merge up from 2.0/2.1:
97
        self.requireFeature(backslashdir_feature)
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
98
        self.build_ascii_tree()
99
        self._run_testset([
100
            [[u'd\\'], [u'd/']],
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
101
            [[u'd\\*'], [u'd/d1', u'd/d2', u'd/e']],
102
            [[u'?\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
103
            [[u'*\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
104
            [[u'*\\'], [u'c/', u'd/']],
105
            ])
106
107
    def test_case_insensitive_globbing(self):
5551.2.1 by Martin
Make case win32utils insensitive globbing tests skip more correctly to stop failures on OSX
108
        if os.path.normcase("AbC") == "AbC":
109
            self.skip("Test requires case insensitive globbing function")
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
110
        self.build_ascii_tree()
111
        self._run_testset([
112
            [[u'A'], [u'A']],
113
            [[u'A?'], [u'a1', u'a2']],
114
            ])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
115
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
116
    def test_tree_unicode(self):
2617.5.7 by Kuno Meyer
Fix for non-ASCII filenames
117
        """Checks behaviour with non-ascii filenames"""
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
118
        self.build_unicode_tree()
2617.5.7 by Kuno Meyer
Fix for non-ASCII filenames
119
        self._run_testset([
120
            # no wildcards
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
121
            [[u'\u1234'], [u'\u1234']],
122
            [[u'\u1235'], [u'\u1235']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
123
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
124
            [[u'\u1235/'], [u'\u1235/']],
125
            [[u'\u1235/\u1235'], [u'\u1235/\u1235']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
126
2617.5.7 by Kuno Meyer
Fix for non-ASCII filenames
127
            # wildcards
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
128
            [[u'?'], [u'\u1234', u'\u1235']],
129
            [[u'*'], [u'\u1234', u'\u1234\u1234', u'\u1235']],
130
            [[u'\u1234*'], [u'\u1234', u'\u1234\u1234']],
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
131
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
132
            [[u'\u1235/?'], [u'\u1235/\u1235']],
133
            [[u'\u1235/*'], [u'\u1235/\u1235']],
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
134
            [[u'?/'], [u'\u1235/']],
135
            [[u'*/'], [u'\u1235/']],
136
            [[u'?/?'], [u'\u1235/\u1235']],
137
            [[u'*/*'], [u'\u1235/\u1235']],
138
            ])
139
140
    def test_unicode_backslashes(self):
5241.2.1 by Robert Collins
Merge up from 2.0/2.1:
141
        self.requireFeature(backslashdir_feature)
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
142
        self.build_unicode_tree()
143
        self._run_testset([
144
            # no wildcards
4789.20.3 by John Arbash Meinel
Use the right case sensitivity feature (cicp, not just ci).
145
            [[u'\u1235\\'], [u'\u1235/']],
146
            [[u'\u1235\\\u1235'], [u'\u1235/\u1235']],
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
147
            [[u'\u1235\\?'], [u'\u1235/\u1235']],
148
            [[u'\u1235\\*'], [u'\u1235/\u1235']],
149
            [[u'?\\'], [u'\u1235/']],
150
            [[u'*\\'], [u'\u1235/']],
151
            [[u'?\\?'], [u'\u1235/\u1235']],
4789.20.2 by John Arbash Meinel
Split the win32 globbing tests up a bit.
152
            [[u'*\\*'], [u'\u1235/\u1235']],
153
            ])
2617.5.7 by Kuno Meyer
Fix for non-ASCII filenames
154
2617.5.1 by Kuno Meyer
Added direct unit tests for win32utils.glob_expand().
155
    def _run_testset(self, testset):
156
        for pattern, expected in testset:
157
            result = glob_expand(pattern)
158
            expected.sort()
159
            result.sort()
160
            self.assertEqual(expected, result, 'pattern %s' % pattern)
2617.5.2 by Kuno Meyer
just reformatting
161
2681.4.2 by Alexander Belchenko
test for get_app_path
162
163
class TestAppPaths(TestCase):
164
2681.4.4 by Alexander Belchenko
test use Feature instead of TestSkipped
165
    _test_needs_features = [Win32RegistryFeature]
166
2681.4.2 by Alexander Belchenko
test for get_app_path
167
    def test_iexplore(self):
168
        # typical windows users should have IE installed
169
        for a in ('iexplore', 'iexplore.exe'):
170
            p = get_app_path(a)
171
            d, b = os.path.split(p)
3146.4.9 by Aaron Bentley
do case-insensitive comparision of iexplore filename
172
            self.assertEquals('iexplore.exe', b.lower())
2681.4.2 by Alexander Belchenko
test for get_app_path
173
            self.assertNotEquals('', d)
174
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
175
    def test_wordpad(self):
176
        # typical windows users should have wordpad in the system
177
        # but there is problem: its path has the format REG_EXPAND_SZ
178
        # so naive attempt to get the path is not working
5314.1.1 by Jason Spashett
Change test_win32utils.py so as not to fail tests if win32api module is not present.
179
        self.requireFeature(Win32ApiFeature)
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
180
        for a in ('wordpad', 'wordpad.exe'):
181
            p = get_app_path(a)
182
            d, b = os.path.split(p)
183
            self.assertEquals('wordpad.exe', b.lower())
184
            self.assertNotEquals('', d)
185
2681.4.2 by Alexander Belchenko
test for get_app_path
186
    def test_not_existing(self):
187
        p = get_app_path('not-existing')
188
        self.assertEquals('not-existing', p)
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
189
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
190
6362.2.6 by Martin Packman
Add tests for deprecated unicode wrapper functions in win32utils
191
class TestLocations(TestCase):
192
    """Tests for windows specific path and name retrieving functions"""
193
194
    def test__ensure_unicode_deprecated(self):
195
        s = "text"
196
        u1 = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
197
            win32utils._ensure_unicode, s)
198
        self.assertEqual(s, u1)
199
        self.assertIsInstance(u1, unicode)
200
        u2 = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
201
            win32utils._ensure_unicode, u1)
202
        self.assertIs(u1, u2)
203
    
204
    def test_appdata_unicode_deprecated(self):
205
        self.overrideEnv("APPDATA", "fakepath")
206
        s = win32utils.get_appdata_location()
207
        u = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
208
            win32utils.get_appdata_location_unicode)
209
        self.assertEqual(s, u)
210
        self.assertIsInstance(s, unicode)
211
212
    def test_home_unicode_deprecated(self):
213
        s = win32utils.get_home_location()
214
        u = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
215
            win32utils.get_home_location_unicode)
216
        self.assertEqual(s, u)
217
        self.assertIsInstance(s, unicode)
218
219
    def test_user_unicode_deprecated(self):
220
        self.overrideEnv("USERNAME", "alien")
221
        s = win32utils.get_user_name()
222
        u = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
223
            win32utils.get_user_name_unicode)
224
        self.assertEqual(s, u)
225
        self.assertIsInstance(s, unicode)
226
227
    def test_host_unicode_deprecated(self):
228
        self.overrideEnv("COMPUTERNAME", "alienbox")
229
        s = win32utils.get_host_name()
230
        u = self.applyDeprecated(symbol_versioning.deprecated_in((2, 5, 0)),
231
            win32utils.get_host_name_unicode)
232
        self.assertEqual(s, u)
233
        self.assertIsInstance(s, unicode)
234
235
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
236
class TestLocationsCtypes(TestCase):
237
238
    _test_needs_features = [CtypesFeature]
239
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
240
    def assertPathsEqual(self, p1, p2):
241
        # TODO: The env var values in particular might return the "short"
242
        # version (ie, "C:\DOCUME~1\...").  Its even possible the returned
243
        # values will differ only by case - handle these situations as we
244
        # come across them.
245
        self.assertEquals(p1, p2)
246
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
247
    def test_appdata_not_using_environment(self):
248
        # Test that we aren't falling back to the environment
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
249
        first = win32utils.get_appdata_location()
5570.3.6 by Vincent Ladeuil
Get rid of all _captureVar() calls, no test failures, pfew.
250
        self.overrideEnv("APPDATA", None)
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
251
        self.assertPathsEqual(first, win32utils.get_appdata_location())
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
252
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
253
    def test_appdata_matches_environment(self):
254
        # Typically the APPDATA environment variable will match
255
        # get_appdata_location
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
256
        # XXX - See bug 262874, which asserts the correct encoding is 'mbcs',
257
        encoding = osutils.get_user_encoding()
3638.4.6 by Mark Hammond
Skip the environment checks when APPDATA isn't in the environment.
258
        env_val = os.environ.get("APPDATA", None)
259
        if not env_val:
260
            raise TestSkipped("No APPDATA environment variable exists")
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
261
        self.assertPathsEqual(win32utils.get_appdata_location(),
3638.4.6 by Mark Hammond
Skip the environment checks when APPDATA isn't in the environment.
262
                              env_val.decode(encoding))
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
263
264
    def test_local_appdata_not_using_environment(self):
265
        # Test that we aren't falling back to the environment
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
266
        first = win32utils.get_local_appdata_location()
5570.3.6 by Vincent Ladeuil
Get rid of all _captureVar() calls, no test failures, pfew.
267
        self.overrideEnv("LOCALAPPDATA", None)
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
268
        self.assertPathsEqual(first, win32utils.get_local_appdata_location())
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
269
270
    def test_local_appdata_matches_environment(self):
271
        # LOCALAPPDATA typically only exists on Vista, so we only attempt to
272
        # compare when it exists.
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
273
        lad = win32utils.get_local_appdata_location()
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
274
        env = os.environ.get("LOCALAPPDATA")
275
        if env:
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
276
            # XXX - See bug 262874, which asserts the correct encoding is 'mbcs'
277
            encoding = osutils.get_user_encoding()
278
            self.assertPathsEqual(lad, env.decode(encoding))
279
280
281
class TestLocationsPywin32(TestLocationsCtypes):
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
282
283
    _test_needs_features = [Win32comShellFeature]
284
285
    def setUp(self):
3638.4.3 by Mark Hammond
cleanup tests, rationalize path checking etc.
286
        super(TestLocationsPywin32, self).setUp()
287
        # We perform the exact same tests after disabling the use of ctypes.
288
        # This causes the implementation to fall back to pywin32.
4985.1.5 by Vincent Ladeuil
Deploying the new overrideAttr facility further reduces the complexity
289
        self.overrideAttr(win32utils, 'has_ctypes', False)
290
        # FIXME: this should be done by parametrization -- vila 100123
4505.2.1 by Alexander Belchenko
Set hidden attribute on .bzr directory below unicode path should never fail with error. The operation should succeed even if bzr unable to set the attribute. (related to bug #335362).
291
292
293
class TestSetHidden(TestCaseInTempDir):
294
4505.2.3 by Alexander Belchenko
added direct test for absolute path.
295
    def test_unicode_dir(self):
296
        # we should handle unicode paths without errors
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
297
        self.requireFeature(features.UnicodeFilenameFeature)
4505.2.3 by Alexander Belchenko
added direct test for absolute path.
298
        os.mkdir(u'\u1234')
299
        win32utils.set_file_attr_hidden(u'\u1234')
300
301
    def test_dot_bzr_in_unicode_dir(self):
4505.2.1 by Alexander Belchenko
Set hidden attribute on .bzr directory below unicode path should never fail with error. The operation should succeed even if bzr unable to set the attribute. (related to bug #335362).
302
        # we should not raise traceback if we try to set hidden attribute
303
        # on .bzr directory below unicode path
5967.12.1 by Martin Pool
Move all test features into bzrlib.tests.features
304
        self.requireFeature(features.UnicodeFilenameFeature)
4505.2.3 by Alexander Belchenko
added direct test for absolute path.
305
        os.makedirs(u'\u1234\\.bzr')
306
        path = osutils.abspath(u'\u1234\\.bzr')
307
        win32utils.set_file_attr_hidden(path)
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
308
309
310
class Test_CommandLineToArgv(tests.TestCaseInTempDir):
311
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
312
    def assertCommandLine(self, expected, line, argv=None,
313
            single_quotes_allowed=False):
4789.3.2 by Vincent Ladeuil
Add a comment precising why we sort the results of _command_line_to_argv.
314
        # Strictly speaking we should respect parameter order versus glob
315
        # expansions, but it's not really worth the effort here
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
316
        if argv is None:
317
            argv = [line]
318
        argv = win32utils._command_line_to_argv(line, argv,
4913.5.11 by Gordon Tyler
Added optional single quote support to UnicodeShlex and thus command_line_to_argv (defaults to disabled).
319
                single_quotes_allowed=single_quotes_allowed)
320
        self.assertEqual(expected, sorted(argv))
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
321
322
    def test_glob_paths(self):
323
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
324
        self.assertCommandLine([u'a/b.c', u'a/c.c'], 'a/*.c')
325
        self.build_tree(['b/', 'b/b.c', 'b/d.c', 'b/d.h'])
326
        self.assertCommandLine([u'a/b.c', u'b/b.c'], '*/b.c')
327
        self.assertCommandLine([u'a/b.c', u'a/c.c', u'b/b.c', u'b/d.c'],
328
                               '*/*.c')
329
        # Bash style, just pass through the argument if nothing matches
330
        self.assertCommandLine([u'*/*.qqq'], '*/*.qqq')
331
332
    def test_quoted_globs(self):
333
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
334
        self.assertCommandLine([u'a/*.c'], '"a/*.c"')
4789.1.1 by Alexander Belchenko
In standard windows shell single quote is not supported as quote. Restored standard windows behavior.
335
        self.assertCommandLine([u"'a/*.c'"], "'a/*.c'")
4913.5.11 by Gordon Tyler
Added optional single quote support to UnicodeShlex and thus command_line_to_argv (defaults to disabled).
336
        self.assertCommandLine([u'a/*.c'], "'a/*.c'",
337
            single_quotes_allowed=True)
4786.1.2 by John Arbash Meinel
Refactor the glob_expand code a bit, making the inner function more reusable.
338
339
    def test_slashes_changed(self):
4818.1.1 by John Arbash Meinel
Fix bug #485771. Only change '/' to '/' when expanding globs.
340
        # Quoting doesn't change the supplied args
341
        self.assertCommandLine([u'a\\*.c'], '"a\\*.c"')
4913.5.11 by Gordon Tyler
Added optional single quote support to UnicodeShlex and thus command_line_to_argv (defaults to disabled).
342
        self.assertCommandLine([u'a\\*.c'], "'a\\*.c'",
343
            single_quotes_allowed=True)
4818.1.1 by John Arbash Meinel
Fix bug #485771. Only change '/' to '/' when expanding globs.
344
        # Expands the glob, but nothing matches, swaps slashes
4786.1.2 by John Arbash Meinel
Refactor the glob_expand code a bit, making the inner function more reusable.
345
        self.assertCommandLine([u'a/*.c'], 'a\\*.c')
4818.1.1 by John Arbash Meinel
Fix bug #485771. Only change '/' to '/' when expanding globs.
346
        self.assertCommandLine([u'a/?.c'], 'a\\?.c')
347
        # No glob, doesn't touch slashes
348
        self.assertCommandLine([u'a\\foo.c'], 'a\\foo.c')
4789.1.1 by Alexander Belchenko
In standard windows shell single quote is not supported as quote. Restored standard windows behavior.
349
4913.5.11 by Gordon Tyler
Added optional single quote support to UnicodeShlex and thus command_line_to_argv (defaults to disabled).
350
    def test_single_quote_support(self):
4789.1.1 by Alexander Belchenko
In standard windows shell single quote is not supported as quote. Restored standard windows behavior.
351
        self.assertCommandLine(["add", "let's-do-it.txt"],
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
352
            "add let's-do-it.txt",
353
            ["add", "let's-do-it.txt"])
354
        self.expectFailure("Using single quotes breaks trimming from argv",
355
            self.assertCommandLine, ["add", "lets do it.txt"],
356
            "add 'lets do it.txt'", ["add", "'lets", "do", "it.txt'"],
357
            single_quotes_allowed=True)
4797.3.20 by John Arbash Meinel
Include the glob updates.
358
4789.20.3 by John Arbash Meinel
Use the right case sensitivity feature (cicp, not just ci).
359
    def test_case_insensitive_globs(self):
5551.2.1 by Martin
Make case win32utils insensitive globbing tests skip more correctly to stop failures on OSX
360
        if os.path.normcase("AbC") == "AbC":
361
            self.skip("Test requires case insensitive globbing function")
4789.20.3 by John Arbash Meinel
Use the right case sensitivity feature (cicp, not just ci).
362
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
363
        self.assertCommandLine([u'A/b.c'], 'A/B*')
364
365
    def test_backslashes(self):
5241.2.1 by Robert Collins
Merge up from 2.0/2.1:
366
        self.requireFeature(backslashdir_feature)
4789.20.3 by John Arbash Meinel
Use the right case sensitivity feature (cicp, not just ci).
367
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
368
        self.assertCommandLine([u'a/b.c'], 'a\\b*')
5274.4.13 by Martin
Add test for lp:587868 to win32 commandline tests
369
370
    def test_with_pdb(self):
371
        """Check stripping Python arguments before bzr script per lp:587868"""
372
        self.assertCommandLine([u"rocks"], "-m pdb rocks", ["rocks"])
373
        self.build_tree(['d/', 'd/f1', 'd/f2'])
374
        self.assertCommandLine([u"rm", u"x*"], "-m pdb rm x*", ["rm", u"x*"])
375
        self.assertCommandLine([u"add", u"d/f1", u"d/f2"], "-m pdb add d/*",
376
            ["add", u"d/*"])
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
377
378
379
class TestGetEnvironUnicode(tests.TestCase):
380
    """Tests for accessing the environment via the windows wide api"""
381
382
    _test_needs_features = [CtypesFeature, features.win32_feature]
383
384
    def setUp(self):
385
        super(TestGetEnvironUnicode, self).setUp()
386
        self.overrideEnv("TEST", "1")
387
388
    def test_get(self):
389
        """In the normal case behaves the same as os.environ access"""
390
        self.assertEqual("1", win32utils.get_environ_unicode("TEST"))
391
392
    def test_unset(self):
393
        """A variable not present in the environment gives None by default"""
394
        del os.environ["TEST"]
395
        self.assertIs(None, win32utils.get_environ_unicode("TEST"))
396
397
    def test_unset_default(self):
398
        """A variable not present in the environment gives passed default"""
399
        del os.environ["TEST"]
400
        self.assertIs("a", win32utils.get_environ_unicode("TEST", "a"))
401
402
    def test_unicode(self):
403
        """A non-ascii variable is returned as unicode"""
404
        unicode_val = u"\xa7" # non-ascii character present in many encodings
405
        try:
406
            bytes_val = unicode_val.encode(osutils.get_user_encoding())
407
        except UnicodeEncodeError:
408
            self.skip("Couldn't encode non-ascii string to place in environ")
409
        os.environ["TEST"] = bytes_val
410
        self.assertEqual(unicode_val, win32utils.get_environ_unicode("TEST"))
411
412
    def test_long(self):
413
        """A variable bigger than heuristic buffer size is still accessible"""
414
        big_val = "x" * (2<<10)
415
        os.environ["TEST"] = big_val
416
        self.assertEqual(big_val, win32utils.get_environ_unicode("TEST"))
417
418
    def test_unexpected_error(self):
419
        """An error from the underlying platform function is propogated"""
420
        ERROR_INVALID_PARAMETER = 87
421
        SetLastError = win32utils.ctypes.windll.kernel32.SetLastError
422
        def failer(*args, **kwargs):
423
            SetLastError(ERROR_INVALID_PARAMETER)
424
            return 0
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
425
        self.overrideAttr(win32utils.get_environ_unicode, "_c_function",
426
            failer)
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
427
        e = self.assertRaises(WindowsError,
428
            win32utils.get_environ_unicode, "TEST")
429
        self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER)