Coverage for jsonschema_diff/config_maker.py: 40%
55 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-15 18:01 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-15 18:01 +0000
1"""
2Factory for a ready-to-use :class:`jsonschema_diff.core.Config` instance.
4All optional switches are enabled by default; pass ``False`` to disable.
5"""
7from dataclasses import dataclass
8from enum import Enum
10from .core import Compare, Config
11from .core.custom_compare import CompareList, CompareRange
12from .core.tools.combine import COMBINE_RULES_TYPE
13from .core.tools.compare import COMPARE_RULES_TYPE
14from .core.tools.context import CONTEXT_RULES_TYPE, PAIR_CONTEXT_RULES_TYPE
15from .core.tools.render import PATH_MAKER_IGNORE_RULES_TYPE
18@dataclass(frozen=True)
19class MultilineChars:
20 START_LINE: str
21 MIDDLE_LINE: str
22 END_LINE: str
23 SINGLE_LINE: str
26class MultilineListRender(Enum):
27 Soft = MultilineChars("╭", "│", "╰", " ")
28 Hard = MultilineChars("┌", "│", "└", " ")
29 Double = MultilineChars("╔", "║", "╚", " ")
30 Without = MultilineChars(" ", " ", " ", " ")
33class ConfigMaker:
34 """Helper that builds a fully populated :class:`~jsonschema_diff.core.Config`."""
36 # pylint: disable=too-many-arguments
37 @staticmethod
38 def make(
39 *,
40 tab_size: int = 1,
41 all_for_rendering: bool = False,
42 crop_path: bool = True,
43 path_render_with_properies: bool = False,
44 path_render_with_items: bool = False,
45 list_comparator: bool = True,
46 list_multiline_render: MultilineListRender = MultilineListRender.Soft,
47 range_digit_comparator: bool = True,
48 range_length_comparator: bool = True,
49 range_items_comparator: bool = True,
50 range_properties_comparator: bool = True,
51 additional_compare_rules: COMPARE_RULES_TYPE = {},
52 additional_combine_rules: COMBINE_RULES_TYPE = [],
53 additional_pair_context_rules: PAIR_CONTEXT_RULES_TYPE = [],
54 additional_context_rules: CONTEXT_RULES_TYPE = {},
55 additional_path_maker_ignore: PATH_MAKER_IGNORE_RULES_TYPE = [],
56 ) -> Config:
57 """
58 Assemble and return a :class:`~jsonschema_diff.core.Config`.
60 Parameters
61 ----------
62 tab_size : int
63 Number of spaces per indentation level.
64 path_render_with_properies, path_render_with_items : bool
65 Include these schema service tokens in rendered paths.
66 list_comparator : bool
67 Enable :class:`~jsonschema_diff.core.custom_compare.CompareList`.
68 list_multiline_render : MultilineListRender
69 How to render multi-line elements of list.
70 range_*_comparator : bool
71 Enable :class:`~jsonschema_diff.core.custom_compare.CompareRange`
72 for numeric/length/items/properties limits.
73 additional_* : collections
74 User-supplied rules that override the built-ins.
75 """
76 tab = " " * tab_size
78 compare_rules: COMPARE_RULES_TYPE = {}
79 combine_rules: COMBINE_RULES_TYPE = []
80 pair_context_rules: list[list[str | type[Compare]]] = []
81 context_rules: dict[str | type[Compare], list[str | type[Compare]]] = {}
82 path_maker_ignore: list[str] = []
83 compare_config: dict[type[Compare], dict] = {}
85 # Built-in comparators
86 if list_comparator:
87 compare_rules[list] = CompareList
88 compare_config[CompareList] = {
89 field: getattr(list_multiline_render.value, field)
90 for field in list_multiline_render.value.__dataclass_fields__
91 }
93 def add_rule(keys: list[str], value: type[Compare]) -> None:
94 combine_rules.append(keys)
95 for key in keys:
96 compare_rules[key] = value
98 ranger = CompareRange
99 if range_digit_comparator:
100 add_rule(["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum"], ranger)
101 if range_length_comparator:
102 add_rule(["minLength", "maxLength"], ranger)
103 if range_items_comparator:
104 add_rule(["minItems", "maxItems"], ranger)
105 if range_properties_comparator:
106 add_rule(["minProperties", "maxProperties"], ranger)
108 # Path-render filters
109 if not path_render_with_properies:
110 path_maker_ignore.append("properties")
111 if not path_render_with_items:
112 path_maker_ignore.append("items")
114 # User additions override defaults
115 compare_rules.update(additional_compare_rules)
116 combine_rules.extend(additional_combine_rules)
117 pair_context_rules.extend([list(r) for r in additional_pair_context_rules])
118 context_rules.update({k: list(v) for k, v in additional_context_rules.items()})
119 path_maker_ignore.extend(additional_path_maker_ignore)
121 return Config(
122 tab=tab,
123 all_for_rendering=all_for_rendering,
124 crop_path=crop_path,
125 compare_rules=compare_rules,
126 combine_rules=combine_rules,
127 path_maker_ignore=path_maker_ignore,
128 pair_context_rules=pair_context_rules,
129 context_rules=context_rules,
130 compare_config=compare_config,
131 )