Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,14 @@ def score_file(

base += kg_bonus

# Penalties.
# Penalties. Actual test specs are penalized so substantive production code
# ranks higher under caps; test support/infrastructure files (fixtures, helpers)
# are preserved without penalty.
if fi.is_test:
base *= _PENALTY_TEST
from repowise.core.test_paths import is_test_support_path

if not is_test_support_path(fi.path, getattr(fi, "language", None)):
base *= _PENALTY_TEST
if (
n_symbols <= _PENALTY_TRIVIAL_SYMBOL_CAP
and fi.size_bytes < _PENALTY_TRIVIAL_SIZE_BYTES
Expand Down
29 changes: 14 additions & 15 deletions packages/core/src/repowise/core/generation/selection/selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,27 +274,26 @@ def count_documentable_files(parsed_files: list[Any]) -> int:
to do before generation starts, in the same terms the policy uses.
"""
return sum(
1 for p in parsed_files if _is_code_file(p) and _passes_importance_floor(p.file_info.path)
1
for p in parsed_files
if _is_code_file(p)
and _passes_importance_floor(p.file_info.path, getattr(p.file_info, "language", None))
)


def _passes_importance_floor(path: str) -> bool:
def _passes_importance_floor(path: str, language: str | None = None) -> bool:
"""Whether *path* is worth a file page at all.

Two exclusions, both measured rather than assumed: test files and pure
``__init__.py`` re-export files. Pages for either only dilute retrieval
(test-file pages pushed real answers below rank 5 in dogfood), and neither
says anything a reader cannot get from the file it re-exports or tests.

This used to gate only the coverage tail, back when the budget picked a
fraction of the repo and the tail backfilled the rest. There is no tail any
more because every file that clears this floor gets a page, so the floor is
now simply what file-page selection means. The rule is unchanged; only the
set it applies to grew from the remainder to the whole.
Two exclusions, both measured rather than assumed: actual test spec files
(is_test_path) and pure ``__init__.py`` re-export files. Test support/fixture
modules (conftest.py, helpers/, fixtures/) pass the floor because they
contain key architectural and harness conventions needed for retrieval.
"""
norm = path.replace("\\", "/")
if norm.startswith("tests/") or "/tests/" in norm:
from repowise.core.test_paths import is_test_path

if is_test_path(path, language):
return False
norm = path.replace("\\", "/")
return norm.rsplit("/", 1)[-1] != "__init__.py"


Expand All @@ -317,7 +316,7 @@ def _build_file_candidates(
if not _is_code_file(p):
continue
path = p.file_info.path
if not _passes_importance_floor(path):
if not _passes_importance_floor(path, getattr(p.file_info, "language", None)):
continue
is_hotspot = bool(git.get(path, {}).get("is_hotspot", False))
s = score_file(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
display_name="JavaScript",
import_support="full",
test_infixes=(".test.", ".spec."),
test_fixture_stems=("fixtures", "fixture", "setup-tests"),
test_stem_suffixes=("_test", ".test", ".spec"),
extensions=frozenset({".js", ".jsx", ".mjs", ".cjs"}),
grammar_package="tree_sitter_javascript",
scm_file="javascript.scm",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
display_name="TypeScript",
import_support="full",
test_infixes=(".test.", ".spec."),
test_fixture_stems=("fixtures", "fixture", "setup-tests"),
test_stem_suffixes=("_test", ".test", ".spec"),
extensions=frozenset({".ts", ".tsx", ".mts", ".cts"}),
grammar_package="tree_sitter_typescript",
grammar_loader="language_typescript",
Expand Down
45 changes: 45 additions & 0 deletions tests/unit/generation/test_selection_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,51 @@ def test_importance_floor_excludes_tests_and_reexports():
assert len(sel.file_page_paths) == 6


def test_test_support_files_pass_importance_floor():
"""Test infrastructure and fixture files pass the floor to receive file pages."""
parsed, pagerank, betweenness, community = _build_synthetic_repo(6)
extras = [
("tests/conftest.py", "python"),
("tests/fixtures/setup.py", "python"),
("apps/console/e2e/helpers/hydration.ts", "typescript"),
("apps/console/e2e/fixtures.ts", "typescript"),
]
for path, lang in extras:
parsed.append(
FakeParsedFile(
file_info=FakeFileInfo(path=path, language=lang, is_test=True),
symbols=[FakeSymbol(name="fixture_helper")],
)
)
pagerank[path] = 0.1
betweenness[path] = 0.0
community[path] = 0

# Also add pure specs which must be excluded
test_specs = [
("tests/unit/test_foo.py", "python"),
("apps/console/e2e/specs/login.spec.ts", "typescript"),
]
for path, lang in test_specs:
parsed.append(
FakeParsedFile(
file_info=FakeFileInfo(path=path, language=lang, is_test=True),
symbols=[FakeSymbol(name="test_login")],
)
)
pagerank[path] = 0.1
betweenness[path] = 0.0
community[path] = 0

sel = select_pages(_inputs(parsed, pagerank, betweenness, community, GenerationConfig()))

for path, _ in extras:
assert path in sel.file_page_paths, f"Expected {path} to receive a file_page"

for path, _ in test_specs:
assert path not in sel.file_page_paths, f"Expected {path} to be excluded"


def test_selection_does_not_depend_on_having_a_key():
"""Keyed and keyless runs select exactly the same pages.

Expand Down
3 changes: 3 additions & 0 deletions tests/unit/test_test_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
("spec/support/helper.rb", None, "support"),
# e2e suites
("e2e/login.ts", None, "test"),
("apps/console/e2e/helpers/hydration.ts", "typescript", "support"),
("apps/console/e2e/fixtures.ts", "typescript", "support"),
("apps/console/e2e/specs/login.spec.ts", "typescript", "test"),
# production code that merely contains the word: the unanchored
# `test[s_/]` substring rule classified the first three as tests
("src/latest/api.py", None, ""), # #1103 finding 1
Expand Down
Loading