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