1
0

Initial public releases

* `bthlabs-jsonrpc-aiohttp` v1.0.0
* `bthlabs-jsonrpc-core` v1.0.0
* `bthlabs-jsonrpc-django` v1.0.0
This commit is contained in:
2022-06-04 10:41:53 +02:00
commit c75ea4ea9d
111 changed files with 7193 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from unittest import mock
import pytest
from bthlabs_jsonrpc_core.registry import MethodRegistry
from bthlabs_jsonrpc_core.serializer import JSONRPCSerializer
@pytest.fixture
def fake_method_registry():
return mock.Mock(spec=MethodRegistry)
@pytest.fixture
def fake_handler():
return mock.Mock()
@pytest.fixture
def fake_rpc_serializer():
return mock.Mock(spec=JSONRPCSerializer)

View File

@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
from unittest import mock
from bthlabs_jsonrpc_core import decorators
from bthlabs_jsonrpc_core.registry import MethodRegistry
@mock.patch.object(decorators.MethodRegistry, 'shared_registry')
def test_default_namespace(mock_shared_registry,
fake_method_registry,
fake_handler):
# Given
mock_shared_registry.return_value = fake_method_registry
decorator = decorators.register_method('test')
# When
result = decorator(fake_handler)
# Then
assert result is fake_handler
assert result.jsonrpc_method == 'test'
assert result.jsonrpc_namespace == MethodRegistry.DEFAULT_NAMESPACE
assert mock_shared_registry.called is True
fake_method_registry.register_method.assert_called_with(
MethodRegistry.DEFAULT_NAMESPACE, 'test', fake_handler,
)
@mock.patch.object(decorators.MethodRegistry, 'shared_registry')
def test_custom_namespace(mock_shared_registry,
fake_method_registry,
fake_handler):
# Given
mock_shared_registry.return_value = fake_method_registry
decorator = decorators.register_method('test', namespace='testing')
# When
result = decorator(fake_handler)
# Then
assert result is fake_handler
assert result.jsonrpc_method == 'test'
assert result.jsonrpc_namespace == 'testing'
assert mock_shared_registry.called is True
fake_method_registry.register_method.assert_called_with(
'testing', 'test', fake_handler,
)

View File

@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from bthlabs_jsonrpc_core import exceptions
def test_to_rpc():
# Given
exception = exceptions.BaseJSONRPCError(data='spam')
exception.ERROR_CODE = -32604
exception.ERROR_MESSAGE = 'Test error'
# When
result = exception.to_rpc()
# Then
assert result['code'] == exception.ERROR_CODE
assert result['message'] == exception.ERROR_MESSAGE
assert result['data'] == exception.data
def test_to_rpc_without_data():
# Given
exception = exceptions.BaseJSONRPCError()
exception.ERROR_CODE = -32604
exception.ERROR_MESSAGE = 'Test error'
# When
result = exception.to_rpc()
# Then
assert result['code'] == exception.ERROR_CODE
assert result['message'] == exception.ERROR_MESSAGE
assert 'data' not in result

View File

