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