##// END OF EJS Templates
Properly mock winreg functions for test...
Thomas Kluyver -
Show More
@@ -1,687 +1,679 b''
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.path.py"""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import errno
8 8 import os
9 9 import shutil
10 10 import sys
11 11 import tempfile
12 12 import warnings
13 13 from contextlib import contextmanager
14 14
15 try: # Python 3.3+
16 from unittest.mock import patch
17 except ImportError:
18 from mock import patch
19
15 20 from os.path import join, abspath, split
16 21
17 22 from nose import SkipTest
18 23 import nose.tools as nt
19 24
20 25 from nose import with_setup
21 26
22 27 import IPython
23 28 from IPython.testing import decorators as dec
24 29 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
25 30 onlyif_unicode_paths,)
26 31 from IPython.testing.tools import make_tempfile, AssertPrints
27 32 from IPython.utils import path
28 33 from IPython.utils import py3compat
29 34 from IPython.utils.tempdir import TemporaryDirectory
30 35
31 36 # Platform-dependent imports
32 37 try:
33 38 import winreg as wreg # Py 3
34 39 except ImportError:
35 40 try:
36 41 import _winreg as wreg # Py 2
37 42 except ImportError:
38 43 #Fake _winreg module on none windows platforms
39 44 import types
40 45 wr_name = "winreg" if py3compat.PY3 else "_winreg"
41 46 sys.modules[wr_name] = types.ModuleType(wr_name)
42 47 try:
43 48 import winreg as wreg
44 49 except ImportError:
45 50 import _winreg as wreg
46 51 #Add entries that needs to be stubbed by the testing code
47 52 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
48 53
49 54 try:
50 55 reload
51 56 except NameError: # Python 3
52 57 from imp import reload
53 58
54 59 #-----------------------------------------------------------------------------
55 60 # Globals
56 61 #-----------------------------------------------------------------------------
57 62 env = os.environ
58 63 TEST_FILE_PATH = split(abspath(__file__))[0]
59 64 TMP_TEST_DIR = tempfile.mkdtemp()
60 65 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
61 66 XDG_TEST_DIR = join(HOME_TEST_DIR, "xdg_test_dir")
62 67 XDG_CACHE_DIR = join(HOME_TEST_DIR, "xdg_cache_dir")
63 68 IP_TEST_DIR = join(HOME_TEST_DIR,'.ipython')
64 69 #
65 70 # Setup/teardown functions/decorators
66 71 #
67 72
68 73 def setup():
69 74 """Setup testenvironment for the module:
70 75
71 76 - Adds dummy home dir tree
72 77 """
73 78 # Do not mask exceptions here. In particular, catching WindowsError is a
74 79 # problem because that exception is only defined on Windows...
75 80 os.makedirs(IP_TEST_DIR)
76 81 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
77 82 os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython'))
78 83
79 84
80 85 def teardown():
81 86 """Teardown testenvironment for the module:
82 87
83 88 - Remove dummy home dir tree
84 89 """
85 90 # Note: we remove the parent test dir, which is the root of all test
86 91 # subdirs we may have created. Use shutil instead of os.removedirs, so
87 92 # that non-empty directories are all recursively removed.
88 93 shutil.rmtree(TMP_TEST_DIR)
89 94
90 95
91 96 def setup_environment():
92 97 """Setup testenvironment for some functions that are tested
93 98 in this module. In particular this functions stores attributes
94 99 and other things that we need to stub in some test functions.
95 100 This needs to be done on a function level and not module level because
96 101 each testfunction needs a pristine environment.
97 102 """
98 103 global oldstuff, platformstuff
99 104 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
100 105
101 if os.name == 'nt':
102 platformstuff = (wreg.OpenKey, wreg.QueryValueEx,)
103
104
105 106 def teardown_environment():
106 107 """Restore things that were remembered by the setup_environment function
107 108 """
108 109 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
109 110 os.chdir(old_wd)
110 111 reload(path)
111 112
112 113 for key in list(env):
113 114 if key not in oldenv:
114 115 del env[key]
115 116 env.update(oldenv)
116 117 if hasattr(sys, 'frozen'):
117 118 del sys.frozen
118 if os.name == 'nt':
119 (wreg.OpenKey, wreg.QueryValueEx,) = platformstuff
120 119
121 120 # Build decorator that uses the setup_environment/setup_environment
122 121 with_environment = with_setup(setup_environment, teardown_environment)
123 122
124 123 @contextmanager
125 124 def patch_get_home_dir(dirpath):
126 125 orig_get_home_dir = path.get_home_dir
127 126 path.get_home_dir = lambda : dirpath
128 127 try:
129 128 yield
130 129 finally:
131 130 path.get_home_dir = orig_get_home_dir
132 131
133 132 @skip_if_not_win32
134 133 @with_environment
135 134 def test_get_home_dir_1():
136 135 """Testcase for py2exe logic, un-compressed lib
137 136 """
138 137 unfrozen = path.get_home_dir()
139 138 sys.frozen = True
140 139
141 140 #fake filename for IPython.__init__
142 141 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
143 142
144 143 home_dir = path.get_home_dir()
145 144 nt.assert_equal(home_dir, unfrozen)
146 145
147 146
148 147 @skip_if_not_win32
149 148 @with_environment
150 149 def test_get_home_dir_2():
151 150 """Testcase for py2exe logic, compressed lib
152 151 """
153 152 unfrozen = path.get_home_dir()
154 153 sys.frozen = True
155 154 #fake filename for IPython.__init__
156 155 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
157 156
158 157 home_dir = path.get_home_dir(True)
159 158 nt.assert_equal(home_dir, unfrozen)
160 159
161 160
162 161 @with_environment
163 162 def test_get_home_dir_3():
164 163 """get_home_dir() uses $HOME if set"""
165 164 env["HOME"] = HOME_TEST_DIR
166 165 home_dir = path.get_home_dir(True)
167 166 # get_home_dir expands symlinks
168 167 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
169 168
170 169
171 170 @with_environment
172 171 def test_get_home_dir_4():
173 172 """get_home_dir() still works if $HOME is not set"""
174 173
175 174 if 'HOME' in env: del env['HOME']
176 175 # this should still succeed, but we don't care what the answer is
177 176 home = path.get_home_dir(False)
178 177
179 178 @with_environment
180 179 def test_get_home_dir_5():
181 180 """raise HomeDirError if $HOME is specified, but not a writable dir"""
182 181 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
183 182 # set os.name = posix, to prevent My Documents fallback on Windows
184 183 os.name = 'posix'
185 184 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
186 185
187
188 186 # Should we stub wreg fully so we can run the test on all platforms?
189 187 @skip_if_not_win32
190 188 @with_environment
191 189 def test_get_home_dir_8():
192 190 """Using registry hack for 'My Documents', os=='nt'
193 191
194 192 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
195 193 """
196 194 os.name = 'nt'
197 195 # Remove from stub environment all keys that may be set
198 196 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
199 197 env.pop(key, None)
200 198
201 #Stub windows registry functions
202 def OpenKey(x, y):
203 199 class key:
204 200 def Close(self):
205 201 pass
206 return key()
207 def QueryValueEx(x, y):
208 return [abspath(HOME_TEST_DIR)]
209
210 wreg.OpenKey = OpenKey
211 wreg.QueryValueEx = QueryValueEx
212 202
203 with patch.object(wreg, 'OpenKey', return_value=key()), \
204 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
213 205 home_dir = path.get_home_dir()
214 206 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
215 207
216 208
217 209 @with_environment
218 210 def test_get_ipython_dir_1():
219 211 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
220 212 env_ipdir = os.path.join("someplace", ".ipython")
221 213 path._writable_dir = lambda path: True
222 214 env['IPYTHONDIR'] = env_ipdir
223 215 ipdir = path.get_ipython_dir()
224 216 nt.assert_equal(ipdir, env_ipdir)
225 217
226 218
227 219 @with_environment
228 220 def test_get_ipython_dir_2():
229 221 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
230 222 with patch_get_home_dir('someplace'):
231 223 path.get_xdg_dir = lambda : None
232 224 path._writable_dir = lambda path: True
233 225 os.name = "posix"
234 226 env.pop('IPYTHON_DIR', None)
235 227 env.pop('IPYTHONDIR', None)
236 228 env.pop('XDG_CONFIG_HOME', None)
237 229 ipdir = path.get_ipython_dir()
238 230 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
239 231
240 232 @with_environment
241 233 def test_get_ipython_dir_3():
242 234 """test_get_ipython_dir_3, move XDG if defined, and .ipython doesn't exist."""
243 235 tmphome = TemporaryDirectory()
244 236 try:
245 237 with patch_get_home_dir(tmphome.name):
246 238 os.name = "posix"
247 239 env.pop('IPYTHON_DIR', None)
248 240 env.pop('IPYTHONDIR', None)
249 241 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
250 242
251 243 with warnings.catch_warnings(record=True) as w:
252 244 ipdir = path.get_ipython_dir()
253 245
254 246 nt.assert_equal(ipdir, os.path.join(tmphome.name, ".ipython"))
255 247 if sys.platform != 'darwin':
256 248 nt.assert_equal(len(w), 1)
257 249 nt.assert_in('Moving', str(w[0]))
258 250 finally:
259 251 tmphome.cleanup()
260 252
261 253 @with_environment
262 254 def test_get_ipython_dir_4():
263 255 """test_get_ipython_dir_4, warn if XDG and home both exist."""
264 256 with patch_get_home_dir(HOME_TEST_DIR):
265 257 os.name = "posix"
266 258 env.pop('IPYTHON_DIR', None)
267 259 env.pop('IPYTHONDIR', None)
268 260 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
269 261 try:
270 262 os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython'))
271 263 except OSError as e:
272 264 if e.errno != errno.EEXIST:
273 265 raise
274 266
275 267 with warnings.catch_warnings(record=True) as w:
276 268 ipdir = path.get_ipython_dir()
277 269
278 270 nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, ".ipython"))
279 271 if sys.platform != 'darwin':
280 272 nt.assert_equal(len(w), 1)
281 273 nt.assert_in('Ignoring', str(w[0]))
282 274
283 275 @with_environment
284 276 def test_get_ipython_dir_5():
285 277 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
286 278 with patch_get_home_dir(HOME_TEST_DIR):
287 279 os.name = "posix"
288 280 env.pop('IPYTHON_DIR', None)
289 281 env.pop('IPYTHONDIR', None)
290 282 env['XDG_CONFIG_HOME'] = XDG_TEST_DIR
291 283 try:
292 284 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
293 285 except OSError as e:
294 286 if e.errno != errno.ENOENT:
295 287 raise
296 288 ipdir = path.get_ipython_dir()
297 289 nt.assert_equal(ipdir, IP_TEST_DIR)
298 290
299 291 @with_environment
300 292 def test_get_ipython_dir_6():
301 293 """test_get_ipython_dir_6, use home over XDG if defined and neither exist."""
302 294 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
303 295 os.mkdir(xdg)
304 296 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
305 297 with patch_get_home_dir(HOME_TEST_DIR):
306 298 orig_get_xdg_dir = path.get_xdg_dir
307 299 path.get_xdg_dir = lambda : xdg
308 300 try:
309 301 os.name = "posix"
310 302 env.pop('IPYTHON_DIR', None)
311 303 env.pop('IPYTHONDIR', None)
312 304 env.pop('XDG_CONFIG_HOME', None)
313 305 with warnings.catch_warnings(record=True) as w:
314 306 ipdir = path.get_ipython_dir()
315 307
316 308 nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, '.ipython'))
317 309 nt.assert_equal(len(w), 0)
318 310 finally:
319 311 path.get_xdg_dir = orig_get_xdg_dir
320 312
321 313 @with_environment
322 314 def test_get_ipython_dir_7():
323 315 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
324 316 path._writable_dir = lambda path: True
325 317 home_dir = os.path.normpath(os.path.expanduser('~'))
326 318 env['IPYTHONDIR'] = os.path.join('~', 'somewhere')
327 319 ipdir = path.get_ipython_dir()
328 320 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
329 321
330 322 @skip_win32
331 323 @with_environment
332 324 def test_get_ipython_dir_8():
333 325 """test_get_ipython_dir_8, test / home directory"""
334 326 old = path._writable_dir, path.get_xdg_dir
335 327 try:
336 328 path._writable_dir = lambda path: bool(path)
337 329 path.get_xdg_dir = lambda: None
338 330 env.pop('IPYTHON_DIR', None)
339 331 env.pop('IPYTHONDIR', None)
340 332 env['HOME'] = '/'
341 333 nt.assert_equal(path.get_ipython_dir(), '/.ipython')
342 334 finally:
343 335 path._writable_dir, path.get_xdg_dir = old
344 336
345 337 @with_environment
346 338 def test_get_xdg_dir_0():
347 339 """test_get_xdg_dir_0, check xdg_dir"""
348 340 reload(path)
349 341 path._writable_dir = lambda path: True
350 342 path.get_home_dir = lambda : 'somewhere'
351 343 os.name = "posix"
352 344 sys.platform = "linux2"
353 345 env.pop('IPYTHON_DIR', None)
354 346 env.pop('IPYTHONDIR', None)
355 347 env.pop('XDG_CONFIG_HOME', None)
356 348
357 349 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
358 350
359 351
360 352 @with_environment
361 353 def test_get_xdg_dir_1():
362 354 """test_get_xdg_dir_1, check nonexistant xdg_dir"""
363 355 reload(path)
364 356 path.get_home_dir = lambda : HOME_TEST_DIR
365 357 os.name = "posix"
366 358 sys.platform = "linux2"
367 359 env.pop('IPYTHON_DIR', None)
368 360 env.pop('IPYTHONDIR', None)
369 361 env.pop('XDG_CONFIG_HOME', None)
370 362 nt.assert_equal(path.get_xdg_dir(), None)
371 363
372 364 @with_environment
373 365 def test_get_xdg_dir_2():
374 366 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
375 367 reload(path)
376 368 path.get_home_dir = lambda : HOME_TEST_DIR
377 369 os.name = "posix"
378 370 sys.platform = "linux2"
379 371 env.pop('IPYTHON_DIR', None)
380 372 env.pop('IPYTHONDIR', None)
381 373 env.pop('XDG_CONFIG_HOME', None)
382 374 cfgdir=os.path.join(path.get_home_dir(), '.config')
383 375 if not os.path.exists(cfgdir):
384 376 os.makedirs(cfgdir)
385 377
386 378 nt.assert_equal(path.get_xdg_dir(), cfgdir)
387 379
388 380 @with_environment
389 381 def test_get_xdg_dir_3():
390 382 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
391 383 reload(path)
392 384 path.get_home_dir = lambda : HOME_TEST_DIR
393 385 os.name = "posix"
394 386 sys.platform = "darwin"
395 387 env.pop('IPYTHON_DIR', None)
396 388 env.pop('IPYTHONDIR', None)
397 389 env.pop('XDG_CONFIG_HOME', None)
398 390 cfgdir=os.path.join(path.get_home_dir(), '.config')
399 391 if not os.path.exists(cfgdir):
400 392 os.makedirs(cfgdir)
401 393
402 394 nt.assert_equal(path.get_xdg_dir(), None)
403 395
404 396 def test_filefind():
405 397 """Various tests for filefind"""
406 398 f = tempfile.NamedTemporaryFile()
407 399 # print 'fname:',f.name
408 400 alt_dirs = path.get_ipython_dir()
409 401 t = path.filefind(f.name, alt_dirs)
410 402 # print 'found:',t
411 403
412 404 @with_environment
413 405 def test_get_ipython_cache_dir():
414 406 os.environ["HOME"] = HOME_TEST_DIR
415 407 if os.name == 'posix' and sys.platform != 'darwin':
416 408 # test default
417 409 os.makedirs(os.path.join(HOME_TEST_DIR, ".cache"))
418 410 os.environ.pop("XDG_CACHE_HOME", None)
419 411 ipdir = path.get_ipython_cache_dir()
420 412 nt.assert_equal(os.path.join(HOME_TEST_DIR, ".cache", "ipython"),
421 413 ipdir)
422 414 nt.assert_true(os.path.isdir(ipdir))
423 415
424 416 # test env override
425 417 os.environ["XDG_CACHE_HOME"] = XDG_CACHE_DIR
426 418 ipdir = path.get_ipython_cache_dir()
427 419 nt.assert_true(os.path.isdir(ipdir))
428 420 nt.assert_equal(ipdir, os.path.join(XDG_CACHE_DIR, "ipython"))
429 421 else:
430 422 nt.assert_equal(path.get_ipython_cache_dir(),
431 423 path.get_ipython_dir())
432 424
433 425 def test_get_ipython_package_dir():
434 426 ipdir = path.get_ipython_package_dir()
435 427 nt.assert_true(os.path.isdir(ipdir))
436 428
437 429
438 430 def test_get_ipython_module_path():
439 431 ipapp_path = path.get_ipython_module_path('IPython.terminal.ipapp')
440 432 nt.assert_true(os.path.isfile(ipapp_path))
441 433
442 434
443 435 @dec.skip_if_not_win32
444 436 def test_get_long_path_name_win32():
445 437 with TemporaryDirectory() as tmpdir:
446 438
447 439 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
448 440 # path component, so ensure we include the long form of it
449 441 long_path = os.path.join(path.get_long_path_name(tmpdir), u'this is my long path name')
450 442 os.makedirs(long_path)
451 443
452 444 # Test to see if the short path evaluates correctly.
453 445 short_path = os.path.join(tmpdir, u'THISIS~1')
454 446 evaluated_path = path.get_long_path_name(short_path)
455 447 nt.assert_equal(evaluated_path.lower(), long_path.lower())
456 448
457 449
458 450 @dec.skip_win32
459 451 def test_get_long_path_name():
460 452 p = path.get_long_path_name('/usr/local')
461 453 nt.assert_equal(p,'/usr/local')
462 454
463 455 @dec.skip_win32 # can't create not-user-writable dir on win
464 456 @with_environment
465 457 def test_not_writable_ipdir():
466 458 tmpdir = tempfile.mkdtemp()
467 459 os.name = "posix"
468 460 env.pop('IPYTHON_DIR', None)
469 461 env.pop('IPYTHONDIR', None)
470 462 env.pop('XDG_CONFIG_HOME', None)
471 463 env['HOME'] = tmpdir
472 464 ipdir = os.path.join(tmpdir, '.ipython')
473 465 os.mkdir(ipdir)
474 466 os.chmod(ipdir, 600)
475 467 try:
476 468 os.listdir(ipdir)
477 469 except OSError:
478 470 pass
479 471 else:
480 472 # I can still read an unreadable dir,
481 473 # assume I'm root and skip the test
482 474 raise SkipTest("I can't create directories that I can't list")
483 475 with AssertPrints('is not a writable location', channel='stderr'):
484 476 ipdir = path.get_ipython_dir()
485 477 env.pop('IPYTHON_DIR', None)
486 478
487 479 def test_unquote_filename():
488 480 for win32 in (True, False):
489 481 nt.assert_equal(path.unquote_filename('foo.py', win32=win32), 'foo.py')
490 482 nt.assert_equal(path.unquote_filename('foo bar.py', win32=win32), 'foo bar.py')
491 483 nt.assert_equal(path.unquote_filename('"foo.py"', win32=True), 'foo.py')
492 484 nt.assert_equal(path.unquote_filename('"foo bar.py"', win32=True), 'foo bar.py')
493 485 nt.assert_equal(path.unquote_filename("'foo.py'", win32=True), 'foo.py')
494 486 nt.assert_equal(path.unquote_filename("'foo bar.py'", win32=True), 'foo bar.py')
495 487 nt.assert_equal(path.unquote_filename('"foo.py"', win32=False), '"foo.py"')
496 488 nt.assert_equal(path.unquote_filename('"foo bar.py"', win32=False), '"foo bar.py"')
497 489 nt.assert_equal(path.unquote_filename("'foo.py'", win32=False), "'foo.py'")
498 490 nt.assert_equal(path.unquote_filename("'foo bar.py'", win32=False), "'foo bar.py'")
499 491
500 492 @with_environment
501 493 def test_get_py_filename():
502 494 os.chdir(TMP_TEST_DIR)
503 495 for win32 in (True, False):
504 496 with make_tempfile('foo.py'):
505 497 nt.assert_equal(path.get_py_filename('foo.py', force_win32=win32), 'foo.py')
506 498 nt.assert_equal(path.get_py_filename('foo', force_win32=win32), 'foo.py')
507 499 with make_tempfile('foo'):
508 500 nt.assert_equal(path.get_py_filename('foo', force_win32=win32), 'foo')
509 501 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
510 502 nt.assert_raises(IOError, path.get_py_filename, 'foo', force_win32=win32)
511 503 nt.assert_raises(IOError, path.get_py_filename, 'foo.py', force_win32=win32)
512 504 true_fn = 'foo with spaces.py'
513 505 with make_tempfile(true_fn):
514 506 nt.assert_equal(path.get_py_filename('foo with spaces', force_win32=win32), true_fn)
515 507 nt.assert_equal(path.get_py_filename('foo with spaces.py', force_win32=win32), true_fn)
516 508 if win32:
517 509 nt.assert_equal(path.get_py_filename('"foo with spaces.py"', force_win32=True), true_fn)
518 510 nt.assert_equal(path.get_py_filename("'foo with spaces.py'", force_win32=True), true_fn)
519 511 else:
520 512 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"', force_win32=False)
521 513 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'", force_win32=False)
522 514
523 515 @onlyif_unicode_paths
524 516 def test_unicode_in_filename():
525 517 """When a file doesn't exist, the exception raised should be safe to call
526 518 str() on - i.e. in Python 2 it must only have ASCII characters.
527 519
528 520 https://github.com/ipython/ipython/issues/875
529 521 """
530 522 try:
531 523 # these calls should not throw unicode encode exceptions
532 524 path.get_py_filename(u'fooéè.py', force_win32=False)
533 525 except IOError as ex:
534 526 str(ex)
535 527
536 528
537 529 class TestShellGlob(object):
538 530
539 531 @classmethod
540 532 def setUpClass(cls):
541 533 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
542 534 cls.filenames_end_with_b = ['0b', '1b', '2b']
543 535 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
544 536 cls.tempdir = TemporaryDirectory()
545 537 td = cls.tempdir.name
546 538
547 539 with cls.in_tempdir():
548 540 # Create empty files
549 541 for fname in cls.filenames:
550 542 open(os.path.join(td, fname), 'w').close()
551 543
552 544 @classmethod
553 545 def tearDownClass(cls):
554 546 cls.tempdir.cleanup()
555 547
556 548 @classmethod
557 549 @contextmanager
558 550 def in_tempdir(cls):
559 551 save = py3compat.getcwd()
560 552 try:
561 553 os.chdir(cls.tempdir.name)
562 554 yield
563 555 finally:
564 556 os.chdir(save)
565 557
566 558 def check_match(self, patterns, matches):
567 559 with self.in_tempdir():
568 560 # glob returns unordered list. that's why sorted is required.
569 561 nt.assert_equals(sorted(path.shellglob(patterns)),
570 562 sorted(matches))
571 563
572 564 def common_cases(self):
573 565 return [
574 566 (['*'], self.filenames),
575 567 (['a*'], self.filenames_start_with_a),
576 568 (['*c'], ['*c']),
577 569 (['*', 'a*', '*b', '*c'], self.filenames
578 570 + self.filenames_start_with_a
579 571 + self.filenames_end_with_b
580 572 + ['*c']),
581 573 (['a[012]'], self.filenames_start_with_a),
582 574 ]
583 575
584 576 @skip_win32
585 577 def test_match_posix(self):
586 578 for (patterns, matches) in self.common_cases() + [
587 579 ([r'\*'], ['*']),
588 580 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
589 581 ([r'a\[012]'], ['a[012]']),
590 582 ]:
591 583 yield (self.check_match, patterns, matches)
592 584
593 585 @skip_if_not_win32
594 586 def test_match_windows(self):
595 587 for (patterns, matches) in self.common_cases() + [
596 588 # In windows, backslash is interpreted as path
597 589 # separator. Therefore, you can't escape glob
598 590 # using it.
599 591 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
600 592 ([r'a\[012]'], [r'a\[012]']),
601 593 ]:
602 594 yield (self.check_match, patterns, matches)
603 595
604 596
605 597 def test_unescape_glob():
606 598 nt.assert_equals(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
607 599 nt.assert_equals(path.unescape_glob(r'\\*'), r'\*')
608 600 nt.assert_equals(path.unescape_glob(r'\\\*'), r'\*')
609 601 nt.assert_equals(path.unescape_glob(r'\\a'), r'\a')
610 602 nt.assert_equals(path.unescape_glob(r'\a'), r'\a')
611 603
612 604
613 605 def test_ensure_dir_exists():
614 606 with TemporaryDirectory() as td:
615 607 d = os.path.join(td, u'βˆ‚ir')
616 608 path.ensure_dir_exists(d) # create it
617 609 assert os.path.isdir(d)
618 610 path.ensure_dir_exists(d) # no-op
619 611 f = os.path.join(td, u'Ζ’ile')
620 612 open(f, 'w').close() # touch
621 613 with nt.assert_raises(IOError):
622 614 path.ensure_dir_exists(f)
623 615
624 616 class TestLinkOrCopy(object):
625 617 def setUp(self):
626 618 self.tempdir = TemporaryDirectory()
627 619 self.src = self.dst("src")
628 620 with open(self.src, "w") as f:
629 621 f.write("Hello, world!")
630 622
631 623 def tearDown(self):
632 624 self.tempdir.cleanup()
633 625
634 626 def dst(self, *args):
635 627 return os.path.join(self.tempdir.name, *args)
636 628
637 629 def assert_inode_not_equal(self, a, b):
638 630 nt.assert_not_equals(os.stat(a).st_ino, os.stat(b).st_ino,
639 631 "%r and %r do reference the same indoes" %(a, b))
640 632
641 633 def assert_inode_equal(self, a, b):
642 634 nt.assert_equals(os.stat(a).st_ino, os.stat(b).st_ino,
643 635 "%r and %r do not reference the same indoes" %(a, b))
644 636
645 637 def assert_content_equal(self, a, b):
646 638 with open(a) as a_f:
647 639 with open(b) as b_f:
648 640 nt.assert_equals(a_f.read(), b_f.read())
649 641
650 642 @skip_win32
651 643 def test_link_successful(self):
652 644 dst = self.dst("target")
653 645 path.link_or_copy(self.src, dst)
654 646 self.assert_inode_equal(self.src, dst)
655 647
656 648 @skip_win32
657 649 def test_link_into_dir(self):
658 650 dst = self.dst("some_dir")
659 651 os.mkdir(dst)
660 652 path.link_or_copy(self.src, dst)
661 653 expected_dst = self.dst("some_dir", os.path.basename(self.src))
662 654 self.assert_inode_equal(self.src, expected_dst)
663 655
664 656 @skip_win32
665 657 def test_target_exists(self):
666 658 dst = self.dst("target")
667 659 open(dst, "w").close()
668 660 path.link_or_copy(self.src, dst)
669 661 self.assert_inode_equal(self.src, dst)
670 662
671 663 @skip_win32
672 664 def test_no_link(self):
673 665 real_link = os.link
674 666 try:
675 667 del os.link
676 668 dst = self.dst("target")
677 669 path.link_or_copy(self.src, dst)
678 670 self.assert_content_equal(self.src, dst)
679 671 self.assert_inode_not_equal(self.src, dst)
680 672 finally:
681 673 os.link = real_link
682 674
683 675 @skip_if_not_win32
684 676 def test_windows(self):
685 677 dst = self.dst("target")
686 678 path.link_or_copy(self.src, dst)
687 679 self.assert_content_equal(self.src, dst)
General Comments 0
You need to be logged in to leave comments. Login now