##// END OF EJS Templates
Merge pull request #11785 from Carreau/pytest_compat_setup_teardown...
Matthias Bussonnier -
r25089:f04ac268 merge
parent child Browse files
Show More
@@ -1,73 +1,73
1 1 # coding: utf-8
2 2 """Tests for the compilerop module.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2010-2011 The IPython Development Team.
6 6 #
7 7 # Distributed under the terms of the BSD License.
8 8 #
9 9 # The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 # Stdlib imports
17 17 import linecache
18 18 import sys
19 19
20 20 # Third-party imports
21 21 import nose.tools as nt
22 22
23 23 # Our own imports
24 24 from IPython.core import compilerop
25 25
26 26 #-----------------------------------------------------------------------------
27 27 # Test functions
28 28 #-----------------------------------------------------------------------------
29 29
30 30 def test_code_name():
31 31 code = 'x=1'
32 32 name = compilerop.code_name(code)
33 33 nt.assert_true(name.startswith('<ipython-input-0'))
34 34
35 35
36 36 def test_code_name2():
37 37 code = 'x=1'
38 38 name = compilerop.code_name(code, 9)
39 39 nt.assert_true(name.startswith('<ipython-input-9'))
40 40
41 41
42 42 def test_cache():
43 43 """Test the compiler correctly compiles and caches inputs
44 44 """
45 45 cp = compilerop.CachingCompiler()
46 46 ncache = len(linecache.cache)
47 47 cp.cache('x=1')
48 48 nt.assert_true(len(linecache.cache) > ncache)
49 49
50 def setUp():
50 def test_proper_default_encoding():
51 51 # Check we're in a proper Python 2 environment (some imports, such
52 52 # as GTK, can change the default encoding, which can hide bugs.)
53 53 nt.assert_equal(sys.getdefaultencoding(), "utf-8")
54 54
55 55 def test_cache_unicode():
56 56 cp = compilerop.CachingCompiler()
57 57 ncache = len(linecache.cache)
58 58 cp.cache(u"t = 'žćčőđ'")
59 59 nt.assert_true(len(linecache.cache) > ncache)
60 60
61 61 def test_compiler_check_cache():
62 62 """Test the compiler properly manages the cache.
63 63 """
64 64 # Rather simple-minded tests that just exercise the API
65 65 cp = compilerop.CachingCompiler()
66 66 cp.cache('x=1', 99)
67 67 # Ensure now that after clearing the cache, our entries survive
68 68 linecache.checkcache()
69 69 for k in linecache.cache:
70 70 if k.startswith('<ipython-input-99'):
71 71 break
72 72 else:
73 73 raise AssertionError('Entry for input-99 missing from linecache')
@@ -1,214 +1,214
1 1 # coding: utf-8
2 2 """Tests for the IPython tab-completion machinery.
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 # Module imports
6 6 #-----------------------------------------------------------------------------
7 7
8 8 # stdlib
9 9 import io
10 10 import os
11 11 import sys
12 12 import tempfile
13 13 from datetime import datetime
14 14 import sqlite3
15 15
16 16 # third party
17 17 import nose.tools as nt
18 18
19 19 # our own packages
20 20 from traitlets.config.loader import Config
21 21 from IPython.utils.tempdir import TemporaryDirectory
22 22 from IPython.core.history import HistoryManager, extract_hist_ranges
23 23 from IPython.testing.decorators import skipif
24 24
25 def setUp():
25 def test_proper_default_encoding():
26 26 nt.assert_equal(sys.getdefaultencoding(), "utf-8")
27 27
28 28 @skipif(sqlite3.sqlite_version_info > (3,24,0))
29 29 def test_history():
30 30 ip = get_ipython()
31 31 with TemporaryDirectory() as tmpdir:
32 32 hist_manager_ori = ip.history_manager
33 33 hist_file = os.path.join(tmpdir, 'history.sqlite')
34 34 try:
35 35 ip.history_manager = HistoryManager(shell=ip, hist_file=hist_file)
36 36 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='β‚¬Γ†ΒΎΓ·ΓŸ'"]
37 37 for i, h in enumerate(hist, start=1):
38 38 ip.history_manager.store_inputs(i, h)
39 39
40 40 ip.history_manager.db_log_output = True
41 41 # Doesn't match the input, but we'll just check it's stored.
42 42 ip.history_manager.output_hist_reprs[3] = "spam"
43 43 ip.history_manager.store_output(3)
44 44
45 45 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
46 46
47 47 # Detailed tests for _get_range_session
48 48 grs = ip.history_manager._get_range_session
49 49 nt.assert_equal(list(grs(start=2,stop=-1)), list(zip([0], [2], hist[1:-1])))
50 50 nt.assert_equal(list(grs(start=-2)), list(zip([0,0], [2,3], hist[-2:])))
51 51 nt.assert_equal(list(grs(output=True)), list(zip([0,0,0], [1,2,3], zip(hist, [None,None,'spam']))))
52 52
53 53 # Check whether specifying a range beyond the end of the current
54 54 # session results in an error (gh-804)
55 55 ip.magic('%hist 2-500')
56 56
57 57 # Check that we can write non-ascii characters to a file
58 58 ip.magic("%%hist -f %s" % os.path.join(tmpdir, "test1"))
59 59 ip.magic("%%hist -pf %s" % os.path.join(tmpdir, "test2"))
60 60 ip.magic("%%hist -nf %s" % os.path.join(tmpdir, "test3"))
61 61 ip.magic("%%save %s 1-10" % os.path.join(tmpdir, "test4"))
62 62
63 63 # New session
64 64 ip.history_manager.reset()
65 65 newcmds = [u"z=5",
66 66 u"class X(object):\n pass",
67 67 u"k='p'",
68 68 u"z=5"]
69 69 for i, cmd in enumerate(newcmds, start=1):
70 70 ip.history_manager.store_inputs(i, cmd)
71 71 gothist = ip.history_manager.get_range(start=1, stop=4)
72 72 nt.assert_equal(list(gothist), list(zip([0,0,0],[1,2,3], newcmds)))
73 73 # Previous session:
74 74 gothist = ip.history_manager.get_range(-1, 1, 4)
75 75 nt.assert_equal(list(gothist), list(zip([1,1,1],[1,2,3], hist)))
76 76
77 77 newhist = [(2, i, c) for (i, c) in enumerate(newcmds, 1)]
78 78
79 79 # Check get_hist_tail
80 80 gothist = ip.history_manager.get_tail(5, output=True,
81 81 include_latest=True)
82 82 expected = [(1, 3, (hist[-1], "spam"))] \
83 83 + [(s, n, (c, None)) for (s, n, c) in newhist]
84 84 nt.assert_equal(list(gothist), expected)
85 85
86 86 gothist = ip.history_manager.get_tail(2)
87 87 expected = newhist[-3:-1]
88 88 nt.assert_equal(list(gothist), expected)
89 89
90 90 # Check get_hist_search
91 91
92 92 gothist = ip.history_manager.search("*test*")
93 93 nt.assert_equal(list(gothist), [(1,2,hist[1])] )
94 94
95 95 gothist = ip.history_manager.search("*=*")
96 96 nt.assert_equal(list(gothist),
97 97 [(1, 1, hist[0]),
98 98 (1, 2, hist[1]),
99 99 (1, 3, hist[2]),
100 100 newhist[0],
101 101 newhist[2],
102 102 newhist[3]])
103 103
104 104 gothist = ip.history_manager.search("*=*", n=4)
105 105 nt.assert_equal(list(gothist),
106 106 [(1, 3, hist[2]),
107 107 newhist[0],
108 108 newhist[2],
109 109 newhist[3]])
110 110
111 111 gothist = ip.history_manager.search("*=*", unique=True)
112 112 nt.assert_equal(list(gothist),
113 113 [(1, 1, hist[0]),
114 114 (1, 2, hist[1]),
115 115 (1, 3, hist[2]),
116 116 newhist[2],
117 117 newhist[3]])
118 118
119 119 gothist = ip.history_manager.search("*=*", unique=True, n=3)
120 120 nt.assert_equal(list(gothist),
121 121 [(1, 3, hist[2]),
122 122 newhist[2],
123 123 newhist[3]])
124 124
125 125 gothist = ip.history_manager.search("b*", output=True)
126 126 nt.assert_equal(list(gothist), [(1,3,(hist[2],"spam"))] )
127 127
128 128 # Cross testing: check that magic %save can get previous session.
129 129 testfilename = os.path.realpath(os.path.join(tmpdir, "test.py"))
130 130 ip.magic("save " + testfilename + " ~1/1-3")
131 131 with io.open(testfilename, encoding='utf-8') as testfile:
132 132 nt.assert_equal(testfile.read(),
133 133 u"# coding: utf-8\n" + u"\n".join(hist)+u"\n")
134 134
135 135 # Duplicate line numbers - check that it doesn't crash, and
136 136 # gets a new session
137 137 ip.history_manager.store_inputs(1, "rogue")
138 138 ip.history_manager.writeout_cache()
139 139 nt.assert_equal(ip.history_manager.session_number, 3)
140 140 finally:
141 141 # Ensure saving thread is shut down before we try to clean up the files
142 142 ip.history_manager.save_thread.stop()
143 143 # Forcibly close database rather than relying on garbage collection
144 144 ip.history_manager.db.close()
145 145 # Restore history manager
146 146 ip.history_manager = hist_manager_ori
147 147
148 148
149 149 def test_extract_hist_ranges():
150 150 instr = "1 2/3 ~4/5-6 ~4/7-~4/9 ~9/2-~7/5 ~10/"
151 151 expected = [(0, 1, 2), # 0 == current session
152 152 (2, 3, 4),
153 153 (-4, 5, 7),
154 154 (-4, 7, 10),
155 155 (-9, 2, None), # None == to end
156 156 (-8, 1, None),
157 157 (-7, 1, 6),
158 158 (-10, 1, None)]
159 159 actual = list(extract_hist_ranges(instr))
160 160 nt.assert_equal(actual, expected)
161 161
162 162 def test_magic_rerun():
163 163 """Simple test for %rerun (no args -> rerun last line)"""
164 164 ip = get_ipython()
165 165 ip.run_cell("a = 10", store_history=True)
166 166 ip.run_cell("a += 1", store_history=True)
167 167 nt.assert_equal(ip.user_ns["a"], 11)
168 168 ip.run_cell("%rerun", store_history=True)
169 169 nt.assert_equal(ip.user_ns["a"], 12)
170 170
171 171 def test_timestamp_type():
172 172 ip = get_ipython()
173 173 info = ip.history_manager.get_session_info()
174 174 nt.assert_true(isinstance(info[1], datetime))
175 175
176 176 def test_hist_file_config():
177 177 cfg = Config()
178 178 tfile = tempfile.NamedTemporaryFile(delete=False)
179 179 cfg.HistoryManager.hist_file = tfile.name
180 180 try:
181 181 hm = HistoryManager(shell=get_ipython(), config=cfg)
182 182 nt.assert_equal(hm.hist_file, cfg.HistoryManager.hist_file)
183 183 finally:
184 184 try:
185 185 os.remove(tfile.name)
186 186 except OSError:
187 187 # same catch as in testing.tools.TempFileMixin
188 188 # On Windows, even though we close the file, we still can't
189 189 # delete it. I have no clue why
190 190 pass
191 191
192 192 def test_histmanager_disabled():
193 193 """Ensure that disabling the history manager doesn't create a database."""
194 194 cfg = Config()
195 195 cfg.HistoryAccessor.enabled = False
196 196
197 197 ip = get_ipython()
198 198 with TemporaryDirectory() as tmpdir:
199 199 hist_manager_ori = ip.history_manager
200 200 hist_file = os.path.join(tmpdir, 'history.sqlite')
201 201 cfg.HistoryManager.hist_file = hist_file
202 202 try:
203 203 ip.history_manager = HistoryManager(shell=ip, config=cfg)
204 204 hist = [u'a=1', u'def f():\n test = 1\n return test', u"b='β‚¬Γ†ΒΎΓ·ΓŸ'"]
205 205 for i, h in enumerate(hist, start=1):
206 206 ip.history_manager.store_inputs(i, h)
207 207 nt.assert_equal(ip.history_manager.input_hist_raw, [''] + hist)
208 208 ip.history_manager.reset()
209 209 ip.history_manager.end_session()
210 210 finally:
211 211 ip.history_manager = hist_manager_ori
212 212
213 213 # hist_file should not be created
214 214 nt.assert_false(os.path.exists(hist_file))
@@ -1,200 +1,200
1 1 import errno
2 2 import os
3 3 import shutil
4 4 import sys
5 5 import tempfile
6 6 import warnings
7 7 from unittest.mock import patch
8 8
9 9 import nose.tools as nt
10 10 from testpath import modified_env, assert_isdir, assert_isfile
11 11
12 12 from IPython import paths
13 13 from IPython.testing.decorators import skip_win32
14 14 from IPython.utils.tempdir import TemporaryDirectory
15 15
16 16 TMP_TEST_DIR = os.path.realpath(tempfile.mkdtemp())
17 17 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
18 18 XDG_TEST_DIR = os.path.join(HOME_TEST_DIR, "xdg_test_dir")
19 19 XDG_CACHE_DIR = os.path.join(HOME_TEST_DIR, "xdg_cache_dir")
20 20 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
21 21
22 def setup():
22 def setup_module():
23 23 """Setup testenvironment for the module:
24 24
25 25 - Adds dummy home dir tree
26 26 """
27 27 # Do not mask exceptions here. In particular, catching WindowsError is a
28 28 # problem because that exception is only defined on Windows...
29 29 os.makedirs(IP_TEST_DIR)
30 30 os.makedirs(os.path.join(XDG_TEST_DIR, 'ipython'))
31 31 os.makedirs(os.path.join(XDG_CACHE_DIR, 'ipython'))
32 32
33 33
34 def teardown():
34 def teardown_module():
35 35 """Teardown testenvironment for the module:
36 36
37 37 - Remove dummy home dir tree
38 38 """
39 39 # Note: we remove the parent test dir, which is the root of all test
40 40 # subdirs we may have created. Use shutil instead of os.removedirs, so
41 41 # that non-empty directories are all recursively removed.
42 42 shutil.rmtree(TMP_TEST_DIR)
43 43
44 44 def patch_get_home_dir(dirpath):
45 45 return patch.object(paths, 'get_home_dir', return_value=dirpath)
46 46
47 47
48 48 def test_get_ipython_dir_1():
49 49 """test_get_ipython_dir_1, Testcase to see if we can call get_ipython_dir without Exceptions."""
50 50 env_ipdir = os.path.join("someplace", ".ipython")
51 51 with patch.object(paths, '_writable_dir', return_value=True), \
52 52 modified_env({'IPYTHONDIR': env_ipdir}):
53 53 ipdir = paths.get_ipython_dir()
54 54
55 55 nt.assert_equal(ipdir, env_ipdir)
56 56
57 57 def test_get_ipython_dir_2():
58 58 """test_get_ipython_dir_2, Testcase to see if we can call get_ipython_dir without Exceptions."""
59 59 with patch_get_home_dir('someplace'), \
60 60 patch.object(paths, 'get_xdg_dir', return_value=None), \
61 61 patch.object(paths, '_writable_dir', return_value=True), \
62 62 patch('os.name', "posix"), \
63 63 modified_env({'IPYTHON_DIR': None,
64 64 'IPYTHONDIR': None,
65 65 'XDG_CONFIG_HOME': None
66 66 }):
67 67 ipdir = paths.get_ipython_dir()
68 68
69 69 nt.assert_equal(ipdir, os.path.join("someplace", ".ipython"))
70 70
71 71 def test_get_ipython_dir_3():
72 72 """test_get_ipython_dir_3, move XDG if defined, and .ipython doesn't exist."""
73 73 tmphome = TemporaryDirectory()
74 74 try:
75 75 with patch_get_home_dir(tmphome.name), \
76 76 patch('os.name', 'posix'), \
77 77 modified_env({
78 78 'IPYTHON_DIR': None,
79 79 'IPYTHONDIR': None,
80 80 'XDG_CONFIG_HOME': XDG_TEST_DIR,
81 81 }), warnings.catch_warnings(record=True) as w:
82 82 ipdir = paths.get_ipython_dir()
83 83
84 84 nt.assert_equal(ipdir, os.path.join(tmphome.name, ".ipython"))
85 85 if sys.platform != 'darwin':
86 86 nt.assert_equal(len(w), 1)
87 87 nt.assert_in('Moving', str(w[0]))
88 88 finally:
89 89 tmphome.cleanup()
90 90
91 91 def test_get_ipython_dir_4():
92 92 """test_get_ipython_dir_4, warn if XDG and home both exist."""
93 93 with patch_get_home_dir(HOME_TEST_DIR), \
94 94 patch('os.name', 'posix'):
95 95 try:
96 96 os.mkdir(os.path.join(XDG_TEST_DIR, 'ipython'))
97 97 except OSError as e:
98 98 if e.errno != errno.EEXIST:
99 99 raise
100 100
101 101
102 102 with modified_env({
103 103 'IPYTHON_DIR': None,
104 104 'IPYTHONDIR': None,
105 105 'XDG_CONFIG_HOME': XDG_TEST_DIR,
106 106 }), warnings.catch_warnings(record=True) as w:
107 107 ipdir = paths.get_ipython_dir()
108 108
109 109 nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, ".ipython"))
110 110 if sys.platform != 'darwin':
111 111 nt.assert_equal(len(w), 1)
112 112 nt.assert_in('Ignoring', str(w[0]))
113 113
114 114 def test_get_ipython_dir_5():
115 115 """test_get_ipython_dir_5, use .ipython if exists and XDG defined, but doesn't exist."""
116 116 with patch_get_home_dir(HOME_TEST_DIR), \
117 117 patch('os.name', 'posix'):
118 118 try:
119 119 os.rmdir(os.path.join(XDG_TEST_DIR, 'ipython'))
120 120 except OSError as e:
121 121 if e.errno != errno.ENOENT:
122 122 raise
123 123
124 124 with modified_env({
125 125 'IPYTHON_DIR': None,
126 126 'IPYTHONDIR': None,
127 127 'XDG_CONFIG_HOME': XDG_TEST_DIR,
128 128 }):
129 129 ipdir = paths.get_ipython_dir()
130 130
131 131 nt.assert_equal(ipdir, IP_TEST_DIR)
132 132
133 133 def test_get_ipython_dir_6():
134 134 """test_get_ipython_dir_6, use home over XDG if defined and neither exist."""
135 135 xdg = os.path.join(HOME_TEST_DIR, 'somexdg')
136 136 os.mkdir(xdg)
137 137 shutil.rmtree(os.path.join(HOME_TEST_DIR, '.ipython'))
138 138 print(paths._writable_dir)
139 139 with patch_get_home_dir(HOME_TEST_DIR), \
140 140 patch.object(paths, 'get_xdg_dir', return_value=xdg), \
141 141 patch('os.name', 'posix'), \
142 142 modified_env({
143 143 'IPYTHON_DIR': None,
144 144 'IPYTHONDIR': None,
145 145 'XDG_CONFIG_HOME': None,
146 146 }), warnings.catch_warnings(record=True) as w:
147 147 ipdir = paths.get_ipython_dir()
148 148
149 149 nt.assert_equal(ipdir, os.path.join(HOME_TEST_DIR, '.ipython'))
150 150 nt.assert_equal(len(w), 0)
151 151
152 152 def test_get_ipython_dir_7():
153 153 """test_get_ipython_dir_7, test home directory expansion on IPYTHONDIR"""
154 154 home_dir = os.path.normpath(os.path.expanduser('~'))
155 155 with modified_env({'IPYTHONDIR': os.path.join('~', 'somewhere')}), \
156 156 patch.object(paths, '_writable_dir', return_value=True):
157 157 ipdir = paths.get_ipython_dir()
158 158 nt.assert_equal(ipdir, os.path.join(home_dir, 'somewhere'))
159 159
160 160 @skip_win32
161 161 def test_get_ipython_dir_8():
162 162 """test_get_ipython_dir_8, test / home directory"""
163 163 with patch.object(paths, '_writable_dir', lambda path: bool(path)), \
164 164 patch.object(paths, 'get_xdg_dir', return_value=None), \
165 165 modified_env({
166 166 'IPYTHON_DIR': None,
167 167 'IPYTHONDIR': None,
168 168 'HOME': '/',
169 169 }):
170 170 nt.assert_equal(paths.get_ipython_dir(), '/.ipython')
171 171
172 172
173 173 def test_get_ipython_cache_dir():
174 174 with modified_env({'HOME': HOME_TEST_DIR}):
175 175 if os.name == 'posix' and sys.platform != 'darwin':
176 176 # test default
177 177 os.makedirs(os.path.join(HOME_TEST_DIR, ".cache"))
178 178 with modified_env({'XDG_CACHE_HOME': None}):
179 179 ipdir = paths.get_ipython_cache_dir()
180 180 nt.assert_equal(os.path.join(HOME_TEST_DIR, ".cache", "ipython"),
181 181 ipdir)
182 182 assert_isdir(ipdir)
183 183
184 184 # test env override
185 185 with modified_env({"XDG_CACHE_HOME": XDG_CACHE_DIR}):
186 186 ipdir = paths.get_ipython_cache_dir()
187 187 assert_isdir(ipdir)
188 188 nt.assert_equal(ipdir, os.path.join(XDG_CACHE_DIR, "ipython"))
189 189 else:
190 190 nt.assert_equal(paths.get_ipython_cache_dir(),
191 191 paths.get_ipython_dir())
192 192
193 193 def test_get_ipython_package_dir():
194 194 ipdir = paths.get_ipython_package_dir()
195 195 assert_isdir(ipdir)
196 196
197 197
198 198 def test_get_ipython_module_path():
199 199 ipapp_path = paths.get_ipython_module_path('IPython.terminal.ipapp')
200 200 assert_isfile(ipapp_path)
@@ -1,161 +1,161
1 1 # coding: utf-8
2 2 """Tests for profile-related functions.
3 3
4 4 Currently only the startup-dir functionality is tested, but more tests should
5 5 be added for:
6 6
7 7 * ipython profile create
8 8 * ipython profile list
9 9 * ipython profile create --parallel
10 10 * security dir permissions
11 11
12 12 Authors
13 13 -------
14 14
15 15 * MinRK
16 16
17 17 """
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import os
24 24 import shutil
25 25 import sys
26 26 import tempfile
27 27
28 28 from unittest import TestCase
29 29
30 30 import nose.tools as nt
31 31
32 32 from IPython.core.profileapp import list_profiles_in, list_bundled_profiles
33 33 from IPython.core.profiledir import ProfileDir
34 34
35 35 from IPython.testing import decorators as dec
36 36 from IPython.testing import tools as tt
37 37 from IPython.utils.process import getoutput
38 38 from IPython.utils.tempdir import TemporaryDirectory
39 39
40 40 #-----------------------------------------------------------------------------
41 41 # Globals
42 42 #-----------------------------------------------------------------------------
43 43 TMP_TEST_DIR = tempfile.mkdtemp()
44 44 HOME_TEST_DIR = os.path.join(TMP_TEST_DIR, "home_test_dir")
45 45 IP_TEST_DIR = os.path.join(HOME_TEST_DIR,'.ipython')
46 46
47 47 #
48 48 # Setup/teardown functions/decorators
49 49 #
50 50
51 def setup():
51 def setup_module():
52 52 """Setup test environment for the module:
53 53
54 54 - Adds dummy home dir tree
55 55 """
56 56 # Do not mask exceptions here. In particular, catching WindowsError is a
57 57 # problem because that exception is only defined on Windows...
58 58 os.makedirs(IP_TEST_DIR)
59 59
60 60
61 def teardown():
61 def teardown_module():
62 62 """Teardown test environment for the module:
63 63
64 64 - Remove dummy home dir tree
65 65 """
66 66 # Note: we remove the parent test dir, which is the root of all test
67 67 # subdirs we may have created. Use shutil instead of os.removedirs, so
68 68 # that non-empty directories are all recursively removed.
69 69 shutil.rmtree(TMP_TEST_DIR)
70 70
71 71
72 72 #-----------------------------------------------------------------------------
73 73 # Test functions
74 74 #-----------------------------------------------------------------------------
75 75 def win32_without_pywin32():
76 76 if sys.platform == 'win32':
77 77 try:
78 78 import pywin32
79 79 except ImportError:
80 80 return True
81 81 return False
82 82
83 83
84 84 class ProfileStartupTest(TestCase):
85 85 def setUp(self):
86 86 # create profile dir
87 87 self.pd = ProfileDir.create_profile_dir_by_name(IP_TEST_DIR, 'test')
88 88 self.options = ['--ipython-dir', IP_TEST_DIR, '--profile', 'test']
89 89 self.fname = os.path.join(TMP_TEST_DIR, 'test.py')
90 90
91 91 def tearDown(self):
92 92 # We must remove this profile right away so its presence doesn't
93 93 # confuse other tests.
94 94 shutil.rmtree(self.pd.location)
95 95
96 96 def init(self, startup_file, startup, test):
97 97 # write startup python file
98 98 with open(os.path.join(self.pd.startup_dir, startup_file), 'w') as f:
99 99 f.write(startup)
100 100 # write simple test file, to check that the startup file was run
101 101 with open(self.fname, 'w') as f:
102 102 f.write(test)
103 103
104 104 def validate(self, output):
105 105 tt.ipexec_validate(self.fname, output, '', options=self.options)
106 106
107 107 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
108 108 def test_startup_py(self):
109 109 self.init('00-start.py', 'zzz=123\n', 'print(zzz)\n')
110 110 self.validate('123')
111 111
112 112 @dec.skipif(win32_without_pywin32(), "Test requires pywin32 on Windows")
113 113 def test_startup_ipy(self):
114 114 self.init('00-start.ipy', '%xmode plain\n', '')
115 115 self.validate('Exception reporting mode: Plain')
116 116
117 117
118 118 def test_list_profiles_in():
119 119 # No need to remove these directories and files, as they will get nuked in
120 120 # the module-level teardown.
121 121 td = tempfile.mkdtemp(dir=TMP_TEST_DIR)
122 122 for name in ('profile_foo', 'profile_hello', 'not_a_profile'):
123 123 os.mkdir(os.path.join(td, name))
124 124 if dec.unicode_paths:
125 125 os.mkdir(os.path.join(td, u'profile_ΓΌnicode'))
126 126
127 127 with open(os.path.join(td, 'profile_file'), 'w') as f:
128 128 f.write("I am not a profile directory")
129 129 profiles = list_profiles_in(td)
130 130
131 131 # unicode normalization can turn u'ΓΌnicode' into u'u\0308nicode',
132 132 # so only check for *nicode, and that creating a ProfileDir from the
133 133 # name remains valid
134 134 found_unicode = False
135 135 for p in list(profiles):
136 136 if p.endswith('nicode'):
137 137 pd = ProfileDir.find_profile_dir_by_name(td, p)
138 138 profiles.remove(p)
139 139 found_unicode = True
140 140 break
141 141 if dec.unicode_paths:
142 142 nt.assert_true(found_unicode)
143 143 nt.assert_equal(set(profiles), {'foo', 'hello'})
144 144
145 145
146 146 def test_list_bundled_profiles():
147 147 # This variable will need to be updated when a new profile gets bundled
148 148 bundled = sorted(list_bundled_profiles())
149 149 nt.assert_equal(bundled, [])
150 150
151 151
152 152 def test_profile_create_ipython_dir():
153 153 """ipython profile create respects --ipython-dir"""
154 154 with TemporaryDirectory() as td:
155 155 getoutput([sys.executable, '-m', 'IPython', 'profile', 'create',
156 156 'foo', '--ipython-dir=%s' % td])
157 157 profile_dir = os.path.join(td, 'profile_foo')
158 158 assert os.path.exists(profile_dir)
159 159 ipython_config = os.path.join(profile_dir, 'ipython_config.py')
160 160 assert os.path.exists(ipython_config)
161 161
@@ -1,114 +1,114
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.module_paths.py"""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2008-2011 The IPython Development Team
6 6 #
7 7 # Distributed under the terms of the BSD License. The full license is in
8 8 # the file COPYING, distributed as part of this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15
16 16 import os
17 17 import shutil
18 18 import sys
19 19 import tempfile
20 20
21 21 from os.path import join, abspath, split
22 22
23 23 from IPython.testing.tools import make_tempfile
24 24
25 25 import IPython.utils.module_paths as mp
26 26
27 27 import nose.tools as nt
28 28
29 29 env = os.environ
30 30 TEST_FILE_PATH = split(abspath(__file__))[0]
31 31
32 32 TMP_TEST_DIR = tempfile.mkdtemp(suffix='with.dot')
33 33 #
34 34 # Setup/teardown functions/decorators
35 35 #
36 36
37 37 old_syspath = sys.path
38 38
39 39 def make_empty_file(fname):
40 40 open(fname, 'w').close()
41 41
42 42
43 def setup():
43 def setup_module():
44 44 """Setup testenvironment for the module:
45 45
46 46 """
47 47 # Do not mask exceptions here. In particular, catching WindowsError is a
48 48 # problem because that exception is only defined on Windows...
49 49 os.makedirs(join(TMP_TEST_DIR, "xmod"))
50 50 os.makedirs(join(TMP_TEST_DIR, "nomod"))
51 51 make_empty_file(join(TMP_TEST_DIR, "xmod/__init__.py"))
52 52 make_empty_file(join(TMP_TEST_DIR, "xmod/sub.py"))
53 53 make_empty_file(join(TMP_TEST_DIR, "pack.py"))
54 54 make_empty_file(join(TMP_TEST_DIR, "packpyc.pyc"))
55 55 sys.path = [TMP_TEST_DIR]
56 56
57 def teardown():
57 def teardown_module():
58 58 """Teardown testenvironment for the module:
59 59
60 60 - Remove tempdir
61 61 - restore sys.path
62 62 """
63 63 # Note: we remove the parent test dir, which is the root of all test
64 64 # subdirs we may have created. Use shutil instead of os.removedirs, so
65 65 # that non-empty directories are all recursively removed.
66 66 shutil.rmtree(TMP_TEST_DIR)
67 67 sys.path = old_syspath
68 68
69 69 def test_tempdir():
70 70 """
71 71 Ensure the test are done with a temporary file that have a dot somewhere.
72 72 """
73 73 nt.assert_in('.',TMP_TEST_DIR)
74 74
75 75
76 76 def test_find_mod_1():
77 77 """
78 78 Search for a directory's file path.
79 79 Expected output: a path to that directory's __init__.py file.
80 80 """
81 81 modpath = join(TMP_TEST_DIR, "xmod", "__init__.py")
82 82 nt.assert_equal(mp.find_mod("xmod"), modpath)
83 83
84 84 def test_find_mod_2():
85 85 """
86 86 Search for a directory's file path.
87 87 Expected output: a path to that directory's __init__.py file.
88 88 TODO: Confirm why this is a duplicate test.
89 89 """
90 90 modpath = join(TMP_TEST_DIR, "xmod", "__init__.py")
91 91 nt.assert_equal(mp.find_mod("xmod"), modpath)
92 92
93 93 def test_find_mod_3():
94 94 """
95 95 Search for a directory + a filename without its .py extension
96 96 Expected output: full path with .py extension.
97 97 """
98 98 modpath = join(TMP_TEST_DIR, "xmod", "sub.py")
99 99 nt.assert_equal(mp.find_mod("xmod.sub"), modpath)
100 100
101 101 def test_find_mod_4():
102 102 """
103 103 Search for a filename without its .py extension
104 104 Expected output: full path with .py extension
105 105 """
106 106 modpath = join(TMP_TEST_DIR, "pack.py")
107 107 nt.assert_equal(mp.find_mod("pack"), modpath)
108 108
109 109 def test_find_mod_5():
110 110 """
111 111 Search for a filename with a .pyc extension
112 112 Expected output: TODO: do we exclude or include .pyc files?
113 113 """
114 114 nt.assert_equal(mp.find_mod("packpyc"), None)
@@ -1,481 +1,481
1 1 # encoding: utf-8
2 2 """Tests for IPython.utils.path.py"""
3 3
4 4 # Copyright (c) IPython Development Team.
5 5 # Distributed under the terms of the Modified BSD License.
6 6
7 7 import os
8 8 import shutil
9 9 import sys
10 10 import tempfile
11 11 import unittest
12 12 from contextlib import contextmanager
13 13 from unittest.mock import patch
14 14 from os.path import join, abspath
15 15 from imp import reload
16 16
17 17 from nose import SkipTest, with_setup
18 18 import nose.tools as nt
19 19
20 20 import IPython
21 21 from IPython import paths
22 22 from IPython.testing import decorators as dec
23 23 from IPython.testing.decorators import (skip_if_not_win32, skip_win32,
24 24 onlyif_unicode_paths,)
25 25 from IPython.testing.tools import make_tempfile, AssertPrints
26 26 from IPython.utils import path
27 27 from IPython.utils.tempdir import TemporaryDirectory
28 28
29 29 # Platform-dependent imports
30 30 try:
31 31 import winreg as wreg
32 32 except ImportError:
33 33 #Fake _winreg module on non-windows platforms
34 34 import types
35 35 wr_name = "winreg"
36 36 sys.modules[wr_name] = types.ModuleType(wr_name)
37 37 try:
38 38 import winreg as wreg
39 39 except ImportError:
40 40 import _winreg as wreg
41 41 #Add entries that needs to be stubbed by the testing code
42 42 (wreg.OpenKey, wreg.QueryValueEx,) = (None, None)
43 43
44 44 #-----------------------------------------------------------------------------
45 45 # Globals
46 46 #-----------------------------------------------------------------------------
47 47 env = os.environ
48 48 TMP_TEST_DIR = tempfile.mkdtemp()
49 49 HOME_TEST_DIR = join(TMP_TEST_DIR, "home_test_dir")
50 50 #
51 51 # Setup/teardown functions/decorators
52 52 #
53 53
54 def setup():
54 def setup_module():
55 55 """Setup testenvironment for the module:
56 56
57 57 - Adds dummy home dir tree
58 58 """
59 59 # Do not mask exceptions here. In particular, catching WindowsError is a
60 60 # problem because that exception is only defined on Windows...
61 61 os.makedirs(os.path.join(HOME_TEST_DIR, 'ipython'))
62 62
63 63
64 def teardown():
64 def teardown_module():
65 65 """Teardown testenvironment for the module:
66 66
67 67 - Remove dummy home dir tree
68 68 """
69 69 # Note: we remove the parent test dir, which is the root of all test
70 70 # subdirs we may have created. Use shutil instead of os.removedirs, so
71 71 # that non-empty directories are all recursively removed.
72 72 shutil.rmtree(TMP_TEST_DIR)
73 73
74 74
75 75 def setup_environment():
76 76 """Setup testenvironment for some functions that are tested
77 77 in this module. In particular this functions stores attributes
78 78 and other things that we need to stub in some test functions.
79 79 This needs to be done on a function level and not module level because
80 80 each testfunction needs a pristine environment.
81 81 """
82 82 global oldstuff, platformstuff
83 83 oldstuff = (env.copy(), os.name, sys.platform, path.get_home_dir, IPython.__file__, os.getcwd())
84 84
85 85 def teardown_environment():
86 86 """Restore things that were remembered by the setup_environment function
87 87 """
88 88 (oldenv, os.name, sys.platform, path.get_home_dir, IPython.__file__, old_wd) = oldstuff
89 89 os.chdir(old_wd)
90 90 reload(path)
91 91
92 92 for key in list(env):
93 93 if key not in oldenv:
94 94 del env[key]
95 95 env.update(oldenv)
96 96 if hasattr(sys, 'frozen'):
97 97 del sys.frozen
98 98
99 99 # Build decorator that uses the setup_environment/setup_environment
100 100 with_environment = with_setup(setup_environment, teardown_environment)
101 101
102 102 @skip_if_not_win32
103 103 @with_environment
104 104 def test_get_home_dir_1():
105 105 """Testcase for py2exe logic, un-compressed lib
106 106 """
107 107 unfrozen = path.get_home_dir()
108 108 sys.frozen = True
109 109
110 110 #fake filename for IPython.__init__
111 111 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Lib/IPython/__init__.py"))
112 112
113 113 home_dir = path.get_home_dir()
114 114 nt.assert_equal(home_dir, unfrozen)
115 115
116 116
117 117 @skip_if_not_win32
118 118 @with_environment
119 119 def test_get_home_dir_2():
120 120 """Testcase for py2exe logic, compressed lib
121 121 """
122 122 unfrozen = path.get_home_dir()
123 123 sys.frozen = True
124 124 #fake filename for IPython.__init__
125 125 IPython.__file__ = abspath(join(HOME_TEST_DIR, "Library.zip/IPython/__init__.py")).lower()
126 126
127 127 home_dir = path.get_home_dir(True)
128 128 nt.assert_equal(home_dir, unfrozen)
129 129
130 130
131 131 @with_environment
132 132 def test_get_home_dir_3():
133 133 """get_home_dir() uses $HOME if set"""
134 134 env["HOME"] = HOME_TEST_DIR
135 135 home_dir = path.get_home_dir(True)
136 136 # get_home_dir expands symlinks
137 137 nt.assert_equal(home_dir, os.path.realpath(env["HOME"]))
138 138
139 139
140 140 @with_environment
141 141 def test_get_home_dir_4():
142 142 """get_home_dir() still works if $HOME is not set"""
143 143
144 144 if 'HOME' in env: del env['HOME']
145 145 # this should still succeed, but we don't care what the answer is
146 146 home = path.get_home_dir(False)
147 147
148 148 @with_environment
149 149 def test_get_home_dir_5():
150 150 """raise HomeDirError if $HOME is specified, but not a writable dir"""
151 151 env['HOME'] = abspath(HOME_TEST_DIR+'garbage')
152 152 # set os.name = posix, to prevent My Documents fallback on Windows
153 153 os.name = 'posix'
154 154 nt.assert_raises(path.HomeDirError, path.get_home_dir, True)
155 155
156 156 # Should we stub wreg fully so we can run the test on all platforms?
157 157 @skip_if_not_win32
158 158 @with_environment
159 159 def test_get_home_dir_8():
160 160 """Using registry hack for 'My Documents', os=='nt'
161 161
162 162 HOMESHARE, HOMEDRIVE, HOMEPATH, USERPROFILE and others are missing.
163 163 """
164 164 os.name = 'nt'
165 165 # Remove from stub environment all keys that may be set
166 166 for key in ['HOME', 'HOMESHARE', 'HOMEDRIVE', 'HOMEPATH', 'USERPROFILE']:
167 167 env.pop(key, None)
168 168
169 169 class key:
170 170 def Close(self):
171 171 pass
172 172
173 173 with patch.object(wreg, 'OpenKey', return_value=key()), \
174 174 patch.object(wreg, 'QueryValueEx', return_value=[abspath(HOME_TEST_DIR)]):
175 175 home_dir = path.get_home_dir()
176 176 nt.assert_equal(home_dir, abspath(HOME_TEST_DIR))
177 177
178 178 @with_environment
179 179 def test_get_xdg_dir_0():
180 180 """test_get_xdg_dir_0, check xdg_dir"""
181 181 reload(path)
182 182 path._writable_dir = lambda path: True
183 183 path.get_home_dir = lambda : 'somewhere'
184 184 os.name = "posix"
185 185 sys.platform = "linux2"
186 186 env.pop('IPYTHON_DIR', None)
187 187 env.pop('IPYTHONDIR', None)
188 188 env.pop('XDG_CONFIG_HOME', None)
189 189
190 190 nt.assert_equal(path.get_xdg_dir(), os.path.join('somewhere', '.config'))
191 191
192 192
193 193 @with_environment
194 194 def test_get_xdg_dir_1():
195 195 """test_get_xdg_dir_1, check nonexistent xdg_dir"""
196 196 reload(path)
197 197 path.get_home_dir = lambda : HOME_TEST_DIR
198 198 os.name = "posix"
199 199 sys.platform = "linux2"
200 200 env.pop('IPYTHON_DIR', None)
201 201 env.pop('IPYTHONDIR', None)
202 202 env.pop('XDG_CONFIG_HOME', None)
203 203 nt.assert_equal(path.get_xdg_dir(), None)
204 204
205 205 @with_environment
206 206 def test_get_xdg_dir_2():
207 207 """test_get_xdg_dir_2, check xdg_dir default to ~/.config"""
208 208 reload(path)
209 209 path.get_home_dir = lambda : HOME_TEST_DIR
210 210 os.name = "posix"
211 211 sys.platform = "linux2"
212 212 env.pop('IPYTHON_DIR', None)
213 213 env.pop('IPYTHONDIR', None)
214 214 env.pop('XDG_CONFIG_HOME', None)
215 215 cfgdir=os.path.join(path.get_home_dir(), '.config')
216 216 if not os.path.exists(cfgdir):
217 217 os.makedirs(cfgdir)
218 218
219 219 nt.assert_equal(path.get_xdg_dir(), cfgdir)
220 220
221 221 @with_environment
222 222 def test_get_xdg_dir_3():
223 223 """test_get_xdg_dir_3, check xdg_dir not used on OS X"""
224 224 reload(path)
225 225 path.get_home_dir = lambda : HOME_TEST_DIR
226 226 os.name = "posix"
227 227 sys.platform = "darwin"
228 228 env.pop('IPYTHON_DIR', None)
229 229 env.pop('IPYTHONDIR', None)
230 230 env.pop('XDG_CONFIG_HOME', None)
231 231 cfgdir=os.path.join(path.get_home_dir(), '.config')
232 232 if not os.path.exists(cfgdir):
233 233 os.makedirs(cfgdir)
234 234
235 235 nt.assert_equal(path.get_xdg_dir(), None)
236 236
237 237 def test_filefind():
238 238 """Various tests for filefind"""
239 239 f = tempfile.NamedTemporaryFile()
240 240 # print 'fname:',f.name
241 241 alt_dirs = paths.get_ipython_dir()
242 242 t = path.filefind(f.name, alt_dirs)
243 243 # print 'found:',t
244 244
245 245
246 246 @dec.skip_if_not_win32
247 247 def test_get_long_path_name_win32():
248 248 with TemporaryDirectory() as tmpdir:
249 249
250 250 # Make a long path. Expands the path of tmpdir prematurely as it may already have a long
251 251 # path component, so ensure we include the long form of it
252 252 long_path = os.path.join(path.get_long_path_name(tmpdir), 'this is my long path name')
253 253 os.makedirs(long_path)
254 254
255 255 # Test to see if the short path evaluates correctly.
256 256 short_path = os.path.join(tmpdir, 'THISIS~1')
257 257 evaluated_path = path.get_long_path_name(short_path)
258 258 nt.assert_equal(evaluated_path.lower(), long_path.lower())
259 259
260 260
261 261 @dec.skip_win32
262 262 def test_get_long_path_name():
263 263 p = path.get_long_path_name('/usr/local')
264 264 nt.assert_equal(p,'/usr/local')
265 265
266 266 @dec.skip_win32 # can't create not-user-writable dir on win
267 267 @with_environment
268 268 def test_not_writable_ipdir():
269 269 tmpdir = tempfile.mkdtemp()
270 270 os.name = "posix"
271 271 env.pop('IPYTHON_DIR', None)
272 272 env.pop('IPYTHONDIR', None)
273 273 env.pop('XDG_CONFIG_HOME', None)
274 274 env['HOME'] = tmpdir
275 275 ipdir = os.path.join(tmpdir, '.ipython')
276 276 os.mkdir(ipdir, 0o555)
277 277 try:
278 278 open(os.path.join(ipdir, "_foo_"), 'w').close()
279 279 except IOError:
280 280 pass
281 281 else:
282 282 # I can still write to an unwritable dir,
283 283 # assume I'm root and skip the test
284 284 raise SkipTest("I can't create directories that I can't write to")
285 285 with AssertPrints('is not a writable location', channel='stderr'):
286 286 ipdir = paths.get_ipython_dir()
287 287 env.pop('IPYTHON_DIR', None)
288 288
289 289 @with_environment
290 290 def test_get_py_filename():
291 291 os.chdir(TMP_TEST_DIR)
292 292 with make_tempfile('foo.py'):
293 293 nt.assert_equal(path.get_py_filename('foo.py'), 'foo.py')
294 294 nt.assert_equal(path.get_py_filename('foo'), 'foo.py')
295 295 with make_tempfile('foo'):
296 296 nt.assert_equal(path.get_py_filename('foo'), 'foo')
297 297 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
298 298 nt.assert_raises(IOError, path.get_py_filename, 'foo')
299 299 nt.assert_raises(IOError, path.get_py_filename, 'foo.py')
300 300 true_fn = 'foo with spaces.py'
301 301 with make_tempfile(true_fn):
302 302 nt.assert_equal(path.get_py_filename('foo with spaces'), true_fn)
303 303 nt.assert_equal(path.get_py_filename('foo with spaces.py'), true_fn)
304 304 nt.assert_raises(IOError, path.get_py_filename, '"foo with spaces.py"')
305 305 nt.assert_raises(IOError, path.get_py_filename, "'foo with spaces.py'")
306 306
307 307 @onlyif_unicode_paths
308 308 def test_unicode_in_filename():
309 309 """When a file doesn't exist, the exception raised should be safe to call
310 310 str() on - i.e. in Python 2 it must only have ASCII characters.
311 311
312 312 https://github.com/ipython/ipython/issues/875
313 313 """
314 314 try:
315 315 # these calls should not throw unicode encode exceptions
316 316 path.get_py_filename('fooéè.py', force_win32=False)
317 317 except IOError as ex:
318 318 str(ex)
319 319
320 320
321 321 class TestShellGlob(unittest.TestCase):
322 322
323 323 @classmethod
324 324 def setUpClass(cls):
325 325 cls.filenames_start_with_a = ['a0', 'a1', 'a2']
326 326 cls.filenames_end_with_b = ['0b', '1b', '2b']
327 327 cls.filenames = cls.filenames_start_with_a + cls.filenames_end_with_b
328 328 cls.tempdir = TemporaryDirectory()
329 329 td = cls.tempdir.name
330 330
331 331 with cls.in_tempdir():
332 332 # Create empty files
333 333 for fname in cls.filenames:
334 334 open(os.path.join(td, fname), 'w').close()
335 335
336 336 @classmethod
337 337 def tearDownClass(cls):
338 338 cls.tempdir.cleanup()
339 339
340 340 @classmethod
341 341 @contextmanager
342 342 def in_tempdir(cls):
343 343 save = os.getcwd()
344 344 try:
345 345 os.chdir(cls.tempdir.name)
346 346 yield
347 347 finally:
348 348 os.chdir(save)
349 349
350 350 def check_match(self, patterns, matches):
351 351 with self.in_tempdir():
352 352 # glob returns unordered list. that's why sorted is required.
353 353 nt.assert_equal(sorted(path.shellglob(patterns)),
354 354 sorted(matches))
355 355
356 356 def common_cases(self):
357 357 return [
358 358 (['*'], self.filenames),
359 359 (['a*'], self.filenames_start_with_a),
360 360 (['*c'], ['*c']),
361 361 (['*', 'a*', '*b', '*c'], self.filenames
362 362 + self.filenames_start_with_a
363 363 + self.filenames_end_with_b
364 364 + ['*c']),
365 365 (['a[012]'], self.filenames_start_with_a),
366 366 ]
367 367
368 368 @skip_win32
369 369 def test_match_posix(self):
370 370 for (patterns, matches) in self.common_cases() + [
371 371 ([r'\*'], ['*']),
372 372 ([r'a\*', 'a*'], ['a*'] + self.filenames_start_with_a),
373 373 ([r'a\[012]'], ['a[012]']),
374 374 ]:
375 375 yield (self.check_match, patterns, matches)
376 376
377 377 @skip_if_not_win32
378 378 def test_match_windows(self):
379 379 for (patterns, matches) in self.common_cases() + [
380 380 # In windows, backslash is interpreted as path
381 381 # separator. Therefore, you can't escape glob
382 382 # using it.
383 383 ([r'a\*', 'a*'], [r'a\*'] + self.filenames_start_with_a),
384 384 ([r'a\[012]'], [r'a\[012]']),
385 385 ]:
386 386 yield (self.check_match, patterns, matches)
387 387
388 388
389 389 def test_unescape_glob():
390 390 nt.assert_equal(path.unescape_glob(r'\*\[\!\]\?'), '*[!]?')
391 391 nt.assert_equal(path.unescape_glob(r'\\*'), r'\*')
392 392 nt.assert_equal(path.unescape_glob(r'\\\*'), r'\*')
393 393 nt.assert_equal(path.unescape_glob(r'\\a'), r'\a')
394 394 nt.assert_equal(path.unescape_glob(r'\a'), r'\a')
395 395
396 396
397 397 @onlyif_unicode_paths
398 398 def test_ensure_dir_exists():
399 399 with TemporaryDirectory() as td:
400 400 d = os.path.join(td, 'βˆ‚ir')
401 401 path.ensure_dir_exists(d) # create it
402 402 assert os.path.isdir(d)
403 403 path.ensure_dir_exists(d) # no-op
404 404 f = os.path.join(td, 'Ζ’ile')
405 405 open(f, 'w').close() # touch
406 406 with nt.assert_raises(IOError):
407 407 path.ensure_dir_exists(f)
408 408
409 409 class TestLinkOrCopy(object):
410 410 def setUp(self):
411 411 self.tempdir = TemporaryDirectory()
412 412 self.src = self.dst("src")
413 413 with open(self.src, "w") as f:
414 414 f.write("Hello, world!")
415 415
416 416 def tearDown(self):
417 417 self.tempdir.cleanup()
418 418
419 419 def dst(self, *args):
420 420 return os.path.join(self.tempdir.name, *args)
421 421
422 422 def assert_inode_not_equal(self, a, b):
423 423 nt.assert_not_equal(os.stat(a).st_ino, os.stat(b).st_ino,
424 424 "%r and %r do reference the same indoes" %(a, b))
425 425
426 426 def assert_inode_equal(self, a, b):
427 427 nt.assert_equal(os.stat(a).st_ino, os.stat(b).st_ino,
428 428 "%r and %r do not reference the same indoes" %(a, b))
429 429
430 430 def assert_content_equal(self, a, b):
431 431 with open(a) as a_f:
432 432 with open(b) as b_f:
433 433 nt.assert_equal(a_f.read(), b_f.read())
434 434
435 435 @skip_win32
436 436 def test_link_successful(self):
437 437 dst = self.dst("target")
438 438 path.link_or_copy(self.src, dst)
439 439 self.assert_inode_equal(self.src, dst)
440 440
441 441 @skip_win32
442 442 def test_link_into_dir(self):
443 443 dst = self.dst("some_dir")
444 444 os.mkdir(dst)
445 445 path.link_or_copy(self.src, dst)
446 446 expected_dst = self.dst("some_dir", os.path.basename(self.src))
447 447 self.assert_inode_equal(self.src, expected_dst)
448 448
449 449 @skip_win32
450 450 def test_target_exists(self):
451 451 dst = self.dst("target")
452 452 open(dst, "w").close()
453 453 path.link_or_copy(self.src, dst)
454 454 self.assert_inode_equal(self.src, dst)
455 455
456 456 @skip_win32
457 457 def test_no_link(self):
458 458 real_link = os.link
459 459 try:
460 460 del os.link
461 461 dst = self.dst("target")
462 462 path.link_or_copy(self.src, dst)
463 463 self.assert_content_equal(self.src, dst)
464 464 self.assert_inode_not_equal(self.src, dst)
465 465 finally:
466 466 os.link = real_link
467 467
468 468 @skip_if_not_win32
469 469 def test_windows(self):
470 470 dst = self.dst("target")
471 471 path.link_or_copy(self.src, dst)
472 472 self.assert_content_equal(self.src, dst)
473 473
474 474 def test_link_twice(self):
475 475 # Linking the same file twice shouldn't leave duplicates around.
476 476 # See https://github.com/ipython/ipython/issues/6450
477 477 dst = self.dst('target')
478 478 path.link_or_copy(self.src, dst)
479 479 path.link_or_copy(self.src, dst)
480 480 self.assert_inode_equal(self.src, dst)
481 481 nt.assert_equal(sorted(os.listdir(self.tempdir.name)), ['src', 'target'])
General Comments 0
You need to be logged in to leave comments. Login now