##// END OF EJS Templates
fix broken tests around xdg_dirs
Julien Rabinow -
Show More
@@ -1,205 +1,201 b''
1 import errno
1 import errno
2 import os
2 import os
3 import shutil
3 import shutil
4 import sys
4 import sys
5 import tempfile
5 import tempfile
6 import warnings
6 import warnings
7 from unittest.mock import patch
7 from unittest.mock import patch
8
8
9 from testpath import modified_env, assert_isdir, assert_isfile
9 from testpath import modified_env, assert_isdir, assert_isfile
10
10
11 from IPython import paths
11 from IPython import paths
12 from IPython.testing.decorators import skip_win32
12 from IPython.testing.decorators import skip_win32
13 from IPython.utils.tempdir import TemporaryDirectory
13 from IPython.utils.tempdir import TemporaryDirectory
14
14
15 TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp())
15 TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp())
16 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
16 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
17 XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir")
17 XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir")
18 XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir")
18 XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir")
19 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
19 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
20
20
21 def setup_module():
21 def setup_module():
22 """Setup testenvironment for the module:
22 """Setup testenvironment for the module:
23
23
24 - Adds dummy home dir tree
24 - Adds dummy home dir tree
25 """
25 """
26 # Do not mask exceptions here. In particular, catching WindowsError is a
26 # Do not mask exceptions here. In particular, catching WindowsError is a
27 # problem because that exception is only defined on Windows...
27 # problem because that exception is only defined on Windows...
28 os.makedirs(IP_TEST_DIR)
28 os.makedirs(IP_TEST_DIR)
29 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
29 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
30 os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython'))
30 os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython'))
31
31
32
32
33 def teardown_module():
33 def teardown_module():
34 """Teardown testenvironment for the module:
34 """Teardown testenvironment for the module:
35
35
36 - Remove dummy home dir tree
36 - Remove dummy home dir tree
37 """
37 """
38 # Note: we remove the parent test dir, which is the root of all test
38 # Note: we remove the parent test dir, which is the root of all test
39 # subdirs we may have created. Use shutil instead of os.removedirs, so
39 # subdirs we may have created. Use shutil instead of os.removedirs, so
40 # that non-empty directories are all recursively removed.
40 # that non-empty directories are all recursively removed.
41 shutil.rmtree(TMP_TEST_DIR)
41 shutil.rmtree(TMP_TEST_DIR)
42
42
43 def patch_get_home_dir(dirpath):
43 def patch_get_home_dir(dirpath):
44 return patch.object(paths, 'get_home_dir', return_value=dirpath)
44 return patch.object(paths, 'get_home_dir', return_value=dirpath)
45
45
46
46
47 def test_get_ipython_dir_1():
47 def test_get_ipython_dir_1():
48 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
48 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
49 env_ipdir = os.path.join("someplace", ".ipython")
49 env_ipdir = os.path.join("someplace", ".ipython")
50 with patch.object(paths, '_writable_dir', return_value=True), \
50 with patch.object(paths, '_writable_dir', return_value=True), \
51 modified_env({'IPYTHONDIR': env_ipdir}):
51 modified_env({'IPYTHONDIR': env_ipdir}):
52 ipdir = paths.get_ipython_dir()
52 ipdir = paths.get_ipython_dir()
53
53
54 assert ipdir == env_ipdir
54 assert ipdir == env_ipdir
55
55
56 def test_get_ipython_dir_2():
56 def test_get_ipython_dir_2():
57 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
57 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
58 with patch_get_home_dir('someplace'), \
58 with patch_get_home_dir('someplace'), \
59 patch.object(paths, 'get_xdg_dir', return_value=None), \
59 patch.object(paths, 'get_xdg_dir', return_value=None), \
60 patch.object(paths, '_writable_dir', return_value=True), \
60 patch.object(paths, '_writable_dir', return_value=True), \
61 patch('os.name', "posix"), \
61 patch('os.name', "posix"), \
62 modified_env({'IPYTHON_DIR': None,
62 modified_env({'IPYTHON_DIR': None,
63 'IPYTHONDIR': None,
63 'IPYTHONDIR': None,
64 'XDG_CONFIG_HOME': None
64 'XDG_CONFIG_HOME': None
65 }):
65 }):
66 ipdir = paths.get_ipython_dir()
66 ipdir = paths.get_ipython_dir()
67
67
68 assert ipdir == os.path.join("someplace", ".ipython")
68 assert ipdir == os.path.join("someplace", ".ipython")
69
69
70 def test_get_ipython_dir_3():
70 def test_get_ipython_dir_3():
71 """test_get_ipython_dir_3, move XDG if defined, and .ipython doesn't exist."""
71 """test_get_ipython_dir_3, use XDG if defined and exists, and .ipython doesn't exist."""
72 tmphome = TemporaryDirectory()
72 tmphome = TemporaryDirectory()
73 try:
73 try:
74 with patch_get_home_dir(tmphome.name), \
74 with patch_get_home_dir(tmphome.name), \
75 patch('os.name', 'posix'), \
75 patch('os.name', 'posix'), \
76 modified_env({
76 modified_env({
77 'IPYTHON_DIR': None,
77 'IPYTHON_DIR': None,
78 'IPYTHONDIR': None,
78 'IPYTHONDIR': None,
79 'XDG_CONFIG_HOME': XDG_TEST_DIR,
79 'XDG_CONFIG_HOME': XDG_TEST_DIR,
80 }), warnings.catch_warnings(record=True) as w:
80 }), warnings.catch_warnings(record=True) as w:
81 ipdir = paths.get_ipython_dir()
81 ipdir = paths.get_ipython_dir()
82
82
83 assert ipdir == os.path.join(tmphome.name, ".ipython")
83 assert ipdir == os.path.join(tmphome.name, XDG_TEST_DIR, "ipython")
84 if sys.platform != 'darwin':
84 assert len(w) == 0
85 assert len(w) == 1
86 assert "Moving" in str(w[0])
87 finally:
85 finally:
88 tmphome.cleanup()
86 tmphome.cleanup()
89
87
90 def test_get_ipython_dir_4():
88 def test_get_ipython_dir_4():
91 """test_get_ipython_dir_4, warn if XDG and home both exist."""
89 """test_get_ipython_dir_4, warn if XDG and home both exist."""
92 with patch_get_home_dir(HOME_TEST_DIR), \
90 with patch_get_home_dir(HOME_TEST_DIR), \
93 patch('os.name', 'posix'):
91 patch('os.name', 'posix'):
94 try:
92 try:
95 os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython'))
93 os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython'))
96 except OSError as e:
94 except OSError as e:
97 if e.errno != errno.EEXIST:
95 if e.errno != errno.EEXIST:
98 raise
96 raise
99
97
100
98
101 with modified_env({
99 with modified_env({
102 'IPYTHON_DIR': None,
100 'IPYTHON_DIR': None,
103 'IPYTHONDIR': None,
101 'IPYTHONDIR': None,
104 'XDG_CONFIG_HOME': XDG_TEST_DIR,
102 'XDG_CONFIG_HOME': XDG_TEST_DIR,
105 }), warnings.catch_warnings(record=True) as w:
103 }), warnings.catch_warnings(record=True) as w:
106 ipdir = paths.get_ipython_dir()
104 ipdir = paths.get_ipython_dir()
107
105
108 assert ipdir == os.path.join(HOME_TEST_DIR, ".ipython")
106 assert len(w) == 1
109 if sys.platform != 'darwin':
107 assert "Ignoring" in str(w[0])
110 assert len(w) == 1
111 assert "Ignoring" in str(w[0])
112
108
113
109
114 def test_get_ipython_dir_5():
110 def test_get_ipython_dir_5():
115 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
111 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
116 with patch_get_home_dir(HOME_TEST_DIR), \
112 with patch_get_home_dir(HOME_TEST_DIR), \
117 patch('os.name', 'posix'):
113 patch('os.name', 'posix'):
118 try:
114 try:
119 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
115 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
120 except OSError as e:
116 except OSError as e:
121 if e.errno != errno.ENOENT:
117 if e.errno != errno.ENOENT:
122 raise
118 raise
123
119
124 with modified_env({
120 with modified_env({
125 'IPYTHON_DIR': None,
121 'IPYTHON_DIR': None,
126 'IPYTHONDIR': None,
122 'IPYTHONDIR': None,
127 'XDG_CONFIG_HOME': XDG_TEST_DIR,
123 'XDG_CONFIG_HOME': XDG_TEST_DIR,
128 }):
124 }):
129 ipdir = paths.get_ipython_dir()
125 ipdir = paths.get_ipython_dir()
130
126
131 assert ipdir == IP_TEST_DIR
127 assert ipdir == IP_TEST_DIR
132
128
133 def test_get_ipython_dir_6():
129 def test_get_ipython_dir_6():
134 """test_get_ipython_dir_6, use home over XDG if defined and neither exist."""
130 """test_get_ipython_dir_6, use home over XDG if defined and neither exist."""
135 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
131 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
136 os.mkdir(xdg)
132 os.mkdir(xdg)
137 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
133 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
138 print(paths._writable_dir)
134 print(paths._writable_dir)
139 with patch_get_home_dir(HOME_TEST_DIR), \
135 with patch_get_home_dir(HOME_TEST_DIR), \
140 patch.object(paths, 'get_xdg_dir', return_value=xdg), \
136 patch.object(paths, 'get_xdg_dir', return_value=xdg), \
141 patch('os.name', 'posix'), \
137 patch('os.name', 'posix'), \
142 modified_env({
138 modified_env({
143 'IPYTHON_DIR': None,
139 'IPYTHON_DIR': None,
144 'IPYTHONDIR': None,
140 'IPYTHONDIR': None,
145 'XDG_CONFIG_HOME': None,
141 'XDG_CONFIG_HOME': None,
146 }), warnings.catch_warnings(record=True) as w:
142 }), warnings.catch_warnings(record=True) as w:
147 ipdir = paths.get_ipython_dir()
143 ipdir = paths.get_ipython_dir()
148
144
149 assert ipdir == os.path.join(HOME_TEST_DIR, ".ipython")
145 assert ipdir == os.path.join(HOME_TEST_DIR, ".ipython")
150 assert len(w) == 0
146 assert len(w) == 0
151
147
152 def test_get_ipython_dir_7():
148 def test_get_ipython_dir_7():
153 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
149 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
154 home_dir = os.path.normpath(os.path.expanduser('~'))
150 home_dir = os.path.normpath(os.path.expanduser('~'))
155 with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \
151 with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \
156 patch.object(paths, '_writable_dir', return_value=True):
152 patch.object(paths, '_writable_dir', return_value=True):
157 ipdir = paths.get_ipython_dir()
153 ipdir = paths.get_ipython_dir()
158 assert ipdir == os.path.join(home_dir, "somewhere")
154 assert ipdir == os.path.join(home_dir, "somewhere")
159
155
160
156
161 @skip_win32
157 @skip_win32
162 def test_get_ipython_dir_8():
158 def test_get_ipython_dir_8():
163 """test_get_ipython_dir_8, test / home directory"""
159 """test_get_ipython_dir_8, test / home directory"""
164 if not os.access("/", os.W_OK):
160 if not os.access("/", os.W_OK):
165 # test only when HOME directory actually writable
161 # test only when HOME directory actually writable
166 return
162 return
167
163
168 with patch.object(paths, "_writable_dir", lambda path: bool(path)), patch.object(
164 with patch.object(paths, "_writable_dir", lambda path: bool(path)), patch.object(
169 paths, "get_xdg_dir", return_value=None
165 paths, "get_xdg_dir", return_value=None
170 ), modified_env(
166 ), modified_env(
171 {
167 {
172 "IPYTHON_DIR": None,
168 "IPYTHON_DIR": None,
173 "IPYTHONDIR": None,
169 "IPYTHONDIR": None,
174 "HOME": "/",
170 "HOME": "/",
175 }
171 }
176 ):
172 ):
177 assert paths.get_ipython_dir() == "/.ipython"
173 assert paths.get_ipython_dir() == "/.ipython"
178
174
179
175
180 def test_get_ipython_cache_dir():
176 def test_get_ipython_cache_dir():
181 with modified_env({'HOME': HOME_TEST_DIR}):
177 with modified_env({'HOME': HOME_TEST_DIR}):
182 if os.name == 'posix' and sys.platform != 'darwin':
178 if os.name == "posix":
183 # test default
179 # test default
184 os.makedirs(os.path.join(HOME_TEST_DIR, ".cache"))
180 os.makedirs(os.path.join(HOME_TEST_DIR, ".cache"))
185 with modified_env({'XDG_CACHE_HOME': None}):
181 with modified_env({'XDG_CACHE_HOME': None}):
186 ipdir = paths.get_ipython_cache_dir()
182 ipdir = paths.get_ipython_cache_dir()
187 assert os.path.join(HOME_TEST_DIR, ".cache", "ipython") == ipdir
183 assert os.path.join(HOME_TEST_DIR, ".cache", "ipython") == ipdir
188 assert_isdir(ipdir)
184 assert_isdir(ipdir)
189
185
190 # test env override
186 # test env override
191 with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}):
187 with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}):
192 ipdir = paths.get_ipython_cache_dir()
188 ipdir = paths.get_ipython_cache_dir()
193 assert_isdir(ipdir)
189 assert_isdir(ipdir)
194 assert ipdir == os.path.join(XDG_CACHE_DIR, "ipython")
190 assert ipdir == os.path.join(XDG_CACHE_DIR, "ipython")
195 else:
191 else:
196 assert paths.get_ipython_cache_dir() == paths.get_ipython_dir()
192 assert paths.get_ipython_cache_dir() == paths.get_ipython_dir()
197
193
198 def test_get_ipython_package_dir():
194 def test_get_ipython_package_dir():
199 ipdir = paths.get_ipython_package_dir()
195 ipdir = paths.get_ipython_package_dir()
200 assert_isdir(ipdir)
196 assert_isdir(ipdir)
201
197
202
198
203 def test_get_ipython_module_path():
199 def test_get_ipython_module_path():
204 ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp')
200 ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp')
205 assert_isfile(ipapp_path)
201 assert_isfile(ipapp_path)
@@ -1,493 +1,493 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 os
7 import os
8 import shutil
8 import shutil
9 import sys
9 import sys
10 import tempfile
10 import tempfile
11 import unittest
11 import unittest
12 from contextlib import contextmanager
12 from contextlib import contextmanager
13 from unittest.mock import patch
13 from unittest.mock import patch
14 from os.path import join, abspath
14 from os.path import join, abspath
15 from imp import reload
15 from imp import reload
16
16
17 from nose import SkipTest, with_setup
17 from nose import SkipTest, with_setup
18 import pytest
18 import pytest
19
19
20 import IPython
20 import IPython
21 from IPython import paths
21 from IPython import paths
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
23 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
24 onlyif_unicode_paths,
24 onlyif_unicode_paths,
25 skip_win32_py38,)
25 skip_win32_py38,)
26 from IPython.testing.tools import make_tempfile
26 from IPython.testing.tools import make_tempfile
27 from IPython.utils import path
27 from IPython.utils import path
28 from IPython.utils.tempdir import TemporaryDirectory
28 from IPython.utils.tempdir import TemporaryDirectory
29
29
30
30
31 # Platform-dependent imports
31 # Platform-dependent imports
32 try:
32 try:
33 import winreg as wreg
33 import winreg as wreg
34 except ImportError:
34 except ImportError:
35 #Fake _winreg module on non-windows platforms
35 #Fake _winreg module on non-windows platforms
36 import types
36 import types
37 wr_name = "winreg"
37 wr_name = "winreg"
38 sys.modules[wr_name] = types.ModuleType(wr_name)
38 sys.modules[wr_name] = types.ModuleType(wr_name)
39 try:
39 try:
40 import winreg as wreg
40 import winreg as wreg
41 except ImportError:
41 except ImportError:
42 import _winreg as wreg
42 import _winreg as wreg
43 #Add entries that needs to be stubbed by the testing code
43 #Add entries that needs to be stubbed by the testing code
44 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
44 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
45
45
46 #-----------------------------------------------------------------------------
46 #-----------------------------------------------------------------------------
47 # Globals
47 # Globals
48 #-----------------------------------------------------------------------------
48 #-----------------------------------------------------------------------------
49 env = os.environ
49 env = os.environ
50 TMP_TEST_DIR = tempfile.mkdtemp()
50 TMP_TEST_DIR = tempfile.mkdtemp()
51 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
51 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
52 #
52 #
53 # Setup/teardown functions/decorators
53 # Setup/teardown functions/decorators
54 #
54 #
55
55
56 def setup_module():
56 def setup_module():
57 """Setup testenvironment for the module:
57 """Setup testenvironment for the module:
58
58
59 - Adds dummy home dir tree
59 - Adds dummy home dir tree
60 """
60 """
61 # Do not mask exceptions here. In particular, catching WindowsError is a
61 # Do not mask exceptions here. In particular, catching WindowsError is a
62 # problem because that exception is only defined on Windows...
62 # problem because that exception is only defined on Windows...
63 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
63 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
64
64
65
65
66 def teardown_module():
66 def teardown_module():
67 """Teardown testenvironment for the module:
67 """Teardown testenvironment for the module:
68
68
69 - Remove dummy home dir tree
69 - Remove dummy home dir tree
70 """
70 """
71 # Note: we remove the parent test dir, which is the root of all test
71 # Note: we remove the parent test dir, which is the root of all test
72 # subdirs we may have created. Use shutil instead of os.removedirs, so
72 # subdirs we may have created. Use shutil instead of os.removedirs, so
73 # that non-empty directories are all recursively removed.
73 # that non-empty directories are all recursively removed.
74 shutil.rmtree(TMP_TEST_DIR)
74 shutil.rmtree(TMP_TEST_DIR)
75
75
76
76
77 def setup_environment():
77 def setup_environment():
78 """Setup testenvironment for some functions that are tested
78 """Setup testenvironment for some functions that are tested
79 in this module. In particular this functions stores attributes
79 in this module. In particular this functions stores attributes
80 and other things that we need to stub in some test functions.
80 and other things that we need to stub in some test functions.
81 This needs to be done on a function level and not module level because
81 This needs to be done on a function level and not module level because
82 each testfunction needs a pristine environment.
82 each testfunction needs a pristine environment.
83 """
83 """
84 global oldstuff, platformstuff
84 global oldstuff, platformstuff
85 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
85 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
86
86
87 def teardown_environment():
87 def teardown_environment():
88 """Restore things that were remembered by the setup_environment function
88 """Restore things that were remembered by the setup_environment function
89 """
89 """
90 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
90 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
91 os.chdir(old_wd)
91 os.chdir(old_wd)
92 reload(path)
92 reload(path)
93
93
94 for key in list(env):
94 for key in list(env):
95 if key not in oldenv:
95 if key not in oldenv:
96 del env[key]
96 del env[key]
97 env.update(oldenv)
97 env.update(oldenv)
98 if hasattr(sys, 'frozen'):
98 if hasattr(sys, 'frozen'):
99 del sys.frozen
99 del sys.frozen
100
100
101 # Build decorator that uses the setup_environment/setup_environment
101 # Build decorator that uses the setup_environment/setup_environment
102 with_environment = with_setup(setup_environment, teardown_environment)
102 with_environment = with_setup(setup_environment, teardown_environment)
103
103
104 @skip_if_not_win32
104 @skip_if_not_win32
105 @with_environment
105 @with_environment
106 def test_get_home_dir_1():
106 def test_get_home_dir_1():
107 """Testcase for py2exe logic, un-compressed lib
107 """Testcase for py2exe logic, un-compressed lib
108 """
108 """
109 unfrozen = path.get_home_dir()
109 unfrozen = path.get_home_dir()
110 sys.frozen = True
110 sys.frozen = True
111
111
112 #fake filename for IPython.__init__
112 #fake filename for IPython.__init__
113 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
113 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
114
114
115 home_dir = path.get_home_dir()
115 home_dir = path.get_home_dir()
116 assert home_dir == unfrozen
116 assert home_dir == unfrozen
117
117
118
118
119 @skip_if_not_win32
119 @skip_if_not_win32
120 @with_environment
120 @with_environment
121 def test_get_home_dir_2():
121 def test_get_home_dir_2():
122 """Testcase for py2exe logic, compressed lib
122 """Testcase for py2exe logic, compressed lib
123 """
123 """
124 unfrozen = path.get_home_dir()
124 unfrozen = path.get_home_dir()
125 sys.frozen = True
125 sys.frozen = True
126 #fake filename for IPython.__init__
126 #fake filename for IPython.__init__
127 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
127 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
128
128
129 home_dir = path.get_home_dir(True)
129 home_dir = path.get_home_dir(True)
130 assert home_dir == unfrozen
130 assert home_dir == unfrozen
131
131
132
132
133 @skip_win32_py38
133 @skip_win32_py38
134 @with_environment
134 @with_environment
135 def test_get_home_dir_3():
135 def test_get_home_dir_3():
136 """get_home_dir() uses $HOME if set"""
136 """get_home_dir() uses $HOME if set"""
137 env["HOME"] = HOME_TEST_DIR
137 env["HOME"] = HOME_TEST_DIR
138 home_dir = path.get_home_dir(True)
138 home_dir = path.get_home_dir(True)
139 # get_home_dir expands symlinks
139 # get_home_dir expands symlinks
140 assert home_dir == os.path.realpath(env["HOME"])
140 assert home_dir == os.path.realpath(env["HOME"])
141
141
142
142
143 @with_environment
143 @with_environment
144 def test_get_home_dir_4():
144 def test_get_home_dir_4():
145 """get_home_dir() still works if $HOME is not set"""
145 """get_home_dir() still works if $HOME is not set"""
146
146
147 if 'HOME' in env: del env['HOME']
147 if 'HOME' in env: del env['HOME']
148 # this should still succeed, but we don't care what the answer is
148 # this should still succeed, but we don't care what the answer is
149 home = path.get_home_dir(False)
149 home = path.get_home_dir(False)
150
150
151 @skip_win32_py38
151 @skip_win32_py38
152 @with_environment
152 @with_environment
153 def test_get_home_dir_5():
153 def test_get_home_dir_5():
154 """raise HomeDirError if $HOME is specified, but not a writable dir"""
154 """raise HomeDirError if $HOME is specified, but not a writable dir"""
155 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
155 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
156 # set os.name = posix, to prevent My Documents fallback on Windows
156 # set os.name = posix, to prevent My Documents fallback on Windows
157 os.name = 'posix'
157 os.name = 'posix'
158 pytest.raises(path.HomeDirError, path.get_home_dir, True)
158 pytest.raises(path.HomeDirError, path.get_home_dir, True)
159
159
160 # Should we stub wreg fully so we can run the test on all platforms?
160 # Should we stub wreg fully so we can run the test on all platforms?
161 @skip_if_not_win32
161 @skip_if_not_win32
162 @with_environment
162 @with_environment
163 def test_get_home_dir_8():
163 def test_get_home_dir_8():
164 """Using registry hack for 'My Documents', os=='nt'
164 """Using registry hack for 'My Documents', os=='nt'
165
165
166 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
166 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
167 """
167 """
168 os.name = 'nt'
168 os.name = 'nt'
169 # Remove from stub environment all keys that may be set
169 # Remove from stub environment all keys that may be set
170 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
170 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
171 env.pop(key, None)
171 env.pop(key, None)
172
172
173 class key:
173 class key:
174 def __enter__(self):
174 def __enter__(self):
175 pass
175 pass
176 def Close(self):
176 def Close(self):
177 pass
177 pass
178 def __exit__(*args, **kwargs):
178 def __exit__(*args, **kwargs):
179 pass
179 pass
180
180
181 with patch.object(wreg, 'OpenKey', return_value=key()), \
181 with patch.object(wreg, 'OpenKey', return_value=key()), \
182 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
182 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
183 home_dir = path.get_home_dir()
183 home_dir = path.get_home_dir()
184 assert home_dir == abspath(HOME_TEST_DIR)
184 assert home_dir == abspath(HOME_TEST_DIR)
185
185
186 @with_environment
186 @with_environment
187 def test_get_xdg_dir_0():
187 def test_get_xdg_dir_0():
188 """test_get_xdg_dir_0, check xdg_dir"""
188 """test_get_xdg_dir_0, check xdg_dir"""
189 reload(path)
189 reload(path)
190 path._writable_dir = lambda path: True
190 path._writable_dir = lambda path: True
191 path.get_home_dir = lambda : 'somewhere'
191 path.get_home_dir = lambda : 'somewhere'
192 os.name = "posix"
192 os.name = "posix"
193 sys.platform = "linux2"
193 sys.platform = "linux2"
194 env.pop('IPYTHON_DIR', None)
194 env.pop('IPYTHON_DIR', None)
195 env.pop('IPYTHONDIR', None)
195 env.pop('IPYTHONDIR', None)
196 env.pop('XDG_CONFIG_HOME', None)
196 env.pop('XDG_CONFIG_HOME', None)
197
197
198 assert path.get_xdg_dir() == os.path.join("somewhere", ".config")
198 assert path.get_xdg_dir() == os.path.join("somewhere", ".config")
199
199
200
200
201 @with_environment
201 @with_environment
202 def test_get_xdg_dir_1():
202 def test_get_xdg_dir_1():
203 """test_get_xdg_dir_1, check nonexistent xdg_dir"""
203 """test_get_xdg_dir_1, check nonexistent xdg_dir"""
204 reload(path)
204 reload(path)
205 path.get_home_dir = lambda : HOME_TEST_DIR
205 path.get_home_dir = lambda : HOME_TEST_DIR
206 os.name = "posix"
206 os.name = "posix"
207 sys.platform = "linux2"
207 sys.platform = "linux2"
208 env.pop('IPYTHON_DIR', None)
208 env.pop('IPYTHON_DIR', None)
209 env.pop('IPYTHONDIR', None)
209 env.pop('IPYTHONDIR', None)
210 env.pop('XDG_CONFIG_HOME', None)
210 env.pop('XDG_CONFIG_HOME', None)
211 assert path.get_xdg_dir() is None
211 assert path.get_xdg_dir() is None
212
212
213 @with_environment
213 @with_environment
214 def test_get_xdg_dir_2():
214 def test_get_xdg_dir_2():
215 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
215 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
216 reload(path)
216 reload(path)
217 path.get_home_dir = lambda : HOME_TEST_DIR
217 path.get_home_dir = lambda : HOME_TEST_DIR
218 os.name = "posix"
218 os.name = "posix"
219 sys.platform = "linux2"
219 sys.platform = "linux2"
220 env.pop('IPYTHON_DIR', None)
220 env.pop('IPYTHON_DIR', None)
221 env.pop('IPYTHONDIR', None)
221 env.pop('IPYTHONDIR', None)
222 env.pop('XDG_CONFIG_HOME', None)
222 env.pop('XDG_CONFIG_HOME', None)
223 cfgdir=os.path.join(path.get_home_dir(), '.config')
223 cfgdir=os.path.join(path.get_home_dir(), '.config')
224 if not os.path.exists(cfgdir):
224 if not os.path.exists(cfgdir):
225 os.makedirs(cfgdir)
225 os.makedirs(cfgdir)
226
226
227 assert path.get_xdg_dir() == cfgdir
227 assert path.get_xdg_dir() == cfgdir
228
228
229 @with_environment
229 @with_environment
230 def test_get_xdg_dir_3():
230 def test_get_xdg_dir_3():
231 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
231 """test_get_xdg_dir_3, check xdg_dir not used on non-posix systems"""
232 reload(path)
232 reload(path)
233 path.get_home_dir = lambda : HOME_TEST_DIR
233 path.get_home_dir = lambda : HOME_TEST_DIR
234 os.name = "posix"
234 os.name = "nt"
235 sys.platform = "darwin"
235 sys.platform = "win32"
236 env.pop('IPYTHON_DIR', None)
236 env.pop('IPYTHON_DIR', None)
237 env.pop('IPYTHONDIR', None)
237 env.pop('IPYTHONDIR', None)
238 env.pop('XDG_CONFIG_HOME', None)
238 env.pop('XDG_CONFIG_HOME', None)
239 cfgdir=os.path.join(path.get_home_dir(), '.config')
239 cfgdir=os.path.join(path.get_home_dir(), '.config')
240 os.makedirs(cfgdir, exist_ok=True)
240 os.makedirs(cfgdir, exist_ok=True)
241
241
242 assert path.get_xdg_dir() is None
242 assert path.get_xdg_dir() is None
243
243
244 def test_filefind():
244 def test_filefind():
245 """Various tests for filefind"""
245 """Various tests for filefind"""
246 f = tempfile.NamedTemporaryFile()
246 f = tempfile.NamedTemporaryFile()
247 # print 'fname:',f.name
247 # print 'fname:',f.name
248 alt_dirs = paths.get_ipython_dir()
248 alt_dirs = paths.get_ipython_dir()
249 t = path.filefind(f.name, alt_dirs)
249 t = path.filefind(f.name, alt_dirs)
250 # print 'found:',t
250 # print 'found:',t
251
251
252
252
253 @dec.skip_if_not_win32
253 @dec.skip_if_not_win32
254 def test_get_long_path_name_win32():
254 def test_get_long_path_name_win32():
255 with TemporaryDirectory() as tmpdir:
255 with TemporaryDirectory() as tmpdir:
256
256
257 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
257 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
258 # path component, so ensure we include the long form of it
258 # path component, so ensure we include the long form of it
259 long_path = os.path.join(path.get_long_path_name(tmpdir), 'this is my long path name')
259 long_path = os.path.join(path.get_long_path_name(tmpdir), 'this is my long path name')
260 os.makedirs(long_path)
260 os.makedirs(long_path)
261
261
262 # Test to see if the short path evaluates correctly.
262 # Test to see if the short path evaluates correctly.
263 short_path = os.path.join(tmpdir, 'THISIS~1')
263 short_path = os.path.join(tmpdir, 'THISIS~1')
264 evaluated_path = path.get_long_path_name(short_path)
264 evaluated_path = path.get_long_path_name(short_path)
265 assert evaluated_path.lower() == long_path.lower()
265 assert evaluated_path.lower() == long_path.lower()
266
266
267
267
268 @dec.skip_win32
268 @dec.skip_win32
269 def test_get_long_path_name():
269 def test_get_long_path_name():
270 p = path.get_long_path_name("/usr/local")
270 p = path.get_long_path_name("/usr/local")
271 assert p == "/usr/local"
271 assert p == "/usr/local"
272
272
273
273
274 class TestRaiseDeprecation(unittest.TestCase):
274 class TestRaiseDeprecation(unittest.TestCase):
275
275
276 @dec.skip_win32 # can't create not-user-writable dir on win
276 @dec.skip_win32 # can't create not-user-writable dir on win
277 @with_environment
277 @with_environment
278 def test_not_writable_ipdir(self):
278 def test_not_writable_ipdir(self):
279 tmpdir = tempfile.mkdtemp()
279 tmpdir = tempfile.mkdtemp()
280 os.name = "posix"
280 os.name = "posix"
281 env.pop('IPYTHON_DIR', None)
281 env.pop('IPYTHON_DIR', None)
282 env.pop('IPYTHONDIR', None)
282 env.pop('IPYTHONDIR', None)
283 env.pop('XDG_CONFIG_HOME', None)
283 env.pop('XDG_CONFIG_HOME', None)
284 env['HOME'] = tmpdir
284 env['HOME'] = tmpdir
285 ipdir = os.path.join(tmpdir, '.ipython')
285 ipdir = os.path.join(tmpdir, '.ipython')
286 os.mkdir(ipdir, 0o555)
286 os.mkdir(ipdir, 0o555)
287 try:
287 try:
288 open(os.path.join(ipdir, "_foo_"), 'w').close()
288 open(os.path.join(ipdir, "_foo_"), 'w').close()
289 except IOError:
289 except IOError:
290 pass
290 pass
291 else:
291 else:
292 # I can still write to an unwritable dir,
292 # I can still write to an unwritable dir,
293 # assume I'm root and skip the test
293 # assume I'm root and skip the test
294 raise SkipTest("I can't create directories that I can't write to")
294 raise SkipTest("I can't create directories that I can't write to")
295 with self.assertWarnsRegex(UserWarning, 'is not a writable location'):
295 with self.assertWarnsRegex(UserWarning, 'is not a writable location'):
296 ipdir = paths.get_ipython_dir()
296 ipdir = paths.get_ipython_dir()
297 env.pop('IPYTHON_DIR', None)
297 env.pop('IPYTHON_DIR', None)
298
298
299 @with_environment
299 @with_environment
300 def test_get_py_filename():
300 def test_get_py_filename():
301 os.chdir(TMP_TEST_DIR)
301 os.chdir(TMP_TEST_DIR)
302 with make_tempfile("foo.py"):
302 with make_tempfile("foo.py"):
303 assert path.get_py_filename("foo.py") == "foo.py"
303 assert path.get_py_filename("foo.py") == "foo.py"
304 assert path.get_py_filename("foo") == "foo.py"
304 assert path.get_py_filename("foo") == "foo.py"
305 with make_tempfile("foo"):
305 with make_tempfile("foo"):
306 assert path.get_py_filename("foo") == "foo"
306 assert path.get_py_filename("foo") == "foo"
307 pytest.raises(IOError, path.get_py_filename, "foo.py")
307 pytest.raises(IOError, path.get_py_filename, "foo.py")
308 pytest.raises(IOError, path.get_py_filename, "foo")
308 pytest.raises(IOError, path.get_py_filename, "foo")
309 pytest.raises(IOError, path.get_py_filename, "foo.py")
309 pytest.raises(IOError, path.get_py_filename, "foo.py")
310 true_fn = "foo with spaces.py"
310 true_fn = "foo with spaces.py"
311 with make_tempfile(true_fn):
311 with make_tempfile(true_fn):
312 assert path.get_py_filename("foo with spaces") == true_fn
312 assert path.get_py_filename("foo with spaces") == true_fn
313 assert path.get_py_filename("foo with spaces.py") == true_fn
313 assert path.get_py_filename("foo with spaces.py") == true_fn
314 pytest.raises(IOError, path.get_py_filename, '"foo with spaces.py"')
314 pytest.raises(IOError, path.get_py_filename, '"foo with spaces.py"')
315 pytest.raises(IOError, path.get_py_filename, "'foo with spaces.py'")
315 pytest.raises(IOError, path.get_py_filename, "'foo with spaces.py'")
316
316
317 @onlyif_unicode_paths
317 @onlyif_unicode_paths
318 def test_unicode_in_filename():
318 def test_unicode_in_filename():
319 """When a file doesn't exist, the exception raised should be safe to call
319 """When a file doesn't exist, the exception raised should be safe to call
320 str() on - i.e. in Python 2 it must only have ASCII characters.
320 str() on - i.e. in Python 2 it must only have ASCII characters.
321
321
322 https://github.com/ipython/ipython/issues/875
322 https://github.com/ipython/ipython/issues/875
323 """
323 """
324 try:
324 try:
325 # these calls should not throw unicode encode exceptions
325 # these calls should not throw unicode encode exceptions
326 path.get_py_filename('fooéè.py')
326 path.get_py_filename('fooéè.py')
327 except IOError as ex:
327 except IOError as ex:
328 str(ex)
328 str(ex)
329
329
330
330
331 class TestShellGlob(unittest.TestCase):
331 class TestShellGlob(unittest.TestCase):
332
332
333 @classmethod
333 @classmethod
334 def setUpClass(cls):
334 def setUpClass(cls):
335 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
335 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
336 cls.filenames_end_with_b = ['0b', '1b', '2b']
336 cls.filenames_end_with_b = ['0b', '1b', '2b']
337 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
337 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
338 cls.tempdir = TemporaryDirectory()
338 cls.tempdir = TemporaryDirectory()
339 td = cls.tempdir.name
339 td = cls.tempdir.name
340
340
341 with cls.in_tempdir():
341 with cls.in_tempdir():
342 # Create empty files
342 # Create empty files
343 for fname in cls.filenames:
343 for fname in cls.filenames:
344 open(os.path.join(td, fname), 'w').close()
344 open(os.path.join(td, fname), 'w').close()
345
345
346 @classmethod
346 @classmethod
347 def tearDownClass(cls):
347 def tearDownClass(cls):
348 cls.tempdir.cleanup()
348 cls.tempdir.cleanup()
349
349
350 @classmethod
350 @classmethod
351 @contextmanager
351 @contextmanager
352 def in_tempdir(cls):
352 def in_tempdir(cls):
353 save = os.getcwd()
353 save = os.getcwd()
354 try:
354 try:
355 os.chdir(cls.tempdir.name)
355 os.chdir(cls.tempdir.name)
356 yield
356 yield
357 finally:
357 finally:
358 os.chdir(save)
358 os.chdir(save)
359
359
360 def check_match(self, patterns, matches):
360 def check_match(self, patterns, matches):
361 with self.in_tempdir():
361 with self.in_tempdir():
362 # glob returns unordered list. that's why sorted is required.
362 # glob returns unordered list. that's why sorted is required.
363 assert sorted(path.shellglob(patterns)) == sorted(matches)
363 assert sorted(path.shellglob(patterns)) == sorted(matches)
364
364
365 def common_cases(self):
365 def common_cases(self):
366 return [
366 return [
367 (['*'], self.filenames),
367 (['*'], self.filenames),
368 (['a*'], self.filenames_start_with_a),
368 (['a*'], self.filenames_start_with_a),
369 (['*c'], ['*c']),
369 (['*c'], ['*c']),
370 (['*', 'a*', '*b', '*c'], self.filenames
370 (['*', 'a*', '*b', '*c'], self.filenames
371 + self.filenames_start_with_a
371 + self.filenames_start_with_a
372 + self.filenames_end_with_b
372 + self.filenames_end_with_b
373 + ['*c']),
373 + ['*c']),
374 (['a[012]'], self.filenames_start_with_a),
374 (['a[012]'], self.filenames_start_with_a),
375 ]
375 ]
376
376
377 @skip_win32
377 @skip_win32
378 def test_match_posix(self):
378 def test_match_posix(self):
379 for (patterns, matches) in self.common_cases() + [
379 for (patterns, matches) in self.common_cases() + [
380 ([r'\*'], ['*']),
380 ([r'\*'], ['*']),
381 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
381 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
382 ([r'a\[012]'], ['a[012]']),
382 ([r'a\[012]'], ['a[012]']),
383 ]:
383 ]:
384 yield (self.check_match, patterns, matches)
384 yield (self.check_match, patterns, matches)
385
385
386 @skip_if_not_win32
386 @skip_if_not_win32
387 def test_match_windows(self):
387 def test_match_windows(self):
388 for (patterns, matches) in self.common_cases() + [
388 for (patterns, matches) in self.common_cases() + [
389 # In windows, backslash is interpreted as path
389 # In windows, backslash is interpreted as path
390 # separator. Therefore, you can't escape glob
390 # separator. Therefore, you can't escape glob
391 # using it.
391 # using it.
392 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
392 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
393 ([r'a\[012]'], [r'a\[012]']),
393 ([r'a\[012]'], [r'a\[012]']),
394 ]:
394 ]:
395 yield (self.check_match, patterns, matches)
395 yield (self.check_match, patterns, matches)
396
396
397
397
398 # TODO : pytest.mark.parametrise once nose is gone.
398 # TODO : pytest.mark.parametrise once nose is gone.
399 def test_unescape_glob():
399 def test_unescape_glob():
400 assert path.unescape_glob(r"\*\[\!\]\?") == "*[!]?"
400 assert path.unescape_glob(r"\*\[\!\]\?") == "*[!]?"
401 assert path.unescape_glob(r"\\*") == r"\*"
401 assert path.unescape_glob(r"\\*") == r"\*"
402 assert path.unescape_glob(r"\\\*") == r"\*"
402 assert path.unescape_glob(r"\\\*") == r"\*"
403 assert path.unescape_glob(r"\\a") == r"\a"
403 assert path.unescape_glob(r"\\a") == r"\a"
404 assert path.unescape_glob(r"\a") == r"\a"
404 assert path.unescape_glob(r"\a") == r"\a"
405
405
406
406
407 @onlyif_unicode_paths
407 @onlyif_unicode_paths
408 def test_ensure_dir_exists():
408 def test_ensure_dir_exists():
409 with TemporaryDirectory() as td:
409 with TemporaryDirectory() as td:
410 d = os.path.join(td, 'βˆ‚ir')
410 d = os.path.join(td, 'βˆ‚ir')
411 path.ensure_dir_exists(d) # create it
411 path.ensure_dir_exists(d) # create it
412 assert os.path.isdir(d)
412 assert os.path.isdir(d)
413 path.ensure_dir_exists(d) # no-op
413 path.ensure_dir_exists(d) # no-op
414 f = os.path.join(td, 'Ζ’ile')
414 f = os.path.join(td, 'Ζ’ile')
415 open(f, 'w').close() # touch
415 open(f, 'w').close() # touch
416 with pytest.raises(IOError):
416 with pytest.raises(IOError):
417 path.ensure_dir_exists(f)
417 path.ensure_dir_exists(f)
418
418
419 class TestLinkOrCopy(unittest.TestCase):
419 class TestLinkOrCopy(unittest.TestCase):
420 def setUp(self):
420 def setUp(self):
421 self.tempdir = TemporaryDirectory()
421 self.tempdir = TemporaryDirectory()
422 self.src = self.dst("src")
422 self.src = self.dst("src")
423 with open(self.src, "w") as f:
423 with open(self.src, "w") as f:
424 f.write("Hello, world!")
424 f.write("Hello, world!")
425
425
426 def tearDown(self):
426 def tearDown(self):
427 self.tempdir.cleanup()
427 self.tempdir.cleanup()
428
428
429 def dst(self, *args):
429 def dst(self, *args):
430 return os.path.join(self.tempdir.name, *args)
430 return os.path.join(self.tempdir.name, *args)
431
431
432 def assert_inode_not_equal(self, a, b):
432 def assert_inode_not_equal(self, a, b):
433 assert (
433 assert (
434 os.stat(a).st_ino != os.stat(b).st_ino
434 os.stat(a).st_ino != os.stat(b).st_ino
435 ), "%r and %r do reference the same indoes" % (a, b)
435 ), "%r and %r do reference the same indoes" % (a, b)
436
436
437 def assert_inode_equal(self, a, b):
437 def assert_inode_equal(self, a, b):
438 assert (
438 assert (
439 os.stat(a).st_ino == os.stat(b).st_ino
439 os.stat(a).st_ino == os.stat(b).st_ino
440 ), "%r and %r do not reference the same indoes" % (a, b)
440 ), "%r and %r do not reference the same indoes" % (a, b)
441
441
442 def assert_content_equal(self, a, b):
442 def assert_content_equal(self, a, b):
443 with open(a) as a_f:
443 with open(a) as a_f:
444 with open(b) as b_f:
444 with open(b) as b_f:
445 assert a_f.read() == b_f.read()
445 assert a_f.read() == b_f.read()
446
446
447 @skip_win32
447 @skip_win32
448 def test_link_successful(self):
448 def test_link_successful(self):
449 dst = self.dst("target")
449 dst = self.dst("target")
450 path.link_or_copy(self.src, dst)
450 path.link_or_copy(self.src, dst)
451 self.assert_inode_equal(self.src, dst)
451 self.assert_inode_equal(self.src, dst)
452
452
453 @skip_win32
453 @skip_win32
454 def test_link_into_dir(self):
454 def test_link_into_dir(self):
455 dst = self.dst("some_dir")
455 dst = self.dst("some_dir")
456 os.mkdir(dst)
456 os.mkdir(dst)
457 path.link_or_copy(self.src, dst)
457 path.link_or_copy(self.src, dst)
458 expected_dst = self.dst("some_dir", os.path.basename(self.src))
458 expected_dst = self.dst("some_dir", os.path.basename(self.src))
459 self.assert_inode_equal(self.src, expected_dst)
459 self.assert_inode_equal(self.src, expected_dst)
460
460
461 @skip_win32
461 @skip_win32
462 def test_target_exists(self):
462 def test_target_exists(self):
463 dst = self.dst("target")
463 dst = self.dst("target")
464 open(dst, "w").close()
464 open(dst, "w").close()
465 path.link_or_copy(self.src, dst)
465 path.link_or_copy(self.src, dst)
466 self.assert_inode_equal(self.src, dst)
466 self.assert_inode_equal(self.src, dst)
467
467
468 @skip_win32
468 @skip_win32
469 def test_no_link(self):
469 def test_no_link(self):
470 real_link = os.link
470 real_link = os.link
471 try:
471 try:
472 del os.link
472 del os.link
473 dst = self.dst("target")
473 dst = self.dst("target")
474 path.link_or_copy(self.src, dst)
474 path.link_or_copy(self.src, dst)
475 self.assert_content_equal(self.src, dst)
475 self.assert_content_equal(self.src, dst)
476 self.assert_inode_not_equal(self.src, dst)
476 self.assert_inode_not_equal(self.src, dst)
477 finally:
477 finally:
478 os.link = real_link
478 os.link = real_link
479
479
480 @skip_if_not_win32
480 @skip_if_not_win32
481 def test_windows(self):
481 def test_windows(self):
482 dst = self.dst("target")
482 dst = self.dst("target")
483 path.link_or_copy(self.src, dst)
483 path.link_or_copy(self.src, dst)
484 self.assert_content_equal(self.src, dst)
484 self.assert_content_equal(self.src, dst)
485
485
486 def test_link_twice(self):
486 def test_link_twice(self):
487 # Linking the same file twice shouldn't leave duplicates around.
487 # Linking the same file twice shouldn't leave duplicates around.
488 # See https://github.com/ipython/ipython/issues/6450
488 # See https://github.com/ipython/ipython/issues/6450
489 dst = self.dst('target')
489 dst = self.dst('target')
490 path.link_or_copy(self.src, dst)
490 path.link_or_copy(self.src, dst)
491 path.link_or_copy(self.src, dst)
491 path.link_or_copy(self.src, dst)
492 self.assert_inode_equal(self.src, dst)
492 self.assert_inode_equal(self.src, dst)
493 assert sorted(os.listdir(self.tempdir.name)) == ["src", "target"]
493 assert sorted(os.listdir(self.tempdir.name)) == ["src", "target"]
General Comments 0
You need to be logged in to leave comments. Login now