Openenv / tests /test_codegraph.py
vishaldhakad's picture
intial push
eda351c
Raw
History Blame Contribute Delete
4.64 kB
"""tests/test_codegraph.py — Unit tests for CodeGraph V2."""
import sys, os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
import pytest
from codegraph.graph import CodeGraph, _naming_style
from codegraph.extractor import extract_metadata
class TestNamingStyle:
def test_snake_case(self):
assert _naming_style("get_user") == "snake_case"
assert _naming_style("handle_path") == "snake_case"
def test_camel_case(self):
assert _naming_style("getUser") == "camelCase"
assert _naming_style("handlePath") == "camelCase"
def test_pascal_case(self):
assert _naming_style("GetUser") == "PascalCase"
assert _naming_style("UserManager") == "PascalCase"
def test_all_lowercase(self):
assert _naming_style("foo") == "snake_case"
class TestCodeGraph:
def test_empty_graph(self):
g = CodeGraph(episode_seed=1)
assert g.components == {}
assert g.conventions == {}
def test_update_adds_component(self):
g = CodeGraph(episode_seed=1)
meta = extract_metadata(
"def get_user(uid: int) -> dict:\n \"\"\"Get user.\"\"\"\n return {}",
"users.py", 0
)
g.update("users.py", meta)
assert "users" in g.components
def test_syntax_error_not_added(self):
g = CodeGraph(episode_seed=1)
bad_meta = {"status": "syntax_error", "functions": [], "imports": []}
g.update("bad.py", bad_meta)
assert len(g.components) == 0
def test_conventions_inferred_after_update(self):
g = CodeGraph(episode_seed=1)
meta = extract_metadata(
"def snake_one(x: int) -> str:\n \"\"\"Doc.\"\"\"\n return str(x)\n"
"def snake_two(y: int) -> str:\n \"\"\"Doc.\"\"\"\n return str(y)",
"module.py", 0
)
g.update("module.py", meta)
assert g.conventions.get("naming") in ("snake_case", "camelCase", "PascalCase", "mixed", "unknown")
def test_mixed_style_detected(self):
g = CodeGraph(episode_seed=1)
# Create artificial metadata with exactly 50/50 split
meta = {
"status": "ok",
"functions": [
{"name": "get_user"}, # snake_case
{"name": "getUser"}, # camelCase
{"name": "set_value"}, # snake_case
{"name": "getValue"}, # camelCase
],
"imports": [],
"conventions": {},
"language": "py",
"created_at_step": 0,
}
g.update("mixed.py", meta)
# 50/50 split — below 60% threshold → should be "mixed"
assert g.conventions.get("naming") == "mixed"
def test_slim_dict_under_limit(self):
g = CodeGraph(episode_seed=1)
for i in range(10):
meta = extract_metadata(
f"def func_{i}(x: int) -> str:\n return str(x)",
f"module_{i}.py", i
)
g.update(f"module_{i}.py", meta)
slim = g.to_slim_dict(limit=6000)
assert len(slim) <= 6000
class TestExtractor:
def test_extracts_functions(self):
code = "def hello(x: int) -> str:\n return str(x)"
meta = extract_metadata(code, "test.py", 0)
assert meta["status"] == "ok"
assert any(f["name"] == "hello" for f in meta["functions"])
def test_extracts_imports(self):
code = "import os\nfrom pathlib import Path\ndef foo(): pass"
meta = extract_metadata(code, "test.py", 0)
assert meta["status"] == "ok"
assert len(meta["imports"]) >= 1
def test_syntax_error_returns_structured(self):
code = "def broken(:\n pass"
meta = extract_metadata(code, "bad.py", 0)
assert meta["status"] == "syntax_error"
assert "line" in meta
assert "feedback" in meta
def test_conventions_detected(self):
code = "try:\n pass\nexcept ValueError:\n pass\ndef f(x: int) -> str:\n return str(x)"
meta = extract_metadata(code, "test.py", 0)
assert meta["conventions"]["uses_try_catch"] is True
assert meta["conventions"]["uses_type_hints"] is True
def test_no_print_detected(self):
code = "def f():\n print('hello')"
meta = extract_metadata(code, "test.py", 0)
assert meta["conventions"]["no_print_stmts"] is False
def test_language_set_correctly(self):
meta_py = extract_metadata("def f(): pass", "module.py", 0)
assert meta_py["language"] == "py"
if __name__ == "__main__":
pytest.main([__file__, "-v"])