Spaces:
Sleeping
Sleeping
| """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"]) | |