import pytest from deg.normalize import count_leaves, normalize_schema from deg.schema import compile_schema def test_refs_inlined_annotations_dropped_and_compiles(): raw = { "$schema": "http://json-schema.org/draft-07/schema#", "definitions": {"addr": {"type": "object", "properties": { "city": {"type": "string", "examples": ["Paris"]}, "zip": {"type": "string", "format": "postal-code"}}}}, "type": "object", "properties": { "home": {"$ref": "#/definitions/addr"}, "when": {"type": "string", "format": "date", "evaluation_config": "exact"}, "kind": {"oneOf": [{"const": "a", "description": "A"}, {"const": "b"}]}, "fixed": {"const": 3}, "map": {"type": "object", "additionalProperties": {"type": "string"}}, "maybe": {"anyOf": [{"type": "integer"}, {"type": "null"}]}, "tags": {"type": "array", "items": {"type": "string"}, "contains": {}}, }, "required": ["home", "fixed"], "minProperties": 1, } out, why = normalize_schema(raw) assert why == "ok" compile_schema(out) props = out["properties"] assert set(props) == {"home", "when", "kind", "maybe", "tags"} assert props["home"]["properties"]["zip"] == {"type": "string"} # unknown format dropped assert "examples" not in props["home"]["properties"]["city"] assert props["kind"]["enum"] == ["a", "b"] assert props["maybe"]["type"] == ["integer", "null"] assert out["required"] == ["home"] and out["additionalProperties"] is False assert "contains" not in props["tags"] def test_leaf_cap_depth_and_skips(): wide = {"type": "object", "properties": {f"f{i}": {"type": "string"} for i in range(50)}} out, _ = normalize_schema(wide, max_leaves=30) assert count_leaves(out) == 30 and list(out["properties"])[-1] == "f29" assert normalize_schema({"type": "array", "items": {"type": "string"}})[1] == \ "root_not_object" rec = {"type": "object", "properties": {"n": {"$ref": "#"}, "a": {"type": "string"}, "b": {"type": "number"}}} out, why = normalize_schema(rec) assert why == "ok" and set(out["properties"]) == {"a", "b"} assert normalize_schema({"type": "object", "properties": {"x": {"const": 1}}})[0] is None @pytest.mark.parametrize("bad", [ {"type": "object", "properties": {"a": {"type": "integer", "minimum": 1, "maximum": 1}, "b": {"type": "string"}, "c": {"type": "boolean"}}}, {"type": "object", "properties": {"a": {"enum": ["x", "y"], "maxLength": 3}, "b": {"type": "string"}}}, ]) def test_compiler_errors_drop_only_the_bad_field(bad): out, why = normalize_schema(bad) assert why == "ok" compile_schema(out) assert "b" in out["properties"] def test_string_or_number_union_becomes_span(): raw = {"type": "object", "properties": { "year": {"anyOf": [{"type": "string", "vendor": 1}, {"type": "integer"}, {"type": "null"}]}, "rank": {"anyOf": [{"type": "integer"}, {"type": "string"}]}, "mixed": {"anyOf": [{"type": "integer", "minimum": 3}, {"type": "string"}]}}} out, why = normalize_schema(raw) assert why == "ok" assert out["properties"]["year"]["type"] == ["string", "null"] assert out["properties"]["rank"]["type"] == "string" assert "mixed" not in out["properties"] # a constrained branch is not merged away def test_union_with_list_typed_branch_does_not_crash(): raw = {"type": "object", "properties": { "a": {"anyOf": [{"type": ["string", "integer"]}, {"type": "string"}]}, "b": {"type": "string"}, "c": {"type": "number"}}} out, why = normalize_schema(raw) assert why == "ok" and set(out["properties"]) == {"b", "c"}