"""Tests for `.astro` extraction (#850).
Astro files have a TypeScript frontmatter block (`---...---`) at the top where
nearly all imports live, followed by an HTML-with-expressions template and
optionally `
""",
)
layout = _write(tmp_path / "src/layouts/Layout.astro", "---\n---\n\n")
hydrate = _write(tmp_path / "src/client/hydrate.ts", "export function hydrate(){}\n")
result = extract_astro(page)
targets = _import_targets(result, relation="imports_from")
assert _make_id(str(layout)) in targets
assert _make_id(str(hydrate)) in targets
def test_extract_astro_no_frontmatter_does_not_crash(tmp_path):
"""Astro permits frontmatter-less files (pure-HTML pages). Must not raise."""
page = _write(
tmp_path / "src/pages/plain.astro",
"
no frontmatter here
\n",
)
result = extract_astro(page)
# Empty/no-imports result is acceptable; the extractor must just not crash.
assert isinstance(result, dict)
assert _import_targets(result, relation="imports_from") == set()
def test_extract_astro_handles_tsconfig_path_alias(tmp_path):
_write(
tmp_path / "tsconfig.json",
"""{
"compilerOptions": {
"baseUrl": ".",
"paths": { "@components/*": ["src/components/*"] }
}
}
""",
)
page = _write(
tmp_path / "src/pages/alias.astro",
"""---
import Hero from '@components/Hero.astro';
---
""",
)
hero = _write(tmp_path / "src/components/Hero.astro", "---\n---\nh
\n")
result = extract_astro(page)
targets = _import_targets(result, relation="imports_from")
assert _make_id(str(hero)) in targets
def _labels(result: dict) -> dict[str, str]:
"""Label -> source_location for every node except the file node."""
return {
str(n.get("label")): str(n.get("source_location"))
for n in result.get("nodes", [])
if n.get("id") != result.get("nodes", [{}])[0].get("id")
}
def test_extract_astro_template_is_not_a_parse_error(tmp_path):
"""The template is not TS; only frontmatter and
""",
)
result = extract_astro(page)
assert result.get("parse_errors") is None
labels = _labels(result)
assert "rank()" in labels and "toggle()" in labels
# Masking keeps offsets, so locations still point at the original lines.
assert labels["rank()"] == "L5"
assert labels["toggle()"] == "L15"
def test_extract_astro_scripts_on_one_line_do_not_merge(tmp_path):
"""Two script bodies on one line must not parse as a single statement."""
page = _write(
tmp_path / "src/pages/inline.astro",
"\n",
)
result = extract_astro(page)
assert result.get("parse_errors") is None
assert "b()" in _labels(result)