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