From a3d473ae890a593a6cf5bb32e0fb34e8a3c2b6bd Mon Sep 17 00:00:00 2001 From: Femi Onisile Date: Sun, 7 Jun 2026 16:16:39 +0100 Subject: [PATCH 1/2] test: add unit tests for safe_json_loads --- .../test_safe_json_loads.py | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 tests/test_litellm/litellm_core_utils/test_safe_json_loads.py diff --git a/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py b/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py new file mode 100644 index 00000000000..a3e1157136e --- /dev/null +++ b/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py @@ -0,0 +1,52 @@ +""" +Unit tests for litellm.litellm_core_utils.safe_json_loads.safe_json_loads. + +safe_json_loads parses a JSON string and, on any failure, returns a default +value instead of raising. These tests cover the success path, the fallback +path, and the non-string edge case. +""" + +import pytest + +from litellm.litellm_core_utils.safe_json_loads import safe_json_loads + + +def test_parses_valid_json_object(): + assert safe_json_loads('{"a": 1, "b": [2, 3]}') == {"a": 1, "b": [2, 3]} + + +def test_parses_valid_json_array(): + assert safe_json_loads("[1, 2, 3]") == [1, 2, 3] + + +@pytest.mark.parametrize( + "raw, expected", + [ + ('"hello"', "hello"), + ("42", 42), + ("3.14", 3.14), + ("true", True), + ("false", False), + ("null", None), + ], +) +def test_parses_valid_json_scalars(raw, expected): + assert safe_json_loads(raw) == expected + + +def test_returns_default_none_on_invalid_json(): + assert safe_json_loads("{not valid json") is None + + +def test_returns_custom_default_on_invalid_json(): + sentinel = {"fallback": True} + assert safe_json_loads("oops", default=sentinel) is sentinel + + +def test_returns_default_on_empty_string(): + assert safe_json_loads("") is None + + +@pytest.mark.parametrize("bad_input", [None, 123, 4.5, ["a"], {"b": 1}]) +def test_returns_default_on_non_string_input(bad_input): + assert safe_json_loads(bad_input, default="fallback") == "fallback" From ab1fc93646270b416825c2b011664a0e7235f98a Mon Sep 17 00:00:00 2001 From: Femi Onisile Date: Sun, 7 Jun 2026 16:45:01 +0100 Subject: [PATCH 2/2] test: make JSON null case falsifiable with a sentinel default --- .../litellm_core_utils/test_safe_json_loads.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py b/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py index a3e1157136e..5fdc8df15ae 100644 --- a/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py +++ b/tests/test_litellm/litellm_core_utils/test_safe_json_loads.py @@ -27,13 +27,19 @@ def test_parses_valid_json_array(): ("3.14", 3.14), ("true", True), ("false", False), - ("null", None), ], ) def test_parses_valid_json_scalars(raw, expected): assert safe_json_loads(raw) == expected +def test_parses_json_null_to_none(): + # Use a non-None default so a correct parse (real None) is distinguishable + # from the function silently falling back to its default. + sentinel = object() + assert safe_json_loads("null", default=sentinel) is None + + def test_returns_default_none_on_invalid_json(): assert safe_json_loads("{not valid json") is None