@@ -0,0 +1,776 @@
# -*- coding: utf-8 -*-
import json
from unittest import mock
import pytest
from bthlabs_jsonrpc_core import exceptions, executor
from bthlabs_jsonrpc_core.registry import MethodRegistry
from bthlabs_jsonrpc_core.serializer import JSONRPCSerializer
@pytest.fixture
def single_call():
return {
'jsonrpc': '2.0',
'id': 'test',
'method': 'test',
}
@pytest.fixture
def batch_calls():
return [
{
'jsonrpc': '2.0',
'id': 'test',
'method': 'test',
},
{
'jsonrpc': '2.0',
'id': 'test2',
'method': 'test',
},
]
@pytest.fixture
def jsonrpc_error():
return exceptions.BaseJSONRPCError('I HAZ FIAL')
@pytest.fixture
def execute_context():
return executor.Executor.ExecuteContext([])
def test_CallContext_invalid_context():
# When
result = executor.Executor.CallContext.invalid_context()
# Then
assert result.method is None
assert result.handler is None
assert result.args is None
assert result.kwargs is None
def test_CallContext_is_valid_method_none(fake_handler):
# When
call_context = executor.Executor.CallContext(None, fake_handler, [], {})
# Then
assert call_context.is_valid is False
def test_CallContext_is_valid_handler_none():
# When
call_context = executor.Executor.CallContext('test', None, [], {})
# Then
assert call_context.is_valid is False
def test_CallContext_is_valid_args_none(fake_handler):
# When
call_context = executor.Executor.CallContext(
'test', fake_handler, None, {},
)
# Then
assert call_context.is_valid is False
def test_CallContext_is_valid_kwargs_none(fake_handler):
# When
call_context = executor.Executor.CallContext(
'test', fake_handler, [], None,
)
# Then
assert call_context.is_valid is False
def test_CallContext_is_valid(fake_handler):
# When
call_context = executor.Executor.CallContext('test', fake_handler, [], {})
# Then
assert call_context.is_valid is True
def test_init_default_namespace():
# When
result = executor.Executor()
# Then
assert result.namespace == MethodRegistry.DEFAULT_NAMESPACE
def test_init_custom_namespace():
# When
result = executor.Executor(namespace='testing')
# Then
assert result.namespace == 'testing'
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_list_methods(mock_shared_registry, fake_method_registry):
# Given
fake_method_registry.get_methods.return_value = ['test']
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
# When
result = the_executor.list_methods()
# Then
assert result == ['system.list_methods', 'test']
assert mock_shared_registry.called is True
fake_method_registry.get_methods.assert_called_with(the_executor.namespace)
def test_get_internal_handler_list_methods():
# Given
the_executor = executor.Executor()
# When
result = the_executor.get_internal_handler('system.list_methods')
# Then
assert result == the_executor.list_methods
def test_get_internal_handler_method_not_found():
# Given
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_internal_handler('test')
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCMethodNotFoundError)
else:
assert False, 'No exception raised?'
def test_deserialize_data():
# Given
the_executor = executor.Executor()
# When
result = the_executor.deserialize_data('"spam"')
# Then
assert result == 'spam'
def test_deserialize_data_error():
# Given
the_executor = executor.Executor()
# When
try:
_ = the_executor.deserialize_data(None)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCParseError)
else:
assert False, 'No exception raised?'
def test_get_calls_batch(batch_calls):
# Given
the_executor = executor.Executor()
# When
result = the_executor.get_calls(batch_calls)
# Then
assert result == batch_calls
def test_get_calls_single(single_call):
# Given
the_executor = executor.Executor()
# When
result = the_executor.get_calls(single_call)
# Then
assert result == [single_call]
def test_get_calls_empty():
# Given
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_calls([])
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidRequestError)
else:
assert False, 'No exception raised?'
def test_get_call_spec_not_dict():
# Given
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(None)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidRequestError)
else:
assert False, 'No exception raised?'
def test_get_call_spec_wihtout_jsonrpc(single_call):
# Given
single_call.pop('jsonrpc')
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(single_call)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidRequestError)
else:
assert False, 'No exception raised?'
def test_get_call_spec_invalid_jsonrpc(single_call):
# Given
single_call['jsonrpc'] = 'test'
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(single_call)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidRequestError)
else:
assert False, 'No exception raised?'
def test_get_call_spec_wihtout_method(single_call):
# Given
single_call.pop('method')
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(single_call)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidRequestError)
else:
assert False, 'No exception raised?'
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_internal_method(mock_shared_registry,
single_call,
fake_handler):
# Given
single_call['method'] = 'system.list_methods'
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_internal_handler') as mock_get_internal_handler:
mock_get_internal_handler.return_value = fake_handler
# When
result = the_executor.get_call_spec(single_call)
# Then
assert result[0] == 'system.list_methods'
assert result[1] is fake_handler
mock_get_internal_handler.assert_called_with('system.list_methods')
assert mock_shared_registry.called is False
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_registry_method(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
# Given
fake_method_registry.get_handler.return_value = fake_handler
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_internal_handler') as mock_get_internal_handler:
# When
result = the_executor.get_call_spec(single_call)
# Then
assert result[0] == 'test'
assert result[1] is fake_handler
assert mock_get_internal_handler.called is False
fake_method_registry.get_handler.assert_called_with(
the_executor.namespace, 'test',
)
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_method_not_found(mock_shared_registry,
single_call,
fake_method_registry):
# Given
fake_method_registry.get_handler.return_value = None
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(single_call)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCMethodNotFoundError)
else:
assert False, 'No exception raised?'
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_invalid_params(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
# Given
single_call['params'] = 'spam'
fake_method_registry.get_handler.return_value = fake_handler
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
# When
try:
_ = the_executor.get_call_spec(single_call)
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCInvalidParamsError)
else:
assert False, 'No exception raised?'
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_with_args(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
# Given
single_call['params'] = ['spam']
fake_method_registry.get_handler.return_value = fake_handler
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'enrich_args') as mock_enrich_args:
mock_enrich_args.return_value = ['spam', 'eggs']
# When
result = the_executor.get_call_spec(single_call)
# Then
assert result[2] == ['spam', 'eggs']
assert result[3] == {}
mock_enrich_args.assert_called_with(['spam'])
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_get_call_spec_with_kwargs(mock_shared_registry,
single_call,
fake_method_registry,
fake_handler):
# Given
single_call['params'] = {'spam': True}
fake_method_registry.get_handler.return_value = fake_handler
mock_shared_registry.return_value = fake_method_registry
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'enrich_kwargs') as mock_enrich_kwargs:
mock_enrich_kwargs.return_value = {'spam': True, 'eggs': False}
# When
result = the_executor.get_call_spec(single_call)
# Then
assert result[2] == []
assert result[3] == {'spam': True, 'eggs': False}
mock_enrich_kwargs.assert_called_with({'spam': True})
def test_process_results(batch_calls, single_call, jsonrpc_error):
# Given
call_without_id = {**single_call}
call_without_id.pop('id')
call_results = [
(batch_calls[0], 'OK'),
(batch_calls[1], jsonrpc_error),
(call_without_id, '???'),
(call_without_id, jsonrpc_error),
]
the_executor = executor.Executor()
# When
result = the_executor.process_results(call_results)
# Then
assert isinstance(result, list)
assert len(result) == 2
first_response, second_response = result
expected_first_response = {
'jsonrpc': '2.0',
'id': batch_calls[0]['id'],
'result': 'OK',
}
assert first_response == expected_first_response
expected_second_response = {
'jsonrpc': '2.0',
'id': batch_calls[1]['id'],
'error': jsonrpc_error,
}
assert second_response == expected_second_response
def test_process_results_single_call(single_call):
# Given
call_results = [
(single_call, 'OK'),
]
the_executor = executor.Executor()
# When
result = the_executor.process_results(call_results)
# Then
expected_result = {
'jsonrpc': '2.0',
'id': single_call['id'],
'result': 'OK',
}
assert result == expected_result
def test_process_results_top_level_error(jsonrpc_error):
# Given
call_results = [
(None, jsonrpc_error),
]
the_executor = executor.Executor()
# When
result = the_executor.process_results(call_results)
# Then
expected_result = {
'jsonrpc': '2.0',
'id': None,
'error': jsonrpc_error,
}
assert result == expected_result
def test_process_results_empty(single_call):
# Given
single_call.pop('id')
call_results = [
(single_call, 'OK'),
]
the_executor = executor.Executor()
# When
result = the_executor.process_results(call_results)
# Then
assert result is None
def test_call_context_invalid_context(jsonrpc_error,
execute_context,
single_call):
# Given
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_call_spec') as mock_get_call_spec:
mock_get_call_spec.side_effect = jsonrpc_error
# When
with the_executor.call_context(execute_context, single_call) as result:
pass
# Then
assert result.is_valid is False
def test_call_context_handle_jsonrpc_error(fake_handler,
jsonrpc_error,
execute_context,
single_call):
# Given
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_call_spec') as mock_get_call_spec:
mock_get_call_spec.return_value = (
'test', fake_handler, [], {},
)
# When
with the_executor.call_context(execute_context, single_call) as _:
raise jsonrpc_error
# Then
assert len(execute_context.results) == 1
call_result = execute_context.results[0]
assert call_result[1] == jsonrpc_error
def test_call_context_handle_exception(fake_handler,
execute_context,
single_call):
# Given
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_call_spec') as mock_get_call_spec:
mock_get_call_spec.return_value = (
'test', fake_handler, [], {},
)
# When
with the_executor.call_context(execute_context, single_call) as _:
raise RuntimeError('I HAZ FIAL')
# Then
assert len(execute_context.results) == 1
call_result = execute_context.results[0]
assert isinstance(call_result[1], exceptions.JSONRPCInternalError)
assert call_result[1].data == 'I HAZ FIAL'
def test_call_context(fake_handler, execute_context, single_call):
# Given
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'get_call_spec') as mock_get_call_spec:
mock_get_call_spec.return_value = (
'test', fake_handler, [], {},
)
# When
with the_executor.call_context(execute_context, single_call) as result:
result.result = 'OK'
# Then
assert result.method == 'test'
assert result.handler is fake_handler
assert result.args == []
assert result.kwargs == {}
assert len(execute_context.results) == 1
expected_call_result = (single_call, 'OK')
assert execute_context.results[0] == expected_call_result
def test_execute_context_handle_jsonrpc_error(jsonrpc_error):
# Given
the_executor = executor.Executor()
# When
with the_executor.execute_context() as result:
raise jsonrpc_error
# Then
assert result.results == [(None, jsonrpc_error)]
def test_execute_context_handle_exception():
# Given
error = RuntimeError('I HAZ FIAL')
the_executor = executor.Executor()
# When
try:
with the_executor.execute_context() as result:
raise error
except Exception as exception:
assert exception is error
assert result.serializer is None
def test_execute_context_handle_empty_results(single_call):
# Given
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'process_results') as mock_process_results:
with mock.patch.object(the_executor, 'serializer') as mock_serializer:
mock_process_results.return_value = None
# When
with the_executor.execute_context() as result:
result.results.append((single_call, 'OK'))
# Then
assert result.serializer is None
assert mock_serializer.called is False
def test_execute_context(fake_rpc_serializer, single_call):
# Given
fake_responses = {
'jsonrpc': '2.0',
'id': 'test',
'result': 'OK',
}
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'process_results') as mock_process_results:
with mock.patch.object(the_executor, 'serializer') as mock_serializer:
mock_process_results.return_value = fake_responses
mock_serializer.return_value = fake_rpc_serializer
# When
with the_executor.execute_context() as result:
result.results.append((single_call, 'OK'))
# Then
assert result.serializer is fake_rpc_serializer
mock_process_results.assert_called_with([(single_call, 'OK')])
mock_serializer.assert_called_with(fake_responses)
def test_enrich_args():
# Given
the_executor = executor.Executor()
# When
result = the_executor.enrich_args(['spam', 'eggs'])
# Then
assert result == ['spam', 'eggs']
def test_enrich_kwargs():
# Given
the_executor = executor.Executor()
# When
result = the_executor.enrich_kwargs({'spam': True, 'eggs': False})
# Then
assert result == {'spam': True, 'eggs': False}
@pytest.mark.skip('NOOP')
def test_before_call():
pass
@mock.patch.object(executor.MethodRegistry, 'shared_registry')
def test_execute(mock_shared_registry, fake_method_registry):
# Given
fake_method_registry.get_handler.return_value = None
fake_method_registry.get_methods.return_value = []
mock_shared_registry.return_value = fake_method_registry
batch = [
{
'jsonrpc': '2.0',
'id': 'call_1',
'method': 'system.list_methods',
'params': ['spam'],
},
{
'jsonrpc': '2.0',
'id': 'call_2',
'method': 'idontexist',
},
{
'jsonrpc': '2.0',
'method': 'system.list_methods',
'params': {'spam': True},
},
]
payload = json.dumps(batch)
the_executor = executor.Executor()
with mock.patch.object(the_executor, 'before_call') as mock_before_call:
# When
result = the_executor.execute(payload)
# Then
assert isinstance(result, JSONRPCSerializer)
expected_result_data = [
{
'jsonrpc': '2.0',
'id': 'call_1',
'result': ['system.list_methods'],
},
{
'jsonrpc': '2.0',
'id': 'call_2',
'error': {
'code': exceptions.JSONRPCMethodNotFoundError.ERROR_CODE,
'message': exceptions.JSONRPCMethodNotFoundError.ERROR_MESSAGE,
},
},
]
assert result.data == expected_result_data
fake_method_registry.get_handler.assert_called_with(
'jsonrpc', 'idontexist',
)
assert mock_before_call.call_count == 2
mock_before_call.assert_any_call('system.list_methods', ['spam'], {})
mock_before_call.assert_any_call(
'system.list_methods', [], {'spam': True},
)

