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