123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- """Tests for adapting Jupyter msg spec versions"""
- # Copyright (c) Jupyter Development Team.
- # Distributed under the terms of the Modified BSD License.
- import copy
- import json
- from unittest import TestCase
- from jupyter_client.adapter import adapt, V4toV5, V5toV4, code_to_line
- from jupyter_client.session import Session
- def test_default_version():
- s = Session()
- msg = s.msg("msg_type")
- msg['header'].pop('version')
- original = copy.deepcopy(msg)
- adapted = adapt(original)
- assert adapted['header']['version'] == V4toV5.version
- def test_code_to_line_no_code():
- line, pos = code_to_line("", 0)
- assert line == ""
- assert pos == 0
- class AdapterTest(TestCase):
- def setUp(self):
- self.session = Session()
- def adapt(self, msg, version=None):
- original = copy.deepcopy(msg)
- adapted = adapt(msg, version or self.to_version)
- return original, adapted
- def check_header(self, msg):
- pass
- class V4toV5TestCase(AdapterTest):
- from_version = 4
- to_version = 5
- def msg(self, msg_type, content):
- """Create a v4 msg (same as v5, minus version header)"""
- msg = self.session.msg(msg_type, content)
- msg['header'].pop('version')
- return msg
- def test_same_version(self):
- msg = self.msg("execute_result",
- content={'status' : 'ok'}
- )
- original, adapted = self.adapt(msg, self.from_version)
- self.assertEqual(original, adapted)
- def test_no_adapt(self):
- msg = self.msg("input_reply", {'value' : 'some text'})
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['header']['version'], V4toV5.version)
- v5['header'].pop('version')
- self.assertEqual(v4, v5)
- def test_rename_type(self):
- for v5_type, v4_type in [
- ('execute_result', 'pyout'),
- ('execute_input', 'pyin'),
- ('error', 'pyerr'),
- ]:
- msg = self.msg(v4_type, {'key' : 'value'})
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['header']['version'], V4toV5.version)
- self.assertEqual(v5['header']['msg_type'], v5_type)
- self.assertEqual(v4['content'], v5['content'])
- def test_execute_request(self):
- msg = self.msg("execute_request", {
- 'code' : 'a=5',
- 'silent' : False,
- 'user_expressions' : {'a' : 'apple'},
- 'user_variables' : ['b'],
- })
- v4, v5 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], v5['header']['msg_type'])
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c['user_expressions'], {'a' : 'apple', 'b': 'b'})
- self.assertNotIn('user_variables', v5c)
- self.assertEqual(v5c['code'], v4c['code'])
- def test_execute_reply(self):
- msg = self.msg("execute_reply", {
- 'status': 'ok',
- 'execution_count': 7,
- 'user_variables': {'a': 1},
- 'user_expressions': {'a+a': 2},
- 'payload': [{'source':'page', 'text':'blah'}]
- })
- v4, v5 = self.adapt(msg)
- v5c = v5['content']
- self.assertNotIn('user_variables', v5c)
- self.assertEqual(v5c['user_expressions'], {'a': 1, 'a+a': 2})
- self.assertEqual(v5c['payload'], [{'source': 'page',
- 'data': {'text/plain': 'blah'}}
- ])
- def test_complete_request(self):
- msg = self.msg("complete_request", {
- 'text' : 'a.is',
- 'line' : 'foo = a.is',
- 'block' : None,
- 'cursor_pos' : 10,
- })
- v4, v5 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- for key in ('text', 'line', 'block'):
- self.assertNotIn(key, v5c)
- self.assertEqual(v5c['cursor_pos'], v4c['cursor_pos'])
- self.assertEqual(v5c['code'], v4c['line'])
- def test_complete_reply(self):
- msg = self.msg("complete_reply", {
- 'matched_text' : 'a.is',
- 'matches' : ['a.isalnum',
- 'a.isalpha',
- 'a.isdigit',
- 'a.islower',
- ],
- })
- v4, v5 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c['matches'], v4c['matches'])
- self.assertEqual(v5c['metadata'], {})
- self.assertEqual(v5c['cursor_start'], -4)
- self.assertEqual(v5c['cursor_end'], None)
- def test_object_info_request(self):
- msg = self.msg("object_info_request", {
- 'oname' : 'foo',
- 'detail_level' : 1,
- })
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['header']['msg_type'], 'inspect_request')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c['code'], v4c['oname'])
- self.assertEqual(v5c['cursor_pos'], len(v4c['oname']))
- self.assertEqual(v5c['detail_level'], v4c['detail_level'])
- def test_object_info_reply(self):
- msg = self.msg("object_info_reply", {
- 'name' : 'foo',
- 'found' : True,
- 'status' : 'ok',
- 'definition' : 'foo(a=5)',
- 'docstring' : "the docstring",
- })
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['header']['msg_type'], 'inspect_reply')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(sorted(v5c), [ 'data', 'found', 'metadata', 'status'])
- text = v5c['data']['text/plain']
- self.assertEqual(text, '\n'.join([v4c['definition'], v4c['docstring']]))
- def test_object_info_reply_not_found(self):
- msg = self.msg("object_info_reply", {
- 'name' : 'foo',
- 'found' : False,
- })
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['header']['msg_type'], 'inspect_reply')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c, {
- 'status': 'ok',
- 'found': False,
- 'data': {},
- 'metadata': {},
- })
- def test_kernel_info_reply(self):
- msg = self.msg("kernel_info_reply", {
- 'language': 'python',
- 'language_version': [2,8,0],
- 'ipython_version': [1,2,3],
- })
- v4, v5 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c, {
- 'protocol_version': '4.1',
- 'implementation': 'ipython',
- 'implementation_version': '1.2.3',
- 'language_info': {
- 'name': 'python',
- 'version': '2.8.0',
- },
- 'banner' : '',
- })
- # iopub channel
- def test_display_data(self):
- jsondata = dict(a=5)
- msg = self.msg("display_data", {
- 'data' : {
- 'text/plain' : 'some text',
- 'application/json' : json.dumps(jsondata)
- },
- 'metadata' : {'text/plain' : { 'key' : 'value' }},
- })
- v4, v5 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c['metadata'], v4c['metadata'])
- self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
- self.assertEqual(v5c['data']['application/json'], jsondata)
- # stdin channel
- def test_input_request(self):
- msg = self.msg('input_request', {'prompt': "$>"})
- v4, v5 = self.adapt(msg)
- self.assertEqual(v5['content']['prompt'], v4['content']['prompt'])
- self.assertFalse(v5['content']['password'])
- class V5toV4TestCase(AdapterTest):
- from_version = 5
- to_version = 4
- def msg(self, msg_type, content):
- return self.session.msg(msg_type, content)
- def test_same_version(self):
- msg = self.msg("execute_result",
- content={'status' : 'ok'}
- )
- original, adapted = self.adapt(msg, self.from_version)
- self.assertEqual(original, adapted)
- def test_no_adapt(self):
- msg = self.msg("input_reply", {'value' : 'some text'})
- v5, v4 = self.adapt(msg)
- self.assertNotIn('version', v4['header'])
- v5['header'].pop('version')
- self.assertEqual(v4, v5)
- def test_rename_type(self):
- for v5_type, v4_type in [
- ('execute_result', 'pyout'),
- ('execute_input', 'pyin'),
- ('error', 'pyerr'),
- ]:
- msg = self.msg(v5_type, {'key' : 'value'})
- v5, v4 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], v4_type)
- assert 'version' not in v4['header']
- self.assertEqual(v4['content'], v5['content'])
- def test_execute_request(self):
- msg = self.msg("execute_request", {
- 'code' : 'a=5',
- 'silent' : False,
- 'user_expressions' : {'a' : 'apple'},
- })
- v5, v4 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], v5['header']['msg_type'])
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v4c['user_variables'], [])
- self.assertEqual(v5c['code'], v4c['code'])
- def test_complete_request(self):
- msg = self.msg("complete_request", {
- 'code' : 'def foo():\n'
- ' a.is\n'
- 'foo()',
- 'cursor_pos': 19,
- })
- v5, v4 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertNotIn('code', v4c)
- self.assertEqual(v4c['line'], v5c['code'].splitlines(True)[1])
- self.assertEqual(v4c['cursor_pos'], 8)
- self.assertEqual(v4c['text'], '')
- self.assertEqual(v4c['block'], None)
- def test_complete_reply(self):
- msg = self.msg("complete_reply", {
- 'cursor_start' : 10,
- 'cursor_end' : 14,
- 'matches' : ['a.isalnum',
- 'a.isalpha',
- 'a.isdigit',
- 'a.islower',
- ],
- 'metadata' : {},
- })
- v5, v4 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v4c['matched_text'], 'a.is')
- self.assertEqual(v4c['matches'], v5c['matches'])
- def test_inspect_request(self):
- msg = self.msg("inspect_request", {
- 'code' : 'def foo():\n'
- ' apple\n'
- 'bar()',
- 'cursor_pos': 18,
- 'detail_level' : 1,
- })
- v5, v4 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], 'object_info_request')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v4c['oname'], 'apple')
- self.assertEqual(v5c['detail_level'], v4c['detail_level'])
- def test_inspect_request_token(self):
- line = 'something(range(10), kwarg=smth) ; xxx.xxx.xxx( firstarg, rand(234,23), kwarg1=2,'
- msg = self.msg("inspect_request", {
- 'code' : line,
- 'cursor_pos': len(line)-1,
- 'detail_level' : 1,
- })
- v5, v4 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], 'object_info_request')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v4c['oname'], 'xxx.xxx.xxx')
- self.assertEqual(v5c['detail_level'], v4c['detail_level'])
- def test_inspect_reply(self):
- msg = self.msg("inspect_reply", {
- 'name' : 'foo',
- 'found' : True,
- 'data' : {'text/plain' : 'some text'},
- 'metadata' : {},
- })
- v5, v4 = self.adapt(msg)
- self.assertEqual(v4['header']['msg_type'], 'object_info_reply')
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(sorted(v4c), ['found', 'oname'])
- self.assertEqual(v4c['found'], False)
- def test_kernel_info_reply(self):
- msg = self.msg("kernel_info_reply", {
- 'protocol_version': '5.0',
- 'implementation': 'ipython',
- 'implementation_version': '1.2.3',
- 'language_info': {
- 'name': 'python',
- 'version': '2.8.0',
- 'mimetype': 'text/x-python',
- },
- 'banner' : 'the banner',
- })
- v5, v4 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- info = v5c['language_info']
- self.assertEqual(v4c, {
- 'protocol_version': [5,0],
- 'language': 'python',
- 'language_version': [2,8,0],
- 'ipython_version': [1,2,3],
- })
- # iopub channel
- def test_display_data(self):
- jsondata = dict(a=5)
- msg = self.msg("display_data", {
- 'data' : {
- 'text/plain' : 'some text',
- 'application/json' : jsondata,
- },
- 'metadata' : {'text/plain' : { 'key' : 'value' }},
- })
- v5, v4 = self.adapt(msg)
- v4c = v4['content']
- v5c = v5['content']
- self.assertEqual(v5c['metadata'], v4c['metadata'])
- self.assertEqual(v5c['data']['text/plain'], v4c['data']['text/plain'])
- self.assertEqual(v4c['data']['application/json'], json.dumps(jsondata))
- # stdin channel
- def test_input_request(self):
- msg = self.msg('input_request', {'prompt': "$>", 'password' : True})
- v5, v4 = self.adapt(msg)
- self.assertEqual(v5['content']['prompt'], v4['content']['prompt'])
- self.assertNotIn('password', v4['content'])
|