View File

@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-
from unittest import mock
from bthlabs_jsonrpc_core import registry
def test_init():
# When
result = registry.MethodRegistry()
# Then
assert result.registry == {'jsonrpc': {}}
@mock.patch.object(registry.MethodRegistry, '__init__')
def test_shared_registry(mock_init):
# Given
mock_init.return_value = None
# When
result = registry.MethodRegistry.shared_registry()
# Then
assert isinstance(result, registry.MethodRegistry)
assert registry.MethodRegistry.INSTANCE is result
assert mock_init.called is True
# After
registry.MethodRegistry.INSTANCE = None
@mock.patch.object(registry.MethodRegistry, '__init__')
def test_shared_registry_with_instance(mock_init, fake_method_registry):
# Given
mock_init.return_value = None
registry.MethodRegistry.INSTANCE = fake_method_registry
# When
result = registry.MethodRegistry.shared_registry()
# Then
assert result is fake_method_registry
assert registry.MethodRegistry.INSTANCE is fake_method_registry
assert mock_init.called is False
# After
registry.MethodRegistry.INSTANCE = None
def test_register_method(fake_handler):
# Given
the_registry = registry.MethodRegistry()
# When'
the_registry.register_method('testing', 'test', fake_handler)
# Then
expected_namespace = {'test': fake_handler}
assert the_registry.registry['testing'] == expected_namespace
def test_register_method_existing_namespace(fake_handler):
# Given
spam_handler = mock.Mock()
the_registry = registry.MethodRegistry()
the_registry.registry['jsonrpc']['spam'] = spam_handler
# When'
the_registry.register_method('jsonrpc', 'test', fake_handler)
# Then
expected_namespace = {'spam': spam_handler, 'test': fake_handler}
assert the_registry.registry['jsonrpc'] == expected_namespace
def test_get_methods():
# Given
the_registry = registry.MethodRegistry()
the_registry.registry['jsonrpc']['spam'] = mock.Mock()
the_registry.registry['jsonrpc']['eggs'] = mock.Mock()
# When'
result = the_registry.get_methods('jsonrpc')
# Then
expected_methods = {'spam', 'eggs'}
assert set(result) == expected_methods
def test_get_handler(fake_handler):
# Given
spam_handler = mock.Mock()
the_registry = registry.MethodRegistry()
the_registry.registry['jsonrpc']['spam'] = spam_handler
the_registry.registry['jsonrpc']['eggs'] = fake_handler
# When'
result = the_registry.get_handler('jsonrpc', 'eggs')
# Then
assert result is fake_handler

