/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

Rework test_script a little bit.


Don't allow someone to request a stdin request to echo.
Echo never reads from stdin, it just echos its arguments.
You use 'cat' if you want to read from stdin.

A few other fixes because the tests were using filenames
that are actually illegal on Windows, rather than just
nonexistant.


Change the exception handling for commands so that
unknown errors don't get silently squashed and then
turn into hard-to-debug errors later.

test_script now passes on Windows.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2010 Canonical Ltd
 
1
# Copyright (C) 2007 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
32
32
from bzrlib.win32utils import glob_expand, get_app_path
33
33
 
34
34
 
35
 
class _BackslashDirSeparatorFeature(tests.Feature):
 
35
# Features
 
36
# --------
 
37
 
 
38
class _NeedsGlobExpansionFeature(Feature):
36
39
 
37
40
    def _probe(self):
38
 
        try:
39
 
            os.lstat(os.getcwd() + '\\')
40
 
        except OSError:
41
 
            return False
42
 
        else:
43
 
            return True
 
41
        return sys.platform == 'win32'
44
42
 
45
43
    def feature_name(self):
46
 
        return "Filesystem treats '\\' as a directory separator."
 
44
        return 'Internally performed glob expansion'
47
45
 
48
 
BackslashDirSeparatorFeature = _BackslashDirSeparatorFeature()
 
46
NeedsGlobExpansionFeature = _NeedsGlobExpansionFeature()
49
47
 
50
48
 
51
49
class _RequiredModuleFeature(Feature):
72
70
# Tests
73
71
# -----
74
72
 
 
73
class TestNeedsGlobExpansionFeature(TestCase):
 
74
 
 
75
    def test_available(self):
 
76
        self.assertEqual(sys.platform == 'win32',
 
77
                         NeedsGlobExpansionFeature.available())
 
78
 
 
79
    def test_str(self):
 
80
        self.assertTrue("performed" in str(NeedsGlobExpansionFeature))
 
81
 
 
82
 
75
83
class TestWin32UtilsGlobExpand(TestCaseInTempDir):
76
84
 
77
 
    _test_needs_features = []
 
85
    _test_needs_features = [NeedsGlobExpansionFeature]
78
86
 
79
87
    def test_empty_tree(self):
80
88
        self.build_tree([])
84
92
            [['*'], ['*']],
85
93
            [['a', 'a'], ['a', 'a']]])
86
94
 
87
 
    def build_ascii_tree(self):
 
95
    def test_tree_ascii(self):
 
96
        """Checks the glob expansion and path separation char
 
97
        normalization"""
