JSON encoder change via app (#2055)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
from pytest import raises
|
||||
|
||||
from sanic.app import Sanic
|
||||
from sanic.blueprints import Blueprint
|
||||
from sanic.blueprint_group import BlueprintGroup
|
||||
from sanic.blueprints import Blueprint
|
||||
from sanic.request import Request
|
||||
from sanic.response import HTTPResponse, text
|
||||
|
||||
|
||||
92
tests/test_json_encoding.py
Normal file
92
tests/test_json_encoding.py
Normal file
@@ -0,0 +1,92 @@
|
||||
import sys
|
||||
|
||||
from dataclasses import asdict, dataclass
|
||||
from functools import partial
|
||||
from json import dumps as sdumps
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
try:
|
||||
from ujson import dumps as udumps
|
||||
|
||||
NO_UJSON = False
|
||||
DEFAULT_DUMPS = udumps
|
||||
except ModuleNotFoundError:
|
||||
NO_UJSON = True
|
||||
DEFAULT_DUMPS = partial(sdumps, separators=(",", ":"))
|
||||
|
||||
from sanic import Sanic
|
||||
from sanic.response import BaseHTTPResponse, json
|
||||
|
||||
|
||||
@dataclass
|
||||
class Foo:
|
||||
bar: str
|
||||
|
||||
def __json__(self):
|
||||
return udumps(asdict(self))
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def foo():
|
||||
return Foo(bar="bar")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def payload(foo):
|
||||
return {"foo": foo}
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def default_back_to_ujson():
|
||||
yield
|
||||
BaseHTTPResponse._dumps = DEFAULT_DUMPS
|
||||
|
||||
|
||||
def test_change_encoder():
|
||||
Sanic("...", dumps=sdumps)
|
||||
assert BaseHTTPResponse._dumps == sdumps
|
||||
|
||||
|
||||
def test_change_encoder_to_some_custom():
|
||||
def my_custom_encoder():
|
||||
return "foo"
|
||||
|
||||
Sanic("...", dumps=my_custom_encoder)
|
||||
assert BaseHTTPResponse._dumps == my_custom_encoder
|
||||
|
||||
|
||||
@pytest.mark.skipif(NO_UJSON is True, reason="ujson not installed")
|
||||
def test_json_response_ujson(payload):
|
||||
"""ujson will look at __json__"""
|
||||
response = json(payload)
|
||||
assert response.body == b'{"foo":{"bar":"bar"}}'
|
||||
|
||||
with pytest.raises(
|
||||
TypeError, match="Object of type Foo is not JSON serializable"
|
||||
):
|
||||
json(payload, dumps=sdumps)
|
||||
|
||||
Sanic("...", dumps=sdumps)
|
||||
with pytest.raises(
|
||||
TypeError, match="Object of type Foo is not JSON serializable"
|
||||
):
|
||||
json(payload)
|
||||
|
||||
|
||||
@pytest.mark.skipif(NO_UJSON is True, reason="ujson not installed")
|
||||
def test_json_response_json():
|
||||
"""One of the easiest ways to tell the difference is that ujson cannot
|
||||
serialize over 64 bits"""
|
||||
too_big_for_ujson = 111111111111111111111
|
||||
|
||||
with pytest.raises(OverflowError, match="int too big to convert"):
|
||||
json(too_big_for_ujson)
|
||||
|
||||
response = json(too_big_for_ujson, dumps=sdumps)
|
||||
assert sys.getsizeof(response.body) == 54
|
||||
|
||||
Sanic("...", dumps=sdumps)
|
||||
response = json(too_big_for_ujson)
|
||||
assert sys.getsizeof(response.body) == 54
|
||||
Reference in New Issue
Block a user