##// END OF EJS Templates
Add some unit tests for the new dictionary syntax for installing nbextensions
Jason Grout -
Show More
@@ -1,282 +1,293 b''
1 # coding: utf-8
1 # coding: utf-8
2 """Test installation of notebook extensions"""
2 """Test installation of notebook extensions"""
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 glob
7 import glob
8 import os
8 import os
9 import re
9 import re
10 import tarfile
10 import tarfile
11 import zipfile
11 import zipfile
12 from io import BytesIO
12 from io import BytesIO
13 from os.path import basename, join as pjoin
13 from os.path import basename, join as pjoin
14 from unittest import TestCase
14 from unittest import TestCase
15
15
16 import IPython.testing.tools as tt
16 import IPython.testing.tools as tt
17 import IPython.testing.decorators as dec
17 import IPython.testing.decorators as dec
18 from IPython.utils import py3compat
18 from IPython.utils import py3compat
19 from IPython.utils.tempdir import TemporaryDirectory
19 from IPython.utils.tempdir import TemporaryDirectory
20 from IPython.html import nbextensions
20 from IPython.html import nbextensions
21 from IPython.html.nbextensions import install_nbextension, check_nbextension
21 from IPython.html.nbextensions import install_nbextension, check_nbextension
22
22
23
23
24 def touch(file, mtime=None):
24 def touch(file, mtime=None):
25 """ensure a file exists, and set its modification time
25 """ensure a file exists, and set its modification time
26
26
27 returns the modification time of the file
27 returns the modification time of the file
28 """
28 """
29 open(file, 'a').close()
29 open(file, 'a').close()
30 # set explicit mtime
30 # set explicit mtime
31 if mtime:
31 if mtime:
32 atime = os.stat(file).st_atime
32 atime = os.stat(file).st_atime
33 os.utime(file, (atime, mtime))
33 os.utime(file, (atime, mtime))
34 return os.stat(file).st_mtime
34 return os.stat(file).st_mtime
35
35
36 class TestInstallNBExtension(TestCase):
36 class TestInstallNBExtension(TestCase):
37
37
38 def tempdir(self):
38 def tempdir(self):
39 td = TemporaryDirectory()
39 td = TemporaryDirectory()
40 self.tempdirs.append(td)
40 self.tempdirs.append(td)
41 return py3compat.cast_unicode(td.name)
41 return py3compat.cast_unicode(td.name)
42
42
43 def setUp(self):
43 def setUp(self):
44 self.tempdirs = []
44 self.tempdirs = []
45 src = self.src = self.tempdir()
45 src = self.src = self.tempdir()
46 self.files = files = [
46 self.files = files = [
47 pjoin(u'ƒile'),
47 pjoin(u'ƒile'),
48 pjoin(u'∂ir', u'ƒile1'),
48 pjoin(u'∂ir', u'ƒile1'),
49 pjoin(u'∂ir', u'∂ir2', u'ƒile2'),
49 pjoin(u'∂ir', u'∂ir2', u'ƒile2'),
50 ]
50 ]
51 for file in files:
51 for file in files:
52 fullpath = os.path.join(self.src, file)
52 fullpath = os.path.join(self.src, file)
53 parent = os.path.dirname(fullpath)
53 parent = os.path.dirname(fullpath)
54 if not os.path.exists(parent):
54 if not os.path.exists(parent):
55 os.makedirs(parent)
55 os.makedirs(parent)
56 touch(fullpath)
56 touch(fullpath)
57
57
58 self.ipdir = self.tempdir()
58 self.ipdir = self.tempdir()
59 self.save_get_ipython_dir = nbextensions.get_ipython_dir
59 self.save_get_ipython_dir = nbextensions.get_ipython_dir
60 nbextensions.get_ipython_dir = lambda : self.ipdir
60 nbextensions.get_ipython_dir = lambda : self.ipdir
61 self.save_system_dir = nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR
61 self.save_system_dir = nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR
62 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.system_nbext = self.tempdir()
62 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.system_nbext = self.tempdir()
63
63
64 def tearDown(self):
64 def tearDown(self):
65 nbextensions.get_ipython_dir = self.save_get_ipython_dir
65 nbextensions.get_ipython_dir = self.save_get_ipython_dir
66 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.save_system_dir
66 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.save_system_dir
67 for td in self.tempdirs:
67 for td in self.tempdirs:
68 td.cleanup()
68 td.cleanup()
69
69
70 def assert_dir_exists(self, path):
70 def assert_dir_exists(self, path):
71 if not os.path.exists(path):
71 if not os.path.exists(path):
72 do_exist = os.listdir(os.path.dirname(path))
72 do_exist = os.listdir(os.path.dirname(path))
73 self.fail(u"%s should exist (found %s)" % (path, do_exist))
73 self.fail(u"%s should exist (found %s)" % (path, do_exist))
74
74
75 def assert_not_dir_exists(self, path):
75 def assert_not_dir_exists(self, path):
76 if os.path.exists(path):
76 if os.path.exists(path):
77 self.fail(u"%s should not exist" % path)
77 self.fail(u"%s should not exist" % path)
78
78
79 def assert_installed(self, relative_path, user=False):
79 def assert_installed(self, relative_path, user=False):
80 if user:
80 if user:
81 nbext = pjoin(self.ipdir, u'nbextensions')
81 nbext = pjoin(self.ipdir, u'nbextensions')
82 else:
82 else:
83 nbext = self.system_nbext
83 nbext = self.system_nbext
84 self.assert_dir_exists(
84 self.assert_dir_exists(
85 pjoin(nbext, relative_path)
85 pjoin(nbext, relative_path)
86 )
86 )
87
87
88 def assert_not_installed(self, relative_path, user=False):
88 def assert_not_installed(self, relative_path, user=False):
89 if user:
89 if user:
90 nbext = pjoin(self.ipdir, u'nbextensions')
90 nbext = pjoin(self.ipdir, u'nbextensions')
91 else:
91 else:
92 nbext = self.system_nbext
92 nbext = self.system_nbext
93 self.assert_not_dir_exists(
93 self.assert_not_dir_exists(
94 pjoin(nbext, relative_path)
94 pjoin(nbext, relative_path)
95 )
95 )
96
96
97 def test_create_ipython_dir(self):
97 def test_create_ipython_dir(self):
98 """install_nbextension when ipython_dir doesn't exist"""
98 """install_nbextension when ipython_dir doesn't exist"""
99 with TemporaryDirectory() as td:
99 with TemporaryDirectory() as td:
100 self.ipdir = ipdir = pjoin(td, u'ipython')
100 self.ipdir = ipdir = pjoin(td, u'ipython')
101 install_nbextension(self.src, user=True)
101 install_nbextension(self.src, user=True)
102 self.assert_dir_exists(ipdir)
102 self.assert_dir_exists(ipdir)
103 for file in self.files:
103 for file in self.files:
104 self.assert_installed(
104 self.assert_installed(
105 pjoin(basename(self.src), file),
105 pjoin(basename(self.src), file),
106 ipdir
106 ipdir
107 )
107 )
108
108
109 def test_create_nbextensions_user(self):
109 def test_create_nbextensions_user(self):
110 with TemporaryDirectory() as td:
110 with TemporaryDirectory() as td:
111 self.ipdir = ipdir = pjoin(td, u'ipython')
111 self.ipdir = ipdir = pjoin(td, u'ipython')
112 install_nbextension(self.src, user=True)
112 install_nbextension(self.src, user=True)
113 self.assert_installed(
113 self.assert_installed(
114 pjoin(basename(self.src), u'ƒile'),
114 pjoin(basename(self.src), u'ƒile'),
115 user=True
115 user=True
116 )
116 )
117
117
118 def test_create_nbextensions_system(self):
118 def test_create_nbextensions_system(self):
119 with TemporaryDirectory() as td:
119 with TemporaryDirectory() as td:
120 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.system_nbext = pjoin(td, u'nbextensions')
120 nbextensions.SYSTEM_NBEXTENSIONS_INSTALL_DIR = self.system_nbext = pjoin(td, u'nbextensions')
121 install_nbextension(self.src, user=False)
121 install_nbextension(self.src, user=False)
122 self.assert_installed(
122 self.assert_installed(
123 pjoin(basename(self.src), u'ƒile'),
123 pjoin(basename(self.src), u'ƒile'),
124 user=False
124 user=False
125 )
125 )
126
126
127 def test_single_file(self):
127 def test_single_file(self):
128 file = self.files[0]
128 file = self.files[0]
129 install_nbextension(pjoin(self.src, file))
129 install_nbextension(pjoin(self.src, file))
130 self.assert_installed(file)
130 self.assert_installed(file)
131
131
132 def test_single_dir(self):
132 def test_single_dir(self):
133 d = u'∂ir'
133 d = u'∂ir'
134 install_nbextension(pjoin(self.src, d))
134 install_nbextension(pjoin(self.src, d))
135 self.assert_installed(self.files[-1])
135 self.assert_installed(self.files[-1])
136 install_nbextension({'test': pjoin(self.src, d)})
137 self.assert_installed(pjoin('test', u'∂ir2', u'ƒile2'))
136
138
137 def test_install_nbextension(self):
139 def test_install_nbextension(self):
138 install_nbextension(glob.glob(pjoin(self.src, '*')))
140 install_nbextension(glob.glob(pjoin(self.src, '*')))
139 for file in self.files:
141 for file in self.files:
140 self.assert_installed(file)
142 self.assert_installed(file)
141
143
142 def test_overwrite_file(self):
144 def test_overwrite_file(self):
143 with TemporaryDirectory() as d:
145 with TemporaryDirectory() as d:
144 fname = u'ƒ.js'
146 fname = u'ƒ.js'
145 src = pjoin(d, fname)
147 src = pjoin(d, fname)
146 with open(src, 'w') as f:
148 with open(src, 'w') as f:
147 f.write('first')
149 f.write('first')
148 mtime = touch(src)
150 mtime = touch(src)
149 dest = pjoin(self.system_nbext, fname)
151 dest = pjoin(self.system_nbext, fname)
150 install_nbextension(src)
152 install_nbextension(src)
151 with open(src, 'w') as f:
153 with open(src, 'w') as f:
152 f.write('overwrite')
154 f.write('overwrite')
153 mtime = touch(src, mtime - 100)
155 mtime = touch(src, mtime - 100)
154 install_nbextension(src, overwrite=True)
156 install_nbextension(src, overwrite=True)
155 with open(dest) as f:
157 with open(dest) as f:
156 self.assertEqual(f.read(), 'overwrite')
158 self.assertEqual(f.read(), 'overwrite')
157
159
158 def test_overwrite_dir(self):
160 def test_overwrite_dir(self):
159 with TemporaryDirectory() as src:
161 with TemporaryDirectory() as src:
160 base = basename(src)
162 base = basename(src)
161 fname = u'ƒ.js'
163 fname = u'ƒ.js'
162 touch(pjoin(src, fname))
164 touch(pjoin(src, fname))
163 install_nbextension(src)
165 install_nbextension(src)
164 self.assert_installed(pjoin(base, fname))
166 self.assert_installed(pjoin(base, fname))
165 os.remove(pjoin(src, fname))
167 os.remove(pjoin(src, fname))
166 fname2 = u'∂.js'
168 fname2 = u'∂.js'
167 touch(pjoin(src, fname2))
169 touch(pjoin(src, fname2))
168 install_nbextension(src, overwrite=True)
170 install_nbextension(src, overwrite=True)
169 self.assert_installed(pjoin(base, fname2))
171 self.assert_installed(pjoin(base, fname2))
170 self.assert_not_installed(pjoin(base, fname))
172 self.assert_not_installed(pjoin(base, fname))
171
173
172 def test_update_file(self):
174 def test_update_file(self):
173 with TemporaryDirectory() as d:
175 with TemporaryDirectory() as d:
174 fname = u'ƒ.js'
176 fname = u'ƒ.js'
175 src = pjoin(d, fname)
177 src = pjoin(d, fname)
176 with open(src, 'w') as f:
178 with open(src, 'w') as f:
177 f.write('first')
179 f.write('first')
178 mtime = touch(src)
180 mtime = touch(src)
179 install_nbextension(src)
181 install_nbextension(src)
180 self.assert_installed(fname)
182 self.assert_installed(fname)
181 dest = pjoin(self.system_nbext, fname)
183 dest = pjoin(self.system_nbext, fname)
182 old_mtime = os.stat(dest).st_mtime
184 old_mtime = os.stat(dest).st_mtime
183 with open(src, 'w') as f:
185 with open(src, 'w') as f:
184 f.write('overwrite')
186 f.write('overwrite')
185 touch(src, mtime + 10)
187 touch(src, mtime + 10)
186 install_nbextension(src)
188 install_nbextension(src)
187 with open(dest) as f:
189 with open(dest) as f:
188 self.assertEqual(f.read(), 'overwrite')
190 self.assertEqual(f.read(), 'overwrite')
189
191
190 def test_skip_old_file(self):
192 def test_skip_old_file(self):
191 with TemporaryDirectory() as d:
193 with TemporaryDirectory() as d:
192 fname = u'ƒ.js'
194 fname = u'ƒ.js'
193 src = pjoin(d, fname)
195 src = pjoin(d, fname)
194 mtime = touch(src)
196 mtime = touch(src)
195 install_nbextension(src)
197 install_nbextension(src)
196 self.assert_installed(fname)
198 self.assert_installed(fname)
197 dest = pjoin(self.system_nbext, fname)
199 dest = pjoin(self.system_nbext, fname)
198 old_mtime = os.stat(dest).st_mtime
200 old_mtime = os.stat(dest).st_mtime
199
201
200 mtime = touch(src, mtime - 100)
202 mtime = touch(src, mtime - 100)
201 install_nbextension(src)
203 install_nbextension(src)
202 new_mtime = os.stat(dest).st_mtime
204 new_mtime = os.stat(dest).st_mtime
203 self.assertEqual(new_mtime, old_mtime)
205 self.assertEqual(new_mtime, old_mtime)
204
206
205 def test_quiet(self):
207 def test_quiet(self):
206 with tt.AssertNotPrints(re.compile(r'.+')):
208 with tt.AssertNotPrints(re.compile(r'.+')):
207 install_nbextension(self.src, verbose=0)
209 install_nbextension(self.src, verbose=0)
208
210
209 def test_install_zip(self):
211 def test_install_zip(self):
210 path = pjoin(self.src, "myjsext.zip")
212 path = pjoin(self.src, "myjsext.zip")
211 with zipfile.ZipFile(path, 'w') as f:
213 with zipfile.ZipFile(path, 'w') as f:
212 f.writestr("a.js", b"b();")
214 f.writestr("a.js", b"b();")
213 f.writestr("foo/a.js", b"foo();")
215 f.writestr("foo/a.js", b"foo();")
214 install_nbextension(path)
216 install_nbextension(path)
215 self.assert_installed("a.js")
217 self.assert_installed("a.js")
216 self.assert_installed(pjoin("foo", "a.js"))
218 self.assert_installed(pjoin("foo", "a.js"))
217
219
218 def test_install_tar(self):
220 def test_install_tar(self):
219 def _add_file(f, fname, buf):
221 def _add_file(f, fname, buf):
220 info = tarfile.TarInfo(fname)
222 info = tarfile.TarInfo(fname)
221 info.size = len(buf)
223 info.size = len(buf)
222 f.addfile(info, BytesIO(buf))
224 f.addfile(info, BytesIO(buf))
223
225
224 for i,ext in enumerate((".tar.gz", ".tgz", ".tar.bz2")):
226 for i,ext in enumerate((".tar.gz", ".tgz", ".tar.bz2")):
225 path = pjoin(self.src, "myjsext" + ext)
227 path = pjoin(self.src, "myjsext" + ext)
226 with tarfile.open(path, 'w') as f:
228 with tarfile.open(path, 'w') as f:
227 _add_file(f, "b%i.js" % i, b"b();")
229 _add_file(f, "b%i.js" % i, b"b();")
228 _add_file(f, "foo/b%i.js" % i, b"foo();")
230 _add_file(f, "foo/b%i.js" % i, b"foo();")
229 install_nbextension(path)
231 install_nbextension(path)
230 self.assert_installed("b%i.js" % i)
232 self.assert_installed("b%i.js" % i)
231 self.assert_installed(pjoin("foo", "b%i.js" % i))
233 self.assert_installed(pjoin("foo", "b%i.js" % i))
232
234
233 def test_install_url(self):
235 def test_install_url(self):
234 def fake_urlretrieve(url, dest):
236 def fake_urlretrieve(url, dest):
235 touch(dest)
237 touch(dest)
236 save_urlretrieve = nbextensions.urlretrieve
238 save_urlretrieve = nbextensions.urlretrieve
237 nbextensions.urlretrieve = fake_urlretrieve
239 nbextensions.urlretrieve = fake_urlretrieve
238 try:
240 try:
239 install_nbextension("http://example.com/path/to/foo.js")
241 install_nbextension("http://example.com/path/to/foo.js")
240 self.assert_installed("foo.js")
242 self.assert_installed("foo.js")
241 install_nbextension("https://example.com/path/to/another/bar.js")
243 install_nbextension("https://example.com/path/to/another/bar.js")
242 self.assert_installed("bar.js")
244 self.assert_installed("bar.js")
245 install_nbextension({'foobar.js': "https://example.com/path/to/another/bar.js"})
246 self.assert_installed("foobar.js")
243 finally:
247 finally:
244 nbextensions.urlretrieve = save_urlretrieve
248 nbextensions.urlretrieve = save_urlretrieve
245
249
246 def test_check_nbextension(self):
250 def test_check_nbextension(self):
247 with TemporaryDirectory() as d:
251 with TemporaryDirectory() as d:
248 f = u'ƒ.js'
252 f = u'ƒ.js'
249 src = pjoin(d, f)
253 src = pjoin(d, f)
250 touch(src)
254 touch(src)
251 install_nbextension(src, user=True)
255 install_nbextension(src, user=True)
252
256
253 nbext = pjoin(self.ipdir, u'nbextensions')
257 assert check_nbextension(f, user=True)
254 assert check_nbextension(f, nbext)
258 assert check_nbextension([f], user=True)
255 assert check_nbextension([f], nbext)
259 assert not check_nbextension([f, pjoin('dne', f)], user=True)
256 assert not check_nbextension([f, pjoin('dne', f)], nbext)
257
260
258 @dec.skip_win32
261 @dec.skip_win32
259 def test_install_symlink(self):
262 def test_install_symlink(self):
260 with TemporaryDirectory() as d:
263 with TemporaryDirectory() as d:
261 f = u'ƒ.js'
264 f = u'ƒ.js'
262 src = pjoin(d, f)
265 src = pjoin(d, f)
263 touch(src)
266 touch(src)
264 install_nbextension(src, symlink=True)
267 install_nbextension(src, symlink=True)
265 dest = pjoin(self.system_nbext, f)
268 dest = pjoin(self.system_nbext, f)
266 assert os.path.islink(dest)
269 assert os.path.islink(dest)
267 link = os.readlink(dest)
270 link = os.readlink(dest)
268 self.assertEqual(link, src)
271 self.assertEqual(link, src)
269
272
270 def test_install_symlink_bad(self):
273 def test_install_symlink_bad(self):
271 with self.assertRaises(ValueError):
274 with self.assertRaises(ValueError):
272 install_nbextension("http://example.com/foo.js", symlink=True)
275 install_nbextension("http://example.com/foo.js", symlink=True)
273
276
274 with TemporaryDirectory() as d:
277 with TemporaryDirectory() as d:
275 zf = u'ƒ.zip'
278 zf = u'ƒ.zip'
276 zsrc = pjoin(d, zf)
279 zsrc = pjoin(d, zf)
277 with zipfile.ZipFile(zsrc, 'w') as z:
280 with zipfile.ZipFile(zsrc, 'w') as z:
278 z.writestr("a.js", b"b();")
281 z.writestr("a.js", b"b();")
279
282
280 with self.assertRaises(ValueError):
283 with self.assertRaises(ValueError):
281 install_nbextension(zsrc, symlink=True)
284 install_nbextension(zsrc, symlink=True)
282
285
286 def test_install_different_name(self):
287 with TemporaryDirectory() as d:
288 f = u'ƒ.js'
289 src = pjoin(d, f)
290 dest_f = 'ƒile.js'
291 touch(src)
292 install_nbextension({dest_f: src})
293 self.assert_installed(dest_f)
General Comments 0
You need to be logged in to leave comments. Login now