88
98
        self.build_tree(['a', 'a1', 'a2', 'a11', 'a.1',
89
99
                         'b', 'b1', 'b2', 'b3',
90
100
                         'c/', 'c/c1', 'c/c2',
91
101
                         '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
102
        self._run_testset([
103
103
            # no wildcards
104
104
            [[u'a'], [u'a']],
105
105
            [[u'a', u'a' ], [u'a', u'a']],
 
106
            [[u'A'], [u'A']],
106
107
 
107
108
            [[u'd'], [u'd']],
108
109
            [[u'd/'], [u'd/']],
 
110
            [[u'd\\'], [u'd/']],
109
111
 
110
112
            # wildcards
111
113
            [[u'a*'], [u'a', u'a1', u'a2', u'a11', u'a.1']],
113
115
            [[u'a?'], [u'a1', u'a2']],
114
116
            [[u'a??'], [u'a11', u'a.1']],
115
117
            [[u'b[1-2]'], [u'b1', u'b2']],
 
118
            [[u'A?'], [u'a1', u'a2']],
116
119
 
117
120
            [[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
121
            [[u'd\\*'], [u'd/d1', u'd/d2', u'd/e']],
129
122
            [[u'?\\*'], [u'c/c1', u'c/c2', u'd/d1', u'd/d2', u'd/e']],
130
123
            [[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
 
            ])
 
124
            [[u'*/'], [u'c/', u'd/']],
 
125
            [[u'*\\'], [u'c/', u'd/']]])
141
126
 
142
127
    def test_tree_unicode(self):
143
128
        """Checks behaviour with non-ascii filenames"""
144
 
        self.build_unicode_tree()
 
129
        self.build_tree([u'\u1234', u'\u1234\u1234', u'\u1235/', u'\u1235/\u1235'])
145
130
        self._run_testset([
146
131
            # no wildcards
147
132
            [[u'\u1234'], [u'\u1234']],
157
142
 
158
143
            [[u'\u1235/?'], [u'\u1235/\u1235']],
159
144
            [[u'\u1235/*'], [u'\u1235/\u1235']],
 
145
            [[u'\u1235\\?'], [u'\u1235/\u1235']],
 
146
            [[u'\u1235\\*'], [u'\u1235/\u1235']],
160
147
            [[u'?/'], [u'\u1235/']],
161
148
            [[u'*/'], [u'\u1235/']],
 
149
            [[u'?\\'], [u'\u1235/']],
 
150
            [[u'*\\'], [u'\u1235/']],
162
151
            [[u'?/?'], [u'\u1235/\u1235']],
163
152
            [[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
153
            [[u'?\\?'], [u'\u1235/\u1235']],
178
 
            [[u'*\\*'], [u'\u1235/\u1235']],
179
 
            ])
 
154
            [[u'*\\*'], [u'\u1235/\u1235']]])
180
155
 
181
156
    def _run_testset(self, testset):
182
157
        for pattern, expected in testset:
266
241
        super(TestLocationsPywin32, self).setUp()
267
242
        # We perform the exact same tests after disabling the use of ctypes.
268
243
        # 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
 
244
        self.old_ctypes = win32utils.has_ctypes
 
245
        win32utils.has_ctypes = False
 
246
        self.addCleanup(self.restoreCtypes)
 
247
 
 
248
    def restoreCtypes(self):
 
249
        win32utils.has_ctypes = self.old_ctypes
271
250
 
272
251
 
273
252
class TestSetHidden(TestCaseInTempDir):
288
267
 
289
268
 
290
269
 
 
270
class TestUnicodeShlex(tests.TestCase):
 
271
 
 
272
    def assertAsTokens(self, expected, line):
 
273
        s = win32utils.UnicodeShlex(line)
 
274
        self.assertEqual(expected, list(s))
 
275
 
 
276
    def test_simple(self):
 
277
        self.assertAsTokens([(False, u'foo'), (False, u'bar'), (False, u'baz')],
 
278
                            u'foo bar baz')
 
279
 
 
280
    def test_ignore_multiple_spaces(self):
 
281
        self.assertAsTokens([(False, u'foo'), (False, u'bar')], u'foo  bar')
 
282
 
 
283
    def test_ignore_leading_space(self):
 
284
        self.assertAsTokens([(False, u'foo'), (False, u'bar')], u'  foo bar')
 
285
 
 
286
    def test_ignore_trailing_space(self):
 
287
        self.assertAsTokens([(False, u'foo'), (False, u'bar')], u'foo bar  ')
 
288
 
 
289
    def test_posix_quotations(self):
 
290
        self.assertAsTokens([(True, u'foo bar')], u'"foo bar"')
 
291
        self.assertAsTokens([(True, u'foo bar')], u"'foo bar'")
 
292
        self.assertAsTokens([(True, u'foo bar')], u"'fo''o b''ar'")
 
293
        self.assertAsTokens([(True, u'foo bar')], u'"fo""o b""ar"')
 
294
        self.assertAsTokens([(True, u'foo bar')], u'"fo"\'o b\'"ar"')
 
295
 
 
296
    def test_nested_quotations(self):
 
297
        self.assertAsTokens([(True, u'foo"" bar')], u"'foo\"\" bar'")
 
298
        self.assertAsTokens([(True, u'foo\'\' bar')], u"\"foo'' bar\"")
 
299
 
 
300
    def test_empty_result(self):
 
301
        self.assertAsTokens([], u'')
 
302
        self.assertAsTokens([], u'    ')
 
303
 
 
304
    def test_quoted_empty(self):
 
305
        self.assertAsTokens([(True, '')], u'""')
 
306
        self.assertAsTokens([(True, '')], u"''")
 
307
 
 
308
    def test_unicode_chars(self):
 
309
        self.assertAsTokens([(False, u'f\xb5\xee'), (False, u'\u1234\u3456')],
 
310
                             u'f\xb5\xee \u1234\u3456')
 
311
 
 
312
    def test_newline_in_quoted_section(self):
 
313
        self.assertAsTokens([(True, u'foo\nbar\nbaz\n')], u'"foo\nbar\nbaz\n"')
 
314
        self.assertAsTokens([(True, u'foo\nbar\nbaz\n')], u"'foo\nbar\nbaz\n'")
 
315
 
 
316
    def test_escape_chars(self):
 
317
        self.assertAsTokens([(False, u'foo\\bar')], u'foo\\bar')
 
318
 
 
319
    def test_escape_quote(self):
 
320
        self.assertAsTokens([(True, u'foo"bar')], u'"foo\\"bar"')
 
321
        self.assertAsTokens([(True, u'foo\\"bar')], u"'foo\\\"bar'")
 
322
 
 
323
    def test_double_escape(self):
 
324
        self.assertAsTokens([(True, u'foo\\bar')], u'"foo\\\\bar"')
 
325
        self.assertAsTokens([(True, u'foo\\\\bar')], u"'foo\\\\bar'")
 
326
        self.assertAsTokens([(False, u'foo\\\\bar')], u"foo\\\\bar")
 
327
 
291
328
 
292
329
class Test_CommandLineToArgv(tests.TestCaseInTempDir):
293
330
 
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))
 
331
    def assertCommandLine(self, expected, line):
 
332
        self.assertEqual(expected, win32utils._command_line_to_argv(line))
300
333
 
301
334
    def test_glob_paths(self):
302
335
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
311
344
    def test_quoted_globs(self):
312
345
        self.build_tree(['a/', 'a/b.c', 'a/c.c', 'a/c.h'])
313
346
        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)
 
347
        self.assertCommandLine([u'a/*.c'], "'a/*.c'")
317
348
 
318
349
    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
 
350
        self.assertCommandLine([u'a/*.c'], '"a\\*.c"')
 
351
        # Expands the glob, but nothing matches
324
352
        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*')
 
353
        self.assertCommandLine([u'a/foo.c'], 'a\\foo.c')