Run full aggregation check across all excluded test directories. Returns: (success, violations) tuple.
()
| 129 | |
| 130 | |
| 131 | def check() -> tuple[bool, list[str]]: |
| 132 | """Run full aggregation check across all excluded test directories. |
| 133 | |
| 134 | Returns: |
| 135 | (success, violations) tuple. |
| 136 | """ |
| 137 | violations: list[str] = [] |
| 138 | excluded_dirs = _get_aggregated_test_dirs() |
| 139 | |
| 140 | for excluded_dir in sorted(excluded_dirs): |
| 141 | if not excluded_dir.exists(): |
| 142 | continue |
| 143 | |
| 144 | aggregator, included_files = _collect_included_files(excluded_dir) |
| 145 | if aggregator is None: |
| 146 | rel = excluded_dir.relative_to(PROJECT_ROOT) |
| 147 | violations.append( |
| 148 | f"Missing aggregator: {rel.as_posix()}.cpp " |
| 149 | f"(no parent .cpp file for excluded directory {rel.as_posix()}/)" |
| 150 | ) |
| 151 | continue |
| 152 | |
| 153 | # Check every .hpp file in the excluded directory and subdirs |
| 154 | for hpp_file in sorted(excluded_dir.rglob("*.hpp")): |
| 155 | resolved = hpp_file.resolve() |
| 156 | if resolved not in included_files: |
| 157 | rel_agg = aggregator.relative_to(PROJECT_ROOT) |
| 158 | rel_file = hpp_file.relative_to(PROJECT_ROOT) |
| 159 | violations.append( |
| 160 | f"{rel_agg.as_posix()}: orphaned test file not " |
| 161 | f"#included by any aggregator: {rel_file.as_posix()}" |
| 162 | ) |
| 163 | |
| 164 | # Check for .cpp includes in the direct aggregator (should be .hpp) |
| 165 | for inc_path in sorted(_parse_includes(aggregator)): |
| 166 | inc_resolved = (aggregator.parent / inc_path).resolve() |
| 167 | if not inc_resolved.exists(): |
| 168 | inc_resolved = (PROJECT_ROOT / inc_path).resolve() |
| 169 | if inc_resolved.is_relative_to(excluded_dir) and inc_path.endswith(".cpp"): |
| 170 | rel_agg = aggregator.relative_to(PROJECT_ROOT) |
| 171 | violations.append( |
| 172 | f'{rel_agg.as_posix()}: #include "{inc_path}" should use .hpp ' |
| 173 | f"(included test files must use .hpp extension)" |
| 174 | ) |
| 175 | |
| 176 | return len(violations) == 0, violations |
| 177 | |
| 178 | |
| 179 | def check_single_file(file_path: Path) -> tuple[bool, list[str]]: |
no test coverage detected