View File

@@ -0,0 +1,193 @@
# -*- coding: utf-8 -*-
import datetime
import decimal
import uuid
import pytest
from bthlabs_jsonrpc_core import exceptions, serializer
def test_init():
# When
result = serializer.JSONRPCSerializer('spam')
# Then
assert result._data == 'spam'
@pytest.mark.parametrize(
'value,expected',
[(None, True), (False, True), (0, True), ('spam', True), ([], False)],
)
def test_is_simple_value(value, expected):
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.is_simple_value(value)
# Then
assert result == expected
@pytest.mark.parametrize(
'value,expected',
[
([], True), ((x for x in [0, 1]), True), (set(), True),
(tuple(), True), ({}, False),
],
)
def test_is_sequence_value(value, expected):
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.is_sequence_value(value)
# Then
assert result == expected
@pytest.mark.parametrize(
'value,expected',
[({}, True), ([], False)],
)
def test_is_dict_value(value, expected):
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.is_dict_value(value)
# Then
assert result == expected
@pytest.mark.parametrize(
'value,expected',
[(uuid.uuid4(), True), (decimal.Decimal('42'), True), ([], False)],
)
def test_is_string_coercible_value(value, expected):
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.is_string_coercible_value(value)
# Then
assert result == expected
@pytest.mark.parametrize(
'value,expected',
[
(
datetime.datetime(1987, 10, 3, 8, 0, 0, 0, tzinfo=datetime.timezone.utc),
'1987-10-03T08:00:00+00:00',
),
(
datetime.date(1987, 10, 3),
'1987-10-03',
),
],
)
def test_serialize_datetime(value, expected):
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.serialize_datetime(value)
# Then
assert result == expected
def test_serialize_sequence():
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.serialize_sequence([(0, 1), 'spam'])
# Then
assert result == [[0, 1], 'spam']
def test_serialize_dict():
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.serialize_dict(
{'spam': True, 'eggs': {'key': decimal.Decimal('42')}},
)
# Then
assert result == {'spam': True, 'eggs': {'key': '42'}}
def test_serialize_string_coercible():
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.serialize_string_coercible(decimal.Decimal('42'))
# Then
assert result == '42'
def test_serialize_value():
# Given
value = [
serializer.JSONRPCSerializer('spam'),
'eggs',
datetime.datetime(1987, 10, 3, 8, 0, 0, 0, tzinfo=datetime.timezone.utc),
[0, 1],
{'spam': True},
decimal.Decimal('42'),
exceptions.BaseJSONRPCError(),
]
the_serializer = serializer.JSONRPCSerializer('spam')
# When
result = the_serializer.serialize_value(value)
# Then
expected = [
'spam',
'eggs',
'1987-10-03T08:00:00+00:00',
[0, 1],
{'spam': True},
'42',
exceptions.BaseJSONRPCError().to_rpc(),
]
assert result == expected
def test_serialize_value_no_to_rpc():
# Given
the_serializer = serializer.JSONRPCSerializer('spam')
# When
try:
_ = the_serializer.serialize_value(object())
except Exception as exception:
# Then
assert isinstance(exception, exceptions.JSONRPCSerializerError)
def test_data():
# Given
the_serializer = serializer.JSONRPCSerializer(decimal.Decimal('42'))
# When
result = the_serializer.data
# Then
assert result == '42'
assert the_serializer._serialized_data == '42'