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