Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion libs/giskard-checks/src/giskard/checks/builtin/json_valid.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,11 @@ async def run(self, trace: TraceType) -> CheckResult:
@staticmethod
def _parse_json(value: Any) -> Any:
if isinstance(value, str):
return json.loads(value)
if value.strip() == "":
return json.loads(value)
if JsonValid._looks_like_serialized_json(value):
return json.loads(value)
return value

try:
json.dumps(value)
Expand All @@ -123,6 +127,27 @@ def _parse_json(value: Any) -> Any:

return value

@staticmethod
def _looks_like_serialized_json(value: str) -> bool:
stripped = value.strip()
if not stripped:
return False

if stripped.startswith(("{", "[", '"')):
return True

if stripped in ("true", "false", "null"):
return True

if (stripped[:1].isdigit() or stripped.startswith("-")) and "_" not in stripped:
try:
parsed = json.loads(stripped)
except json.JSONDecodeError:
return False
return isinstance(parsed, int | float)

return False

@staticmethod
def _validate_schema_definition(schema: dict[str, Any]) -> None:
validator_for(schema).check_schema(schema)
Expand Down
8 changes: 8 additions & 0 deletions libs/giskard-checks/tests/builtin/test_json_valid.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@
("null", None),
("true", True),
("42", 42),
("hello", "hello"),
("truth", "truth"),
("falsehood", "falsehood"),
("nullify", "nullify"),
("123-apple", "123-apple"),
("-infinity", "-infinity"),
],
)
async def test_valid_json_output_passes(outputs: Any, expected_parsed: Any) -> None:
Expand All @@ -37,6 +43,7 @@ async def test_valid_json_output_passes(outputs: Any, expected_parsed: Any) -> N
[
'{"name": "Alice"',
"",
" ",
],
)
async def test_invalid_json_string_fails(outputs: str) -> None:
Expand Down Expand Up @@ -83,6 +90,7 @@ async def test_nested_jsonpath_extraction() -> None:
),
({"type": "integer"}, 42, 42),
({"type": "string", "minLength": 3, "maxLength": 7}, '"hello"', "hello"),
({"type": "string", "minLength": 3, "maxLength": 7}, "hello", "hello"),
],
)
async def test_schema_validation_passes(
Expand Down
Loading