Skip to content

Commit 59439e9

Browse files
authored
Add tests for common types (#11)
This PR adds tests for common types to ensure that they are being encoded
1 parent 390b356 commit 59439e9

File tree

1 file changed

+133
-16
lines changed

1 file changed

+133
-16
lines changed

tests/test_formatters.py

Lines changed: 133 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66
## Standard Library
77
from dataclasses import dataclass
88
import datetime
9+
import enum
910
import io
1011
import json
1112
import logging
1213
import sys
1314
import traceback
15+
from types import TracebackType
1416
from typing import Any, Generator
17+
import uuid
1518

1619
## Installed
1720
from freezegun import freeze_time
@@ -81,6 +84,34 @@ def get_traceback_from_exception_followed_by_log_call(env_: LoggingEnvironment)
8184
return str_traceback
8285

8386

87+
class SomeClass:
88+
def __init__(self, thing: int):
89+
self.thing = thing
90+
return
91+
92+
93+
@dataclass
94+
class SomeDataclass:
95+
things: str
96+
stuff: int
97+
junk: bool
98+
99+
100+
try:
101+
raise ValueError
102+
except ValueError as e:
103+
STATIC_TRACEBACK = e.__traceback__
104+
del e
105+
106+
107+
class MultiEnum(enum.Enum):
108+
NONE = None
109+
BOOL = False
110+
STR = "somestring"
111+
INT = 99
112+
BYTES = b"somebytes"
113+
114+
84115
### TESTS
85116
### ============================================================================
86117
def test_merge_record_extra():
@@ -344,13 +375,114 @@ def test_default_encoder_with_timestamp(env: LoggingEnvironment, class_: type[Ba
344375
env.set_formatter(class_(timestamp=True))
345376

346377
env.logger.info("Hello")
347-
print(env.buffer.getvalue())
348378
log_json = env.load_json()
349379

350380
assert log_json["timestamp"] == "2017-07-14T02:40:00+00:00"
351381
return
352382

353383

384+
@pytest.mark.parametrize("class_", ALL_FORMATTERS)
385+
@pytest.mark.parametrize(
386+
["obj", "type_"],
387+
[
388+
("somestring", str),
389+
(1234, int),
390+
(1234.5, float),
391+
(False, bool),
392+
(None, type(None)),
393+
(b"somebytes", str),
394+
(datetime.time(16, 45, 30, 100), str),
395+
(datetime.date.today(), str),
396+
(datetime.datetime.utcnow(), str),
397+
(uuid.uuid4(), str),
398+
(Exception, str),
399+
(Exception("Foo occurred"), str),
400+
(BaseException, str),
401+
(BaseException("BaseFoo occurred"), str),
402+
(STATIC_TRACEBACK, str),
403+
(SomeDataclass(things="le_things", stuff=99, junk=False), dict),
404+
(SomeDataclass, str),
405+
(SomeClass, str),
406+
(SomeClass(1234), str),
407+
(MultiEnum.NONE, type(None)),
408+
(MultiEnum.BOOL, bool),
409+
(MultiEnum.STR, str),
410+
(MultiEnum.INT, int),
411+
(MultiEnum.BYTES, str),
412+
(MultiEnum, str),
413+
],
414+
)
415+
def test_common_types_encoded(
416+
env: LoggingEnvironment, class_: type[BaseJsonFormatter], obj: object, type_: type
417+
):
418+
## Known bad cases
419+
if class_ is JsonFormatter:
420+
if obj is SomeDataclass or isinstance(obj, SomeDataclass) or isinstance(obj, enum.Enum):
421+
pytest.xfail()
422+
423+
if pythonjsonlogger.ORJSON_AVAILABLE and class_ is OrjsonFormatter:
424+
if (
425+
obj is Exception
426+
or obj is BaseException
427+
or isinstance(obj, BaseException)
428+
or obj is SomeDataclass
429+
or obj is SomeClass
430+
or isinstance(obj, SomeClass)
431+
or isinstance(obj, bytes)
432+
or isinstance(obj, TracebackType)
433+
or isinstance(obj, enum.EnumMeta)
434+
or obj is MultiEnum.BYTES
435+
):
436+
pytest.xfail()
437+
438+
if pythonjsonlogger.MSGSPEC_AVAILABLE and class_ is MsgspecFormatter:
439+
if (
440+
obj is Exception
441+
or obj is BaseException
442+
or isinstance(obj, BaseException)
443+
or obj is SomeDataclass
444+
or obj is SomeClass
445+
or isinstance(obj, SomeClass)
446+
or isinstance(obj, TracebackType)
447+
or isinstance(obj, enum.EnumMeta)
448+
or (
449+
isinstance(obj, enum.Enum)
450+
and obj in {MultiEnum.BYTES, MultiEnum.NONE, MultiEnum.BOOL}
451+
)
452+
):
453+
pytest.xfail()
454+
455+
## Test
456+
env.set_formatter(class_())
457+
extra = {
458+
"extra": obj,
459+
"extra_dict": {"item": obj},
460+
"extra_list": [obj],
461+
}
462+
env.logger.info("hello", extra=extra)
463+
log_json = env.load_json()
464+
465+
assert isinstance(log_json["extra"], type_)
466+
assert isinstance(log_json["extra_dict"]["item"], type_)
467+
assert isinstance(log_json["extra_list"][0], type_)
468+
return
469+
470+
471+
@pytest.mark.parametrize("class_", ALL_FORMATTERS)
472+
def test_custom_default(env: LoggingEnvironment, class_: type[BaseJsonFormatter]):
473+
def custom_default(obj):
474+
if isinstance(obj, SomeClass):
475+
return {"TYPE": obj.thing}
476+
return None
477+
478+
env.set_formatter(class_(json_default=custom_default)) # type: ignore[call-arg]
479+
env.logger.info("hello", extra={"extra": SomeClass(999)})
480+
log_json = env.load_json()
481+
482+
assert log_json["extra"] == {"TYPE": 999}
483+
return
484+
485+
354486
## JsonFormatter Specific
355487
## -----------------------------------------------------------------------------
356488
def test_json_default_encoder(env: LoggingEnvironment):
@@ -372,21 +504,6 @@ def test_json_default_encoder(env: LoggingEnvironment):
372504
return
373505

374506

375-
def test_json_custom_default(env: LoggingEnvironment):
376-
def custom(o):
377-
return "very custom"
378-
379-
env.set_formatter(JsonFormatter(json_default=custom))
380-
381-
msg = {"adate": datetime.datetime(1999, 12, 31, 23, 59), "normal": "value"}
382-
env.logger.info(msg)
383-
log_json = env.load_json()
384-
385-
assert log_json["adate"] == "very custom"
386-
assert log_json["normal"] == "value"
387-
return
388-
389-
390507
def test_json_ensure_ascii_true(env: LoggingEnvironment):
391508
env.set_formatter(JsonFormatter())
392509
env.logger.info("Привет")

0 commit comments

Comments
 (0)