Show More
@@ -12,7 +12,7 b' pjoin = os.path.join' | |||||
12 |
|
12 | |||
13 | import requests |
|
13 | import requests | |
14 |
|
14 | |||
15 | from IPython.html.utils import url_path_join, url_escape |
|
15 | from IPython.html.utils import url_path_join, url_escape, to_os_path | |
16 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error |
|
16 | from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error | |
17 | from IPython.nbformat import read, write, from_dict |
|
17 | from IPython.nbformat import read, write, from_dict | |
18 | from IPython.nbformat.v4 import ( |
|
18 | from IPython.nbformat.v4 import ( | |
@@ -73,9 +73,6 b' class API(object):' | |||||
73 | def upload(self, path, body): |
|
73 | def upload(self, path, body): | |
74 | return self._req('PUT', path, body) |
|
74 | return self._req('PUT', path, body) | |
75 |
|
75 | |||
76 | def mkdir_untitled(self, path='/'): |
|
|||
77 | return self._req('POST', path, json.dumps({'type': 'directory'})) |
|
|||
78 |
|
||||
79 | def mkdir(self, path='/'): |
|
76 | def mkdir(self, path='/'): | |
80 | return self._req('PUT', path, json.dumps({'type': 'directory'})) |
|
77 | return self._req('PUT', path, json.dumps({'type': 'directory'})) | |
81 |
|
78 | |||
@@ -133,33 +130,62 b' class APITest(NotebookTestBase):' | |||||
133 | @staticmethod |
|
130 | @staticmethod | |
134 | def _txt_for_name(name): |
|
131 | def _txt_for_name(name): | |
135 | return u'%s text file' % name |
|
132 | return u'%s text file' % name | |
136 |
|
133 | |||
|
134 | def to_os_path(self, api_path): | |||
|
135 | return to_os_path(api_path, root=self.notebook_dir.name) | |||
|
136 | ||||
|
137 | def make_dir(self, api_path): | |||
|
138 | """Create a directory at api_path""" | |||
|
139 | os_path = self.to_os_path(api_path) | |||
|
140 | try: | |||
|
141 | os.makedirs(os_path) | |||
|
142 | except OSError: | |||
|
143 | print("Directory already exists: %r" % os_path) | |||
|
144 | ||||
|
145 | def make_txt(self, api_path, txt): | |||
|
146 | """Make a text file at a given api_path""" | |||
|
147 | os_path = self.to_os_path(api_path) | |||
|
148 | with io.open(os_path, 'w', encoding='utf-8') as f: | |||
|
149 | f.write(txt) | |||
|
150 | ||||
|
151 | def make_blob(self, api_path, blob): | |||
|
152 | """Make a binary file at a given api_path""" | |||
|
153 | os_path = self.to_os_path(api_path) | |||
|
154 | with io.open(os_path, 'wb') as f: | |||
|
155 | f.write(blob) | |||
|
156 | ||||
|
157 | def make_nb(self, api_path, nb): | |||
|
158 | """Make a notebook file at a given api_path""" | |||
|
159 | os_path = self.to_os_path(api_path) | |||
|
160 | ||||
|
161 | with io.open(os_path, 'w', encoding='utf-8') as f: | |||
|
162 | write(nb, f, version=4) | |||
|
163 | ||||
|
164 | def isfile(self, api_path): | |||
|
165 | return os.path.isfile(self.to_os_path(api_path)) | |||
|
166 | ||||
|
167 | def isdir(self, api_path): | |||
|
168 | return os.path.isdir(self.to_os_path(api_path)) | |||
|
169 | ||||
137 | def setUp(self): |
|
170 | def setUp(self): | |
138 | nbdir = self.notebook_dir.name |
|
|||
139 | self.blob = os.urandom(100) |
|
171 | self.blob = os.urandom(100) | |
140 | self.b64_blob = base64.encodestring(self.blob).decode('ascii') |
|
172 | self.b64_blob = base64.encodestring(self.blob).decode('ascii') | |
141 |
|
173 | |||
142 | for d in (self.dirs + self.hidden_dirs): |
|
174 | for d in (self.dirs + self.hidden_dirs): | |
143 | d.replace('/', os.sep) |
|
175 | self.make_dir(d) | |
144 | if not os.path.isdir(pjoin(nbdir, d)): |
|
|||
145 | os.mkdir(pjoin(nbdir, d)) |
|
|||
146 |
|
176 | |||
147 | for d, name in self.dirs_nbs: |
|
177 | for d, name in self.dirs_nbs: | |
148 | d = d.replace('/', os.sep) |
|
|||
149 | # create a notebook |
|
178 | # create a notebook | |
150 | with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w', |
|
179 | nb = new_notebook() | |
151 | encoding='utf-8') as f: |
|
180 | self.make_nb(u'{}/{}.ipynb'.format(d, name), nb) | |
152 | nb = new_notebook() |
|
181 | ||
153 | write(nb, f, version=4) |
|
|||
154 |
|
||||
155 | # create a text file |
|
182 | # create a text file | |
156 | with io.open(pjoin(nbdir, d, '%s.txt' % name), 'w', |
|
183 | txt = self._txt_for_name(name) | |
157 | encoding='utf-8') as f: |
|
184 | self.make_txt(u'{}/{}.txt'.format(d, name), txt) | |
158 | f.write(self._txt_for_name(name)) |
|
185 | ||
159 |
|
||||
160 | # create a binary file |
|
186 | # create a binary file | |
161 | with io.open(pjoin(nbdir, d, '%s.blob' % name), 'wb') as f: |
|
187 | blob = self._blob_for_name(name) | |
162 | f.write(self._blob_for_name(name)) |
|
188 | self.make_blob(u'{}/{}.blob'.format(d, name), blob) | |
163 |
|
189 | |||
164 | self.api = API(self.base_url()) |
|
190 | self.api = API(self.base_url()) | |
165 |
|
191 | |||
@@ -204,11 +230,8 b' class APITest(NotebookTestBase):' | |||||
204 | self.assertEqual(nbnames, expected) |
|
230 | self.assertEqual(nbnames, expected) | |
205 |
|
231 | |||
206 | def test_list_dirs(self): |
|
232 | def test_list_dirs(self): | |
207 | print(self.api.list().json()) |
|
|||
208 | dirs = dirs_only(self.api.list().json()) |
|
233 | dirs = dirs_only(self.api.list().json()) | |
209 | dir_names = {normalize('NFC', d['name']) for d in dirs} |
|
234 | dir_names = {normalize('NFC', d['name']) for d in dirs} | |
210 | print(dir_names) |
|
|||
211 | print(self.top_level_dirs) |
|
|||
212 | self.assertEqual(dir_names, self.top_level_dirs) # Excluding hidden dirs |
|
235 | self.assertEqual(dir_names, self.top_level_dirs) # Excluding hidden dirs | |
213 |
|
236 | |||
214 | def test_list_nonexistant_dir(self): |
|
237 | def test_list_nonexistant_dir(self): | |
@@ -283,11 +306,8 b' class APITest(NotebookTestBase):' | |||||
283 | self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1]) |
|
306 | self.assertEqual(rjson['name'], path.rsplit('/', 1)[-1]) | |
284 | self.assertEqual(rjson['path'], path) |
|
307 | self.assertEqual(rjson['path'], path) | |
285 | self.assertEqual(rjson['type'], type) |
|
308 | self.assertEqual(rjson['type'], type) | |
286 |
isright = |
|
309 | isright = self.isdir if type == 'directory' else self.isfile | |
287 |
assert isright(p |
|
310 | assert isright(path) | |
288 | self.notebook_dir.name, |
|
|||
289 | path.replace('/', os.sep), |
|
|||
290 | )) |
|
|||
291 |
|
311 | |||
292 | def test_create_untitled(self): |
|
312 | def test_create_untitled(self): | |
293 | resp = self.api.create_untitled(path=u'å b') |
|
313 | resp = self.api.create_untitled(path=u'å b') | |
@@ -451,7 +471,7 b' class APITest(NotebookTestBase):' | |||||
451 | self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb') |
|
471 | self.assertEqual(resp.headers['Location'].split('/')[-1], 'z.ipynb') | |
452 | self.assertEqual(resp.json()['name'], 'z.ipynb') |
|
472 | self.assertEqual(resp.json()['name'], 'z.ipynb') | |
453 | self.assertEqual(resp.json()['path'], 'foo/z.ipynb') |
|
473 | self.assertEqual(resp.json()['path'], 'foo/z.ipynb') | |
454 |
assert |
|
474 | assert self.isfile('foo/z.ipynb') | |
455 |
|
475 | |||
456 | nbs = notebooks_only(self.api.list('foo').json()) |
|
476 | nbs = notebooks_only(self.api.list('foo').json()) | |
457 | nbnames = set(n['name'] for n in nbs) |
|
477 | nbnames = set(n['name'] for n in nbs) | |
@@ -471,11 +491,6 b' class APITest(NotebookTestBase):' | |||||
471 | nbmodel= {'content': nb, 'type': 'notebook'} |
|
491 | nbmodel= {'content': nb, 'type': 'notebook'} | |
472 | resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) |
|
492 | resp = self.api.save('foo/a.ipynb', body=json.dumps(nbmodel)) | |
473 |
|
493 | |||
474 | nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb') |
|
|||
475 | with io.open(nbfile, 'r', encoding='utf-8') as f: |
|
|||
476 | newnb = read(f, as_version=4) |
|
|||
477 | self.assertEqual(newnb.cells[0].source, |
|
|||
478 | u'Created by test ³') |
|
|||
479 | nbcontent = self.api.read('foo/a.ipynb').json()['content'] |
|
494 | nbcontent = self.api.read('foo/a.ipynb').json()['content'] | |
480 | newnb = from_dict(nbcontent) |
|
495 | newnb = from_dict(nbcontent) | |
481 | self.assertEqual(newnb.cells[0].source, |
|
496 | self.assertEqual(newnb.cells[0].source, |
@@ -2,7 +2,6 b'' | |||||
2 | """Tests for the notebook manager.""" |
|
2 | """Tests for the notebook manager.""" | |
3 | from __future__ import print_function |
|
3 | from __future__ import print_function | |
4 |
|
4 | |||
5 | import logging |
|
|||
6 | import os |
|
5 | import os | |
7 |
|
6 | |||
8 | from tornado.web import HTTPError |
|
7 | from tornado.web import HTTPError | |
@@ -17,7 +16,6 b' from IPython.html.utils import url_path_join' | |||||
17 | from IPython.testing import decorators as dec |
|
16 | from IPython.testing import decorators as dec | |
18 |
|
17 | |||
19 | from ..filemanager import FileContentsManager |
|
18 | from ..filemanager import FileContentsManager | |
20 | from ..manager import ContentsManager |
|
|||
21 |
|
19 | |||
22 |
|
20 | |||
23 | class TestFileContentsManager(TestCase): |
|
21 | class TestFileContentsManager(TestCase): | |
@@ -72,7 +70,7 b' class TestFileContentsManager(TestCase):' | |||||
72 |
|
70 | |||
73 |
|
71 | |||
74 | class TestContentsManager(TestCase): |
|
72 | class TestContentsManager(TestCase): | |
75 |
|
73 | |||
76 | def setUp(self): |
|
74 | def setUp(self): | |
77 | self._temp_dir = TemporaryDirectory() |
|
75 | self._temp_dir = TemporaryDirectory() | |
78 | self.td = self._temp_dir.name |
|
76 | self.td = self._temp_dir.name | |
@@ -83,15 +81,25 b' class TestContentsManager(TestCase):' | |||||
83 | def tearDown(self): |
|
81 | def tearDown(self): | |
84 | self._temp_dir.cleanup() |
|
82 | self._temp_dir.cleanup() | |
85 |
|
83 | |||
86 |
def make_dir(self, a |
|
84 | def make_dir(self, api_path): | |
87 | """make subdirectory, rel_path is the relative path |
|
85 | """make subdirectory, rel_path is the relative path | |
88 | to that directory from the location where the server started""" |
|
86 | to that directory from the location where the server started""" | |
89 |
os_path = |
|
87 | os_path = self.contents_manager._get_os_path(api_path) | |
90 | try: |
|
88 | try: | |
91 | os.makedirs(os_path) |
|
89 | os.makedirs(os_path) | |
92 | except OSError: |
|
90 | except OSError: | |
93 | print("Directory already exists: %r" % os_path) |
|
91 | print("Directory already exists: %r" % os_path) | |
94 | return os_path |
|
92 | ||
|
93 | def symlink(self, src, dst): | |||
|
94 | """Make a symlink to src from dst | |||
|
95 | ||||
|
96 | src and dst are api_paths | |||
|
97 | """ | |||
|
98 | src_os_path = self.contents_manager._get_os_path(src) | |||
|
99 | dst_os_path = self.contents_manager._get_os_path(dst) | |||
|
100 | print(src_os_path, dst_os_path, os.path.isfile(src_os_path)) | |||
|
101 | os.symlink(src_os_path, dst_os_path) | |||
|
102 | ||||
95 |
|
103 | |||
96 | def add_code_cell(self, nb): |
|
104 | def add_code_cell(self, nb): | |
97 | output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"}) |
|
105 | output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"}) | |
@@ -169,7 +177,7 b' class TestContentsManager(TestCase):' | |||||
169 |
|
177 | |||
170 | # Test in sub-directory |
|
178 | # Test in sub-directory | |
171 | sub_dir = '/foo/' |
|
179 | sub_dir = '/foo/' | |
172 |
self.make_dir( |
|
180 | self.make_dir('foo') | |
173 | model = cm.new_untitled(path=sub_dir, ext='.ipynb') |
|
181 | model = cm.new_untitled(path=sub_dir, ext='.ipynb') | |
174 | model2 = cm.get(sub_dir + name) |
|
182 | model2 = cm.get(sub_dir + name) | |
175 | assert isinstance(model2, dict) |
|
183 | assert isinstance(model2, dict) | |
@@ -191,12 +199,12 b' class TestContentsManager(TestCase):' | |||||
191 | def test_bad_symlink(self): |
|
199 | def test_bad_symlink(self): | |
192 | cm = self.contents_manager |
|
200 | cm = self.contents_manager | |
193 | path = 'test bad symlink' |
|
201 | path = 'test bad symlink' | |
194 |
|
|
202 | self.make_dir(path) | |
195 |
|
203 | |||
196 | file_model = cm.new_untitled(path=path, ext='.txt') |
|
204 | file_model = cm.new_untitled(path=path, ext='.txt') | |
197 |
|
205 | |||
198 | # create a broken symlink |
|
206 | # create a broken symlink | |
199 |
|
|
207 | self.symlink("target", '%s/%s' % (path, 'bad symlink')) | |
200 | model = cm.get(path) |
|
208 | model = cm.get(path) | |
201 | self.assertEqual(model['content'], [file_model]) |
|
209 | self.assertEqual(model['content'], [file_model]) | |
202 |
|
210 | |||
@@ -206,12 +214,12 b' class TestContentsManager(TestCase):' | |||||
206 | parent = 'test good symlink' |
|
214 | parent = 'test good symlink' | |
207 | name = 'good symlink' |
|
215 | name = 'good symlink' | |
208 | path = '{0}/{1}'.format(parent, name) |
|
216 | path = '{0}/{1}'.format(parent, name) | |
209 |
|
|
217 | self.make_dir(parent) | |
210 |
|
218 | |||
211 | file_model = cm.new(path=parent + '/zfoo.txt') |
|
219 | file_model = cm.new(path=parent + '/zfoo.txt') | |
212 |
|
220 | |||
213 | # create a good symlink |
|
221 | # create a good symlink | |
214 |
|
|
222 | self.symlink(file_model['path'], path) | |
215 | symlink_model = cm.get(path, content=False) |
|
223 | symlink_model = cm.get(path, content=False) | |
216 | dir_model = cm.get(parent) |
|
224 | dir_model = cm.get(parent) | |
217 | self.assertEqual( |
|
225 | self.assertEqual( | |
@@ -240,9 +248,8 b' class TestContentsManager(TestCase):' | |||||
240 | # Test in sub-directory |
|
248 | # Test in sub-directory | |
241 | # Create a directory and notebook in that directory |
|
249 | # Create a directory and notebook in that directory | |
242 | sub_dir = '/foo/' |
|
250 | sub_dir = '/foo/' | |
243 |
self.make_dir( |
|
251 | self.make_dir('foo') | |
244 | model = cm.new_untitled(path=sub_dir, type='notebook') |
|
252 | model = cm.new_untitled(path=sub_dir, type='notebook') | |
245 | name = model['name'] |
|
|||
246 | path = model['path'] |
|
253 | path = model['path'] | |
247 |
|
254 | |||
248 | # Change the name in the model for rename |
|
255 | # Change the name in the model for rename | |
@@ -279,7 +286,7 b' class TestContentsManager(TestCase):' | |||||
279 | # Test in sub-directory |
|
286 | # Test in sub-directory | |
280 | # Create a directory and notebook in that directory |
|
287 | # Create a directory and notebook in that directory | |
281 | sub_dir = '/foo/' |
|
288 | sub_dir = '/foo/' | |
282 |
self.make_dir( |
|
289 | self.make_dir('foo') | |
283 | model = cm.new_untitled(path=sub_dir, type='notebook') |
|
290 | model = cm.new_untitled(path=sub_dir, type='notebook') | |
284 | name = model['name'] |
|
291 | name = model['name'] | |
285 | path = model['path'] |
|
292 | path = model['path'] | |
@@ -309,7 +316,7 b' class TestContentsManager(TestCase):' | |||||
309 | parent = u'å b' |
|
316 | parent = u'å b' | |
310 | name = u'nb √.ipynb' |
|
317 | name = u'nb √.ipynb' | |
311 | path = u'{0}/{1}'.format(parent, name) |
|
318 | path = u'{0}/{1}'.format(parent, name) | |
312 | os.mkdir(os.path.join(cm.root_dir, parent)) |
|
319 | self.make_dir(parent) | |
313 | orig = cm.new(path=path) |
|
320 | orig = cm.new(path=path) | |
314 |
|
321 | |||
315 | # copy with unspecified name |
|
322 | # copy with unspecified name |
@@ -30,6 +30,7 b' class NotebookTestBase(TestCase):' | |||||
30 | """ |
|
30 | """ | |
31 |
|
31 | |||
32 | port = 12341 |
|
32 | port = 12341 | |
|
33 | config = None | |||
33 |
|
34 | |||
34 | @classmethod |
|
35 | @classmethod | |
35 | def wait_until_alive(cls): |
|
36 | def wait_until_alive(cls): | |
@@ -65,6 +66,7 b' class NotebookTestBase(TestCase):' | |||||
65 | open_browser=False, |
|
66 | open_browser=False, | |
66 | ipython_dir=cls.ipython_dir.name, |
|
67 | ipython_dir=cls.ipython_dir.name, | |
67 | notebook_dir=cls.notebook_dir.name, |
|
68 | notebook_dir=cls.notebook_dir.name, | |
|
69 | config=cls.config, | |||
68 | ) |
|
70 | ) | |
69 |
|
71 | |||
70 | # clear log handlers and propagate to root for nose to capture it |
|
72 | # clear log handlers and propagate to root for nose to capture it |
General Comments 0
You need to be logged in to leave comments.
Login now