File size: 3,901 Bytes
f8dbde1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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"}