Coverage for jsonschema_diff/core/compare_combined.py: 68%

31 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-15 18:01 +0000

1from typing import TYPE_CHECKING, Any, Dict 

2 

3from .abstraction import Statuses, ToCompare 

4from .compare_base import Compare 

5 

6if TYPE_CHECKING: 

7 from .compare_base import LEGEND_RETURN_TYPE 

8 

9 

10class CompareCombined(Compare): 

11 def __init__(self, *args: Any, **kwargs: Any) -> None: 

12 super().__init__(*args, **kwargs) 

13 self.dict_compare: Dict[str, ToCompare] = {} 

14 self.dict_values: Dict[str, Any] = {} 

15 

16 def compare(self) -> Statuses: 

17 for c in self.to_compare: 

18 if self.status == Statuses.UNKNOWN: 

19 self.status = c.status 

20 elif self.status != c.status: 

21 self.status = Statuses.REPLACED 

22 

23 self.dict_compare[c.key] = c 

24 self.dict_values[c.key] = c.value 

25 

26 return self.status 

27 

28 def calc_diff(self) -> dict[str, int]: 

29 """ 

30 Multiple implementation: counts its own status as the number of keys. 

31 Complex comparators (e.g. CompareList) override this to return an aggregate. 

32 """ 

33 stats = {self.status.name: 1} 

34 for comp in self.dict_compare.values(): 

35 if comp.status.name not in stats: 

36 stats[comp.status.name] = 0 

37 stats[comp.status.name] += 1 

38 

39 return stats 

40 

41 def get_name(self) -> str: 

42 raise NotImplementedError("The get_name method must be overridden") 

43 

44 def render( 

45 self, tab_level: int = 0, with_path: bool = True, to_crop: tuple[int, int] = (0, 0) 

46 ) -> str: 

47 raise NotImplementedError("The render method must be overridden") 

48 

49 @staticmethod 

50 def legend() -> "LEGEND_RETURN_TYPE": 

51 raise NotImplementedError("The legend method must be overridden")