Coverage for src/jsoncrack_for_sphinx/patterns/pattern_strategies_impl.py: 76%

45 statements  

« prev     ^ index     » next       coverage.py v7.10.0, created at 2025-07-24 22:26 +0000

1""" 

2Pattern generation strategies for different use cases. 

3""" 

4 

5from typing import TYPE_CHECKING, List, Tuple 

6 

7from .pattern_utils import join_with_separator 

8 

9if TYPE_CHECKING: 

10 from ..search.search_policy import SearchPolicy 

11 

12 

13def add_class_method_patterns( 

14 parts: List[str], search_policy: "SearchPolicy" 

15) -> List[Tuple[str, str]]: 

16 """Add class.method patterns.""" 

17 class_method_parts = parts[-2:] # Last 2 parts 

18 class_method = join_with_separator( 

19 class_method_parts, search_policy.path_to_class_separator 

20 ) 

21 return [ 

22 (f"{class_method}.schema.json", "schema"), 

23 (f"{class_method}.json", "json"), 

24 ] 

25 

26 

27def add_path_component_patterns( 

28 parts: List[str], search_policy: "SearchPolicy" 

29) -> List[Tuple[str, str]]: 

30 """Add intermediate path component patterns.""" 

31 patterns = [] 

32 

33 # Generate intermediate patterns like "catalog.ProductService.similar" 

34 for i in range(len(parts) - 3, 0, -1): 

35 partial_parts = parts[i:] 

36 if len(partial_parts) >= 3: 

37 partial_path = join_with_separator( 

38 partial_parts, search_policy.path_to_file_separator 

39 ) 

40 patterns.extend( 

41 [ 

42 (f"{partial_path}.schema.json", "schema"), 

43 (f"{partial_path}.json", "json"), 

44 ] 

45 ) 

46 

47 # Include intermediate path components without package name 

48 if not search_policy.include_package_name and len(parts) >= 3: 

49 without_package = parts[1:] 

50 if search_policy.path_to_file_separator.name == "SLASH": 

51 patterns.extend( 

52 add_slash_separated_patterns(without_package, search_policy) 

53 ) 

54 else: 

55 full_path = join_with_separator( 

56 without_package, search_policy.path_to_file_separator 

57 ) 

58 patterns.extend( 

59 [ 

60 (f"{full_path}.schema.json", "schema"), 

61 (f"{full_path}.json", "json"), 

62 ] 

63 ) 

64 

65 return patterns 

66 

67 

68def add_package_name_patterns( 

69 parts: List[str], search_policy: "SearchPolicy" 

70) -> List[Tuple[str, str]]: 

71 """Add patterns that include package name.""" 

72 patterns = [] 

73 

74 if search_policy.path_to_file_separator.name == "SLASH": 

75 if len(parts) >= 2: 

76 dir_parts = parts[:-2] 

77 class_method_parts = parts[-2:] 

78 class_method = join_with_separator( 

79 class_method_parts, search_policy.path_to_class_separator 

80 ) 

81 if dir_parts: 

82 dir_path = "/".join(dir_parts) 

83 patterns.extend( 

84 [ 

85 (f"{dir_path}/{class_method}.schema.json", "schema"), 

86 (f"{dir_path}/{class_method}.json", "json"), 

87 ] 

88 ) 

89 else: 

90 full_path = join_with_separator(parts, search_policy.path_to_file_separator) 

91 patterns.extend( 

92 [ 

93 (f"{full_path}.schema.json", "schema"), 

94 (f"{full_path}.json", "json"), 

95 ] 

96 ) 

97 

98 return patterns 

99 

100 

101def add_slash_separated_patterns( 

102 without_package: List[str], search_policy: "SearchPolicy" 

103) -> List[Tuple[str, str]]: 

104 """Add patterns for slash-separated directory structure.""" 

105 patterns = [] 

106 

107 if len(without_package) >= 2: 

108 dir_parts = without_package[:-2] 

109 class_method_parts = without_package[-2:] 

110 class_method = join_with_separator( 

111 class_method_parts, search_policy.path_to_class_separator 

112 ) 

113 if dir_parts: 

114 dir_path = "/".join(dir_parts) 

115 patterns.extend( 

116 [ 

117 (f"{dir_path}/{class_method}.schema.json", "schema"), 

118 (f"{dir_path}/{class_method}.json", "json"), 

119 ] 

120 ) 

121 

122 return patterns