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