mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-15 03:47:05 +00:00
add missing test coverage for #1077 scope guard and markdown fence fixes
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+74
-1
@@ -1110,6 +1110,45 @@ def test_js_local_const_does_not_emit_phantom_node(tmp_path):
|
||||
assert "exportedConst" in labels, f"exported const 'exportedConst' missing: {labels}"
|
||||
|
||||
|
||||
def test_js_module_level_arrow_produces_node_and_call_edges(tmp_path):
|
||||
"""Module-level arrow functions must still emit a node and capture their calls (#1077).
|
||||
|
||||
The scope guard must not accidentally suppress top-level arrow functions.
|
||||
"""
|
||||
src = (
|
||||
"function helper() { return 1; }\n"
|
||||
"const handler = () => {\n"
|
||||
" helper();\n"
|
||||
"};\n"
|
||||
)
|
||||
f = tmp_path / "arrows.js"
|
||||
f.write_text(src)
|
||||
r = extract_js(f)
|
||||
labels = _labels(r)
|
||||
relations = _relations(r)
|
||||
|
||||
assert any("handler" in l for l in labels), f"module-level arrow 'handler' missing: {labels}"
|
||||
assert "calls" in relations, f"expected 'calls' edge from handler->helper: {relations}"
|
||||
|
||||
|
||||
def test_ts_local_const_does_not_emit_phantom_node(tmp_path):
|
||||
"""Scope guard applies to TypeScript files too (shared _js_extra_walk path)."""
|
||||
src = (
|
||||
"describe('suite', () => {\n"
|
||||
" const inner: Set<number> = new Set([1, 2]);\n"
|
||||
"});\n"
|
||||
"\n"
|
||||
"export const topLevel = { a: 1 };\n"
|
||||
)
|
||||
f = tmp_path / "scope_guard.ts"
|
||||
f.write_text(src)
|
||||
r = extract_js(f)
|
||||
labels = _labels(r)
|
||||
|
||||
assert "inner" not in labels, f"phantom TS node for arrow-body local 'inner': {labels}"
|
||||
assert "topLevel" in labels, f"module-level TS const 'topLevel' missing: {labels}"
|
||||
|
||||
|
||||
# ── Markdown ─────────────────────────────────────────────────────────────────
|
||||
|
||||
from graphify.extract import extract_markdown
|
||||
@@ -1150,7 +1189,41 @@ def test_markdown_contains_edges():
|
||||
r = extract_markdown(FIXTURES / "deploy_guide.md")
|
||||
assert "contains" in _relations(r)
|
||||
contains_edges = [e for e in r["edges"] if e["relation"] == "contains"]
|
||||
assert len(contains_edges) >= 4 # file->h1, h1->h2s, h2->h3
|
||||
# deploy_guide.md has: file->h1, h1->h2(Prerequisites), h1->h2(Full Deploy),
|
||||
# h2(Full Deploy)->h3(Database Migration), h1->h2(Rollback) = 5 edges
|
||||
assert len(contains_edges) >= 5, f"expected >= 5 contains edges, got {len(contains_edges)}"
|
||||
|
||||
|
||||
def test_markdown_fenced_heading_not_parsed():
|
||||
"""A '## heading' inside a fenced block must not produce a heading node (#1077).
|
||||
|
||||
The fence-toggle skips over fenced contents so interior markdown syntax
|
||||
is not misread as document structure.
|
||||
"""
|
||||
import tempfile, os
|
||||
src = (
|
||||
"# Real Heading\n"
|
||||
"\n"
|
||||
"```bash\n"
|
||||
"## Not A Heading\n"
|
||||
"echo hello\n"
|
||||
"```\n"
|
||||
"\n"
|
||||
"## Another Real Heading\n"
|
||||
)
|
||||
with tempfile.NamedTemporaryFile(suffix=".md", mode="w", delete=False) as fh:
|
||||
fh.write(src)
|
||||
fpath = fh.name
|
||||
try:
|
||||
r = extract_markdown(Path(fpath))
|
||||
labels = _labels(r)
|
||||
finally:
|
||||
os.unlink(fpath)
|
||||
|
||||
assert any("Real Heading" in l for l in labels), f"'Real Heading' missing: {labels}"
|
||||
assert any("Another Real Heading" in l for l in labels), f"'Another Real Heading' missing: {labels}"
|
||||
assert not any("Not A Heading" in l for l in labels), \
|
||||
f"fenced '## Not A Heading' was incorrectly parsed as a node: {labels}"
|
||||
|
||||
def test_markdown_no_dangling_edges():
|
||||
r = extract_markdown(FIXTURES / "deploy_guide.md")
|
||||
|
||||
Reference in New Issue
Block a user