Coverage for src/jsoncrack_for_sphinx/patterns/pattern_strategies.py: 100%
61 statements
« prev ^ index » next coverage.py v7.10.0, created at 2025-07-24 22:26 +0000
« prev ^ index » next coverage.py v7.10.0, created at 2025-07-24 22:26 +0000
1"""
2Pattern generation strategies.
3"""
5from typing import List, Tuple
7from ..search.search_policy import SearchPolicy
8from ..utils.types import PathSeparator
11def join_with_separator(parts_list: List[str], separator: PathSeparator) -> str:
12 """Join parts with the specified separator."""
13 if separator == PathSeparator.DOT:
14 return ".".join(parts_list)
15 elif separator == PathSeparator.SLASH:
16 return "/".join(parts_list)
17 elif separator == PathSeparator.NONE:
18 return "".join(parts_list)
19 else:
20 return ".".join(parts_list) # fallback
23def add_class_method_patterns(
24 parts: List[str], search_policy: SearchPolicy
25) -> List[Tuple[str, str]]:
26 """Add class.method patterns."""
27 class_method_parts = parts[-2:] # Last 2 parts
28 class_method = join_with_separator(
29 class_method_parts, search_policy.path_to_class_separator
30 )
31 return [
32 (f"{class_method}.schema.json", "schema"),
33 (f"{class_method}.json", "json"),
34 ]
37def add_path_component_patterns(
38 parts: List[str], search_policy: SearchPolicy
39) -> List[Tuple[str, str]]:
40 """Add intermediate path component patterns."""
41 patterns = []
43 # Generate intermediate patterns like "catalog.ProductService.similar"
44 for i in range(len(parts) - 3, 0, -1):
45 partial_parts = parts[i:]
46 if len(partial_parts) >= 3:
47 partial_path = join_with_separator(
48 partial_parts, search_policy.path_to_file_separator
49 )
50 patterns.extend(
51 [
52 (f"{partial_path}.schema.json", "schema"),
53 (f"{partial_path}.json", "json"),
54 ]
55 )
57 # Include intermediate path components without package name
58 if not search_policy.include_package_name and len(parts) >= 3:
59 without_package = parts[1:]
60 if search_policy.path_to_file_separator == PathSeparator.SLASH:
61 patterns.extend(
62 add_slash_separated_patterns(without_package, search_policy)
63 )
64 else:
65 full_path = join_with_separator(
66 without_package, search_policy.path_to_file_separator
67 )
68 patterns.extend(
69 [
70 (f"{full_path}.schema.json", "schema"),
71 (f"{full_path}.json", "json"),
72 ]
73 )
75 return patterns
78def add_package_name_patterns(
79 parts: List[str], search_policy: SearchPolicy
80) -> List[Tuple[str, str]]:
81 """Add patterns that include package name."""
82 patterns = []
84 if search_policy.path_to_file_separator == PathSeparator.SLASH:
85 if len(parts) >= 2:
86 dir_parts = parts[:-2]
87 class_method_parts = parts[-2:]
88 class_method = join_with_separator(
89 class_method_parts, search_policy.path_to_class_separator
90 )
91 if dir_parts:
92 dir_path = "/".join(dir_parts)
93 patterns.extend(
94 [
95 (f"{dir_path}/{class_method}.schema.json", "schema"),
96 (f"{dir_path}/{class_method}.json", "json"),
97 ]
98 )
99 else:
100 full_path = join_with_separator(parts, search_policy.path_to_file_separator)
101 patterns.extend(
102 [
103 (f"{full_path}.schema.json", "schema"),
104 (f"{full_path}.json", "json"),
105 ]
106 )
108 return patterns
111def add_slash_separated_patterns(
112 without_package: List[str], search_policy: SearchPolicy
113) -> List[Tuple[str, str]]:
114 """Add patterns for slash-separated directory structure."""
115 patterns = []
117 if len(without_package) >= 2:
118 dir_parts = without_package[:-2]
119 class_method_parts = without_package[-2:]
120 class_method = join_with_separator(
121 class_method_parts, search_policy.path_to_class_separator
122 )
123 if dir_parts:
124 dir_path = "/".join(dir_parts)
125 patterns.extend(
126 [
127 (f"{dir_path}/{class_method}.schema.json", "schema"),
128 (f"{dir_path}/{class_method}.json", "json"),
129 ]
130 )
132 return patterns
135def remove_duplicates(patterns: List[Tuple[str, str]]) -> List[Tuple[str, str]]:
136 """Remove duplicate patterns while preserving order."""
137 seen = set()
138 unique_patterns = []
139 for pattern, file_type in patterns:
140 key = (pattern, file_type)
141 if key not in seen:
142 seen.add(key)
143 unique_patterns.append((pattern, file_type))
144 return unique_patterns