##// END OF EJS Templates
further adapter tests, and associated fixes
MinRK -
Show More
@@ -54,6 +54,9 b' class Adapter(object):'
54 handler = getattr(self, header['msg_type'], None)
54 handler = getattr(self, header['msg_type'], None)
55 if handler is None:
55 if handler is None:
56 return msg
56 return msg
57 # no transform for status=error
58 if msg['content'].get('status', None) in {'error', 'aborted'}:
59 return msg
57 return handler(msg)
60 return handler(msg)
58
61
59 def _version_str_to_list(version):
62 def _version_str_to_list(version):
@@ -62,7 +65,7 b' def _version_str_to_list(version):'
62 non-int segments are excluded
65 non-int segments are excluded
63 """
66 """
64 v = []
67 v = []
65 for part in content[key].split('.'):
68 for part in version.split('.'):
66 try:
69 try:
67 v.append(int(part))
70 v.append(int(part))
68 except ValueError:
71 except ValueError:
@@ -121,7 +124,7 b' class V5toV4(Adapter):'
121 new_content = msg['content'] = {}
124 new_content = msg['content'] = {}
122 new_content['text'] = ''
125 new_content['text'] = ''
123 new_content['line'] = line
126 new_content['line'] = line
124 new_content['blob'] = None
127 new_content['block'] = None
125 new_content['cursor_pos'] = cursor_pos
128 new_content['cursor_pos'] = cursor_pos
126 return msg
129 return msg
127
130
@@ -138,10 +141,10 b' class V5toV4(Adapter):'
138 content = msg['content']
141 content = msg['content']
139 code = content['code']
142 code = content['code']
140 cursor_pos = content['cursor_pos']
143 cursor_pos = content['cursor_pos']
141 line, cursor_pos = code_to_line(code, cursor_pos)
144 line, _ = code_to_line(code, cursor_pos)
142
145
143 new_content = msg['content'] = {}
146 new_content = msg['content'] = {'status' : 'ok'}
144 new_content['name'] = token_at_cursor(code, cursor_pos)
147 new_content['oname'] = token_at_cursor(code, cursor_pos)
145 new_content['detail_level'] = content['detail_level']
148 new_content['detail_level'] = content['detail_level']
146 return msg
149 return msg
147
150
@@ -155,6 +158,13 b' class V5toV4(Adapter):'
155 def display_data(self, msg):
158 def display_data(self, msg):
156 content = msg['content']
159 content = msg['content']
157 content.setdefault("source", "display")
160 content.setdefault("source", "display")
161 data = content['data']
162 if 'application/json' in data:
163 try:
164 data['application/json'] = json.dumps(data['application/json'])
165 except Exception:
166 # warn?
167 pass
158 return msg
168 return msg
159
169
160 # stdin channel
170 # stdin channel
@@ -219,25 +229,45 b' class V4toV5(Adapter):'
219 def complete_reply(self, msg):
229 def complete_reply(self, msg):
220 # TODO: complete_reply needs more context than we have
230 # TODO: complete_reply needs more context than we have
221 # Maybe strip common prefix and give magic cursor_start = cursor_end = 0?
231 # Maybe strip common prefix and give magic cursor_start = cursor_end = 0?
222 content = msg['content'] = {}
232 content = msg['content']
223 content['matches'] = []
233 new_content = msg['content'] = {'status' : 'ok'}
224 content['cursor_start'] = content['cursor_end'] = 0
234 n = len(content['matched_text'])
225 content['metadata'] = {}
235 new_content['matches'] = [ m[n:] for m in content['matches'] ]
236 new_content['cursor_start'] = new_content['cursor_end'] = 0
237 new_content['metadata'] = {}
226 return msg
238 return msg
227
239
228 def inspect_request(self, msg):
240 def inspect_request(self, msg):
229 content = msg['content']
241 content = msg['content']
230 name = content['name']
242 name = content['oname']
231
243
232 new_content = msg['content'] = {}
244 new_content = msg['content'] = {}
233 new_content['code'] = name
245 new_content['code'] = name
234 new_content['cursor_pos'] = len(name) - 1
246 new_content['cursor_pos'] = len(name)
235 new_content['detail_level'] = content['detail_level']
247 new_content['detail_level'] = content['detail_level']
236 return msg
248 return msg
237
249
238 def inspect_reply(self, msg):
250 def inspect_reply(self, msg):
239 """inspect_reply can't be easily backward compatible"""
251 """inspect_reply can't be easily backward compatible"""
240 msg['content'] = {'found' : False, 'name' : 'unknown'}
252 content = msg['content']
253 new_content = msg['content'] = {'status' : 'ok'}
254 found = new_content['found'] = content['found']
255 new_content['name'] = content['name']
256 new_content['data'] = data = {}
257 new_content['metadata'] = {}
258 if found:
259 lines = []
260 for key in ('call_def', 'init_definition', 'definition'):
261 if content.get(key, False):
262 lines.append(content[key])
263 break
264 for key in ('call_docstring', 'init_docstring', 'docstring'):
265 if content.get(key, False):
266 lines.append(content[key])
267 break
268 if not lines:
269 lines.append("<empty docstring>")
270 data['text/plain'] = '\n'.join(lines)
241 return msg
271 return msg
242
272
243 # iopub channel
273 # iopub channel
@@ -247,7 +277,11 b' class V4toV5(Adapter):'
247 content.pop("source", None)
277 content.pop("source", None)
248 data = content['data']
278 data = content['data']
249 if 'application/json' in data:
279 if 'application/json' in data:
250 data['application/json'] = json.dumps(data['application/json'])
280 try:
281 data['application/json'] = json.loads(data['application/json'])
282 except Exception:
283 # warn?
284 pass
251 return msg
285 return msg
252
286
253 # stdin channel
287 # stdin channel
@@ -4,7 +4,7 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import copy
6 import copy
7
7 import json
8 from unittest import TestCase
8 from unittest import TestCase
9 import nose.tools as nt
9 import nose.tools as nt
10
10
@@ -18,13 +18,12 b' def test_default_version():'
18 msg['header'].pop('version')
18 msg['header'].pop('version')
19 original = copy.deepcopy(msg)
19 original = copy.deepcopy(msg)
20 adapted = adapt(original)
20 adapted = adapt(original)
21 nt.assert_equal(adapted['header'].version, V4toV5.version)
21 nt.assert_equal(adapted['header']['version'], V4toV5.version)
22
22
23
23
24 class AdapterTest(TestCase):
24 class AdapterTest(TestCase):
25
25
26 def setUp(self):
26 def setUp(self):
27 print("hi")
28 self.session = Session()
27 self.session = Session()
29
28
30 def adapt(self, msg, version=None):
29 def adapt(self, msg, version=None):
@@ -85,25 +84,90 b' class V4toV5TestCase(AdapterTest):'
85 v4c = v4['content']
84 v4c = v4['content']
86 v5c = v5['content']
85 v5c = v5['content']
87 self.assertEqual(v5c['user_expressions'], {'a' : 'apple', 'b': 'b'})
86 self.assertEqual(v5c['user_expressions'], {'a' : 'apple', 'b': 'b'})
88 nt.assert_not_in('user_variables', v5c)
87 self.assertNotIn('user_variables', v5c)
89 self.assertEqual(v5c['code'], v4c['code'])
88 self.assertEqual(v5c['code'], v4c['code'])
90
89
91 def test_complete_request(self):
90 def test_complete_request(self):
92 pass
91 msg = self.msg("complete_request", {
92 'text' : 'a.is',
93 'line' : 'foo = a.is',
94 'block' : None,
95 'cursor_pos' : 10,
96 })
97 v4, v5 = self.adapt(msg)
98 v4c = v4['content']
99 v5c = v5['content']
100 for key in ('text', 'line', 'block'):
101 self.assertNotIn(key, v5c)
102 self.assertEqual(v5c['cursor_pos'], v4c['cursor_pos'])
103 self.assertEqual(v5c['code'], v4c['line'])
93
104
94 def test_complete_reply(self):
105 def test_complete_reply(self):
95 pass
106 msg = self.msg("complete_reply", {
107 'matched_text' : 'a.is',
108 'matches' : ['a.isalnum',
109 'a.isalpha',
110 'a.isdigit',
111 'a.islower',
112 ],
113 })
114 v4, v5 = self.adapt(msg)
115 v4c = v4['content']
116 v5c = v5['content']
117 n = len(v4c['matched_text'])
118 expected_matches = [ m[n:] for m in v4c['matches'] ]
119
120 self.assertEqual(v5c['matches'], expected_matches)
121 self.assertEqual(v5c['metadata'], {})
122 self.assertEqual(v5c['cursor_start'], 0)
123 self.assertEqual(v5c['cursor_end'], 0)
96
124
97 def test_object_info_request(self):
125 def test_object_info_request(self):
98 pass
126 msg = self.msg("object_info_request", {
127 'oname' : 'foo',
128 'detail_level' : 1,
129 })
130 v4, v5 = self.adapt(msg)
131 self.assertEqual(v5['header']['msg_type'], 'inspect_request')
132 v4c = v4['content']
133 v5c = v5['content']
134 self.assertEqual(v5c['code'], v4c['oname'])
135 self.assertEqual(v5c['cursor_pos'], len(v4c['oname']))
136 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
99
137
100 def test_object_info_reply(self):
138 def test_object_info_reply(self):
101 pass
139 msg = self.msg("object_info_reply", {
140 'name' : 'foo',
141 'found' : True,
142 'status' : 'ok',
143 'definition' : 'foo(a=5)',
144 'docstring' : "the docstring",
145 })
146 v4, v5 = self.adapt(msg)
147 self.assertEqual(v5['header']['msg_type'], 'inspect_reply')
148 v4c = v4['content']
149 v5c = v5['content']
150 self.assertEqual(sorted(v5c), [ 'data', 'found', 'metadata', 'name', 'status'])
151 text = v5c['data']['text/plain']
152 self.assertEqual(text, '\n'.join([v4c['definition'], v4c['docstring']]))
102
153
103 # iopub channel
154 # iopub channel
104
155
105 def test_display_data(self):
156 def test_display_data(self):
106 pass
157 jsondata = dict(a=5)
158 msg = self.msg("display_data", {
159 'data' : {
160 'text/plain' : 'some text',
161 'application/json' : json.dumps(jsondata)
162 },
163 'metadata' : {'text/plain' : { 'key' : 'value' }},
164 })
165 v4, v5 = self.adapt(msg)
166 v4c = v4['content']
167 v5c = v5['content']
168 self.assertEqual(v5c['metadata'], v4c['metadata'])
169 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
170 self.assertEqual(v5c['data']['application/json'], jsondata)
107
171
108 # stdin channel
172 # stdin channel
109
173
@@ -162,21 +226,84 b' class V5toV4TestCase(AdapterTest):'
162 self.assertEqual(v5c['code'], v4c['code'])
226 self.assertEqual(v5c['code'], v4c['code'])
163
227
164 def test_complete_request(self):
228 def test_complete_request(self):
165 pass
229 msg = self.msg("complete_request", {
230 'code' : 'def foo():\n'
231 ' a.is\n'
232 'foo()',
233 'cursor_pos': 19,
234 })
235 v5, v4 = self.adapt(msg)
236 v4c = v4['content']
237 v5c = v5['content']
238 self.assertNotIn('code', v4c)
239 self.assertEqual(v4c['line'], v5c['code'].splitlines(True)[1])
240 self.assertEqual(v4c['cursor_pos'], 8)
241 self.assertEqual(v4c['text'], '')
242 self.assertEqual(v4c['block'], None)
166
243
167 def test_complete_reply(self):
244 def test_complete_reply(self):
168 pass
245 msg = self.msg("complete_reply", {
246 'cursor_start' : 10,
247 'cursor_end' : 14,
248 'matches' : ['a.isalnum',
249 'a.isalpha',
250 'a.isdigit',
251 'a.islower',
252 ],
253 'metadata' : {},
254 })
255 v5, v4 = self.adapt(msg)
256 v4c = v4['content']
257 v5c = v5['content']
258 self.assertEqual(v4c['matched_text'], 'a.is')
259 self.assertEqual(v4c['matches'], v5c['matches'])
169
260
170 def test_inspect_request(self):
261 def test_inspect_request(self):
171 pass
262 msg = self.msg("inspect_request", {
263 'code' : 'def foo():\n'
264 ' apple\n'
265 'bar()',
266 'cursor_pos': 18,
267 'detail_level' : 1,
268 })
269 v5, v4 = self.adapt(msg)
270 self.assertEqual(v4['header']['msg_type'], 'object_info_request')
271 v4c = v4['content']
272 v5c = v5['content']
273 self.assertEqual(v4c['oname'], 'apple')
274 self.assertEqual(v5c['detail_level'], v4c['detail_level'])
172
275
173 def test_inspect_reply(self):
276 def test_inspect_reply(self):
174 pass
277 msg = self.msg("inspect_reply", {
278 'name' : 'foo',
279 'found' : True,
280 'data' : {'text/plain' : 'some text'},
281 'metadata' : {},
282 })
283 v5, v4 = self.adapt(msg)
284 self.assertEqual(v4['header']['msg_type'], 'object_info_reply')
285 v4c = v4['content']
286 v5c = v5['content']
287 self.assertEqual(sorted(v4c), ['found', 'name'])
288 self.assertEqual(v4c['found'], False)
175
289
176 # iopub channel
290 # iopub channel
177
291
178 def test_display_data(self):
292 def test_display_data(self):
179 pass
293 jsondata = dict(a=5)
294 msg = self.msg("display_data", {
295 'data' : {
296 'text/plain' : 'some text',
297 'application/json' : jsondata,
298 },
299 'metadata' : {'text/plain' : { 'key' : 'value' }},
300 })
301 v5, v4 = self.adapt(msg)
302 v4c = v4['content']
303 v5c = v5['content']
304 self.assertEqual(v5c['metadata'], v4c['metadata'])
305 self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
306 self.assertEqual(v4c['data']['application/json'], json.dumps(jsondata))
180
307
181 # stdin channel
308 # stdin channel
182
309
General Comments 0
You need to be logged in to leave comments. Login now