209 lines
5.7 KiB
Python
209 lines
5.7 KiB
Python
import tempfile
|
|
import json
|
|
from pathlib import Path
|
|
from src.parsers.python import PythonParser
|
|
from src.parsers.javascript import JavaScriptParser
|
|
from src.graph.builder import GraphBuilder, GraphType
|
|
from src.analyzers.complexity import ComplexityCalculator
|
|
from src.exporters.json_exporter import JSONExporter
|
|
|
|
|
|
class TestFullWorkflow:
|
|
def test_python_file_analysis(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_file = Path(tmpdir) / "test.py"
|
|
test_file.write_text("""
|
|
def hello(name):
|
|
if name:
|
|
print(f"Hello, {name}")
|
|
else:
|
|
print("Hello, World")
|
|
|
|
class Greeter:
|
|
def __init__(self, prefix):
|
|
self.prefix = prefix
|
|
|
|
def greet(self, name):
|
|
if self.prefix and name:
|
|
return f"{self.prefix} {name}"
|
|
return "Hello"
|
|
""")
|
|
|
|
parser = PythonParser()
|
|
content = test_file.read_text()
|
|
result = parser.parse(test_file, content)
|
|
|
|
assert result.language == "python"
|
|
assert len(result.entities) >= 2
|
|
assert any(e.name == "hello" for e in result.entities)
|
|
assert any(e.name == "Greeter" for e in result.entities)
|
|
|
|
def test_javascript_file_analysis(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_file = Path(tmpdir) / "test.js"
|
|
test_file.write_text("""
|
|
function calculate(a, b) {
|
|
if (a > 0 && b > 0) {
|
|
return a + b;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
class Calculator {
|
|
constructor() {
|
|
this.value = 0;
|
|
}
|
|
|
|
add(num) {
|
|
this.value += num;
|
|
return this.value;
|
|
}
|
|
}
|
|
""")
|
|
|
|
parser = JavaScriptParser()
|
|
content = test_file.read_text()
|
|
result = parser.parse(test_file, content)
|
|
|
|
assert result.language == "javascript"
|
|
assert len(result.entities) >= 2
|
|
|
|
def test_graph_construction(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
file1 = Path(tmpdir) / "main.py"
|
|
file1.write_text("""
|
|
from utils import helper
|
|
|
|
def main():
|
|
helper()
|
|
""")
|
|
|
|
file2 = Path(tmpdir) / "utils.py"
|
|
file2.write_text("""
|
|
def helper():
|
|
print("Helper")
|
|
""")
|
|
|
|
builder = GraphBuilder(GraphType.DIRECTED)
|
|
|
|
parser = PythonParser()
|
|
results = []
|
|
for file_path in [file1, file2]:
|
|
content = file_path.read_text()
|
|
result = parser.parse(file_path, content)
|
|
results.append(result)
|
|
|
|
builder.build_from_parser_results(results)
|
|
nodes = builder.get_nodes()
|
|
|
|
assert len(nodes) >= 2
|
|
|
|
def test_complexity_calculation(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_file = Path(tmpdir) / "test.py"
|
|
test_file.write_text("""
|
|
def complex_function(x, y, z):
|
|
if x > 0:
|
|
if y > 0:
|
|
for i in range(z):
|
|
if i % 2 == 0:
|
|
print(i)
|
|
return True
|
|
""")
|
|
|
|
parser = PythonParser()
|
|
content = test_file.read_text()
|
|
result = parser.parse(test_file, content)
|
|
|
|
calculator = ComplexityCalculator()
|
|
|
|
for entity in result.entities:
|
|
complexity = calculator.calculate_for_entity(entity)
|
|
assert complexity["complexity_score"] >= 1
|
|
|
|
def test_json_export(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_file = Path(tmpdir) / "test.py"
|
|
test_file.write_text("""
|
|
def simple():
|
|
pass
|
|
""")
|
|
|
|
parser = PythonParser()
|
|
content = test_file.read_text()
|
|
result = parser.parse(test_file, content)
|
|
|
|
builder = GraphBuilder(GraphType.DIRECTED)
|
|
builder.build_from_parser_results([result])
|
|
|
|
exporter = JSONExporter(builder)
|
|
|
|
output_file = Path(tmpdir) / "output.json"
|
|
exporter.export(output_file)
|
|
|
|
assert output_file.exists()
|
|
data = json.loads(output_file.read_text())
|
|
assert "nodes" in data
|
|
assert "edges" in data
|
|
|
|
def test_multi_file_project_analysis(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
(Path(tmpdir) / "main.py").write_text("""
|
|
from module_a import func_a
|
|
from module_b import func_b
|
|
|
|
def main():
|
|
func_a()
|
|
func_b()
|
|
""")
|
|
|
|
(Path(tmpdir) / "module_a.py").write_text("""
|
|
def func_a():
|
|
pass
|
|
|
|
class ClassA:
|
|
pass
|
|
""")
|
|
|
|
(Path(tmpdir) / "module_b.py").write_text("""
|
|
def func_b():
|
|
pass
|
|
""")
|
|
|
|
parser = PythonParser()
|
|
results = []
|
|
|
|
for py_file in Path(tmpdir).glob("*.py"):
|
|
content = py_file.read_text()
|
|
result = parser.parse(py_file, content)
|
|
results.append(result)
|
|
|
|
builder = GraphBuilder(GraphType.DIRECTED)
|
|
builder.build_from_parser_results(results)
|
|
|
|
nodes = builder.get_nodes()
|
|
assert len(nodes) >= 3
|
|
|
|
file_nodes = [n for n in nodes if n.node_type.value == "file"]
|
|
func_nodes = [n for n in nodes if n.node_type.value == "function"]
|
|
|
|
assert len(file_nodes) == 3
|
|
assert len(func_nodes) >= 3
|
|
|
|
def test_error_handling_invalid_file(self):
|
|
parser = PythonParser()
|
|
result = parser.parse(Path("/nonexistent/file.py"), "")
|
|
|
|
assert result.errors is not None
|
|
|
|
def test_empty_code_handling(self):
|
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
test_file = Path(tmpdir) / "empty.py"
|
|
test_file.write_text("# Just a comment\n")
|
|
|
|
parser = PythonParser()
|
|
content = test_file.read_text()
|
|
result = parser.parse(test_file, content)
|
|
|
|
assert result.language == "python"
|