code2llm 0.5.112__tar.gz → 0.5.113__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {code2llm-0.5.112 → code2llm-0.5.113}/PKG-INFO +2 -2
- {code2llm-0.5.112 → code2llm-0.5.113}/README.md +1 -1
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/__init__.py +1 -1
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/__init__.py +1 -1
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/PKG-INFO +2 -2
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/SOURCES.txt +1 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/pyproject.toml +1 -1
- {code2llm-0.5.112 → code2llm-0.5.113}/setup.py +1 -1
- code2llm-0.5.113/tests/test_calls_toon_export.py +241 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/LICENSE +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/__main__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/call_graph.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/cfg.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/coupling.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/data_analysis.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/dfg.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/pipeline_detector.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/side_effects.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/smells.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/type_inference.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/utils/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/analysis/utils/ast_helpers.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/api.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_analysis.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_commands.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_exports/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_exports/code2logic.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_exports/formats.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_exports/orchestrator.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_exports/prompt.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/cli_parser.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/analyzer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/ast_registry.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/config.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/export_pipeline.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/file_analyzer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/file_cache.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/file_filter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/gitignore.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/incremental.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/base.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/cpp.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/csharp.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/generic.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/go_lang.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/java.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/php.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/ruby.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/rust.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/ts_extractors.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/ts_parser.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/lang/typescript.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/large_repo.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/models.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/refactoring.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/repo_files.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/cache.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/incremental.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/prioritizer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/scanner.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming/strategies.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/streaming_analyzer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/core/toon_size_manager.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/article_view.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/base.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/context_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/context_view.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/evolution_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/flow_constants.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/flow_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/flow_renderer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/html_dashboard.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/index_generator.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/json_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/llm_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/map_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/mermaid_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/mermaid_flow_helpers.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/constants.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/core.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/evolution.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/health.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/hotspots.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml/modules.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/project_yaml_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/readme_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/report_generators.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon/helpers.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon/metrics.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon/module_detail.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon/renderer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/toon_view.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/validate_project.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/exporters/yaml_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/generators/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/generators/llm_flow.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/generators/llm_task.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/generators/mermaid.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/config.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/entity_resolution.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/intent_matching.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/normalization.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/nlp/pipeline.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/patterns/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/patterns/detector.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/refactor/__init__.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm/refactor/prompt_engine.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/dependency_links.txt +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/entry_points.txt +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/requires.txt +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/code2llm.egg-info/top_level.txt +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/setup.cfg +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_advanced_analysis.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_analyzer.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_deep_analysis.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_edge_cases.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_flow_exporter.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_format_quality.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_multilanguage_e2e.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_nlp_pipeline.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_nonpython_cc_calls.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_pipeline_detector.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_project_toon_export.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_prompt_engine.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_prompt_txt.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_refactoring_engine.py +0 -0
- {code2llm-0.5.112 → code2llm-0.5.113}/tests/test_toon_v2.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2llm
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.113
|
|
4
4
|
Summary: High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries
|
|
5
5
|
Home-page: https://github.com/wronai/stts
|
|
6
6
|
Author: STTS Project
|
|
@@ -67,7 +67,7 @@ Dynamic: requires-python
|
|
|
67
67
|
|
|
68
68
|
## AI Cost Tracking
|
|
69
69
|
|
|
70
|
-
    
|
|
71
71
|
  
|
|
72
72
|
|
|
73
73
|
- 🤖 **LLM usage:** $7.5000 (162 commits)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
## AI Cost Tracking
|
|
5
5
|
|
|
6
|
-
    
|
|
7
7
|
  
|
|
8
8
|
|
|
9
9
|
- 🤖 **LLM usage:** $7.5000 (162 commits)
|
|
@@ -8,7 +8,7 @@ Includes NLP Processing Pipeline for query normalization, intent matching,
|
|
|
8
8
|
and entity resolution with multilingual support.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = "0.5.
|
|
11
|
+
__version__ = "0.5.113"
|
|
12
12
|
__author__ = "STTS Project"
|
|
13
13
|
|
|
14
14
|
# Core analysis components (lightweight, always needed)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2llm
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.113
|
|
4
4
|
Summary: High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries
|
|
5
5
|
Home-page: https://github.com/wronai/stts
|
|
6
6
|
Author: STTS Project
|
|
@@ -67,7 +67,7 @@ Dynamic: requires-python
|
|
|
67
67
|
|
|
68
68
|
## AI Cost Tracking
|
|
69
69
|
|
|
70
|
-
    
|
|
71
71
|
  
|
|
72
72
|
|
|
73
73
|
- 🤖 **LLM usage:** $7.5000 (162 commits)
|
|
@@ -118,6 +118,7 @@ code2llm/refactor/__init__.py
|
|
|
118
118
|
code2llm/refactor/prompt_engine.py
|
|
119
119
|
tests/test_advanced_analysis.py
|
|
120
120
|
tests/test_analyzer.py
|
|
121
|
+
tests/test_calls_toon_export.py
|
|
121
122
|
tests/test_deep_analysis.py
|
|
122
123
|
tests/test_edge_cases.py
|
|
123
124
|
tests/test_flow_exporter.py
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code2llm"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.113"
|
|
8
8
|
description = "High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""Tests for calls.toon.yaml export functionality."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest.mock import MagicMock
|
|
5
|
+
|
|
6
|
+
from code2llm.core.models import AnalysisResult, FunctionInfo, ClassInfo
|
|
7
|
+
from code2llm.exporters.yaml_exporter import YAMLExporter
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_export_calls_toon_generates_file(tmp_path):
|
|
11
|
+
"""Test that export_calls_toon generates a valid toon format file."""
|
|
12
|
+
# Create a mock result with some functions and calls
|
|
13
|
+
result = MagicMock(spec=AnalysisResult)
|
|
14
|
+
result.project_path = "."
|
|
15
|
+
|
|
16
|
+
# Add some mock functions
|
|
17
|
+
func1 = MagicMock(spec=FunctionInfo)
|
|
18
|
+
func1.name = "func1"
|
|
19
|
+
func1.module = "module1"
|
|
20
|
+
func1.line = 10
|
|
21
|
+
func1.complexity = {"cyclomatic_complexity": 5}
|
|
22
|
+
func1.calls = ["func2", "func3"]
|
|
23
|
+
|
|
24
|
+
func2 = MagicMock(spec=FunctionInfo)
|
|
25
|
+
func2.name = "func2"
|
|
26
|
+
func2.module = "module1"
|
|
27
|
+
func2.line = 20
|
|
28
|
+
func2.complexity = {"cyclomatic_complexity": 3}
|
|
29
|
+
func2.calls = []
|
|
30
|
+
|
|
31
|
+
func3 = MagicMock(spec=FunctionInfo)
|
|
32
|
+
func3.name = "func3"
|
|
33
|
+
func3.module = "module2"
|
|
34
|
+
func3.line = 30
|
|
35
|
+
func3.complexity = {"cyclomatic_complexity": 2}
|
|
36
|
+
func3.calls = []
|
|
37
|
+
|
|
38
|
+
result.functions = {
|
|
39
|
+
"module1.func1": func1,
|
|
40
|
+
"module1.func2": func2,
|
|
41
|
+
"module2.func3": func3,
|
|
42
|
+
}
|
|
43
|
+
result.classes = {}
|
|
44
|
+
result.entry_points = ["module1.func1"]
|
|
45
|
+
|
|
46
|
+
# Export
|
|
47
|
+
exporter = YAMLExporter()
|
|
48
|
+
output_path = tmp_path / "calls.toon.yaml"
|
|
49
|
+
exporter.export_calls_toon(result, str(output_path))
|
|
50
|
+
|
|
51
|
+
# Verify file exists
|
|
52
|
+
assert output_path.exists()
|
|
53
|
+
|
|
54
|
+
# Verify content
|
|
55
|
+
content = output_path.read_text(encoding="utf-8")
|
|
56
|
+
assert "# code2llm call graph" in content
|
|
57
|
+
assert "HUBS[" in content
|
|
58
|
+
assert "MODULES:" in content
|
|
59
|
+
assert "EDGES:" in content
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_export_calls_toon_hubs_section(tmp_path):
|
|
63
|
+
"""Test that HUBS section contains high-degree functions sorted by total calls."""
|
|
64
|
+
result = MagicMock(spec=AnalysisResult)
|
|
65
|
+
result.project_path = "."
|
|
66
|
+
|
|
67
|
+
# Create functions with different call patterns
|
|
68
|
+
func_hub = MagicMock(spec=FunctionInfo)
|
|
69
|
+
func_hub.name = "hub_func"
|
|
70
|
+
func_hub.module = "module1"
|
|
71
|
+
func_hub.line = 10
|
|
72
|
+
func_hub.complexity = {"cyclomatic_complexity": 10}
|
|
73
|
+
func_hub.calls = ["func2", "func3", "func4", "func5"] # 4 outgoing calls
|
|
74
|
+
|
|
75
|
+
func2 = MagicMock(spec=FunctionInfo)
|
|
76
|
+
func2.name = "func2"
|
|
77
|
+
func2.module = "module1"
|
|
78
|
+
func2.line = 20
|
|
79
|
+
func2.complexity = {"cyclomatic_complexity": 2}
|
|
80
|
+
func2.calls = []
|
|
81
|
+
|
|
82
|
+
func3 = MagicMock(spec=FunctionInfo)
|
|
83
|
+
func3.name = "func3"
|
|
84
|
+
func3.module = "module2"
|
|
85
|
+
func3.line = 30
|
|
86
|
+
func3.complexity = {"cyclomatic_complexity": 1}
|
|
87
|
+
func3.calls = []
|
|
88
|
+
|
|
89
|
+
func4 = MagicMock(spec=FunctionInfo)
|
|
90
|
+
func4.name = "func4"
|
|
91
|
+
func4.module = "module3"
|
|
92
|
+
func4.line = 40
|
|
93
|
+
func4.complexity = {"cyclomatic_complexity": 1}
|
|
94
|
+
func4.calls = []
|
|
95
|
+
|
|
96
|
+
func5 = MagicMock(spec=FunctionInfo)
|
|
97
|
+
func5.name = "func5"
|
|
98
|
+
func5.module = "module4"
|
|
99
|
+
func5.line = 50
|
|
100
|
+
func5.complexity = {"cyclomatic_complexity": 1}
|
|
101
|
+
func5.calls = []
|
|
102
|
+
|
|
103
|
+
result.functions = {
|
|
104
|
+
"module1.hub_func": func_hub,
|
|
105
|
+
"module1.func2": func2,
|
|
106
|
+
"module2.func3": func3,
|
|
107
|
+
"module3.func4": func4,
|
|
108
|
+
"module4.func5": func5,
|
|
109
|
+
}
|
|
110
|
+
result.classes = {}
|
|
111
|
+
result.entry_points = []
|
|
112
|
+
|
|
113
|
+
exporter = YAMLExporter()
|
|
114
|
+
output_path = tmp_path / "calls.toon.yaml"
|
|
115
|
+
exporter.export_calls_toon(result, str(output_path))
|
|
116
|
+
|
|
117
|
+
content = output_path.read_text(encoding="utf-8")
|
|
118
|
+
assert "HUBS[" in content
|
|
119
|
+
assert "hub_func" in content
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def test_export_calls_toon_modules_section(tmp_path):
|
|
123
|
+
"""Test that MODULES section groups functions by module."""
|
|
124
|
+
result = MagicMock(spec=AnalysisResult)
|
|
125
|
+
result.project_path = "."
|
|
126
|
+
|
|
127
|
+
func1 = MagicMock(spec=FunctionInfo)
|
|
128
|
+
func1.name = "func1"
|
|
129
|
+
func1.module = "module_a"
|
|
130
|
+
func1.line = 10
|
|
131
|
+
func1.complexity = {"cyclomatic_complexity": 3}
|
|
132
|
+
func1.calls = ["func2", "func3"]
|
|
133
|
+
|
|
134
|
+
func2 = MagicMock(spec=FunctionInfo)
|
|
135
|
+
func2.name = "func2"
|
|
136
|
+
func2.module = "module_a"
|
|
137
|
+
func2.line = 20
|
|
138
|
+
func2.complexity = {"cyclomatic_complexity": 2}
|
|
139
|
+
func2.calls = []
|
|
140
|
+
|
|
141
|
+
func3 = MagicMock(spec=FunctionInfo)
|
|
142
|
+
func3.name = "func3"
|
|
143
|
+
func3.module = "module_b"
|
|
144
|
+
func3.line = 30
|
|
145
|
+
func3.complexity = {"cyclomatic_complexity": 4}
|
|
146
|
+
func3.calls = []
|
|
147
|
+
|
|
148
|
+
result.functions = {
|
|
149
|
+
"module_a.func1": func1,
|
|
150
|
+
"module_a.func2": func2,
|
|
151
|
+
"module_b.func3": func3,
|
|
152
|
+
}
|
|
153
|
+
result.classes = {}
|
|
154
|
+
result.entry_points = []
|
|
155
|
+
|
|
156
|
+
exporter = YAMLExporter()
|
|
157
|
+
output_path = tmp_path / "calls.toon.yaml"
|
|
158
|
+
exporter.export_calls_toon(result, str(output_path))
|
|
159
|
+
|
|
160
|
+
content = output_path.read_text(encoding="utf-8")
|
|
161
|
+
assert "MODULES:" in content
|
|
162
|
+
assert "module_a" in content
|
|
163
|
+
assert "module_b" in content
|
|
164
|
+
assert "[2 funcs]" in content or "[1 func]" in content
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def test_export_calls_toon_edges_section(tmp_path):
|
|
168
|
+
"""Test that EDGES section contains caller -> callee relationships."""
|
|
169
|
+
result = MagicMock(spec=AnalysisResult)
|
|
170
|
+
result.project_path = "."
|
|
171
|
+
|
|
172
|
+
caller = MagicMock(spec=FunctionInfo)
|
|
173
|
+
caller.name = "caller"
|
|
174
|
+
caller.module = "module1"
|
|
175
|
+
caller.line = 10
|
|
176
|
+
caller.complexity = {"cyclomatic_complexity": 2}
|
|
177
|
+
caller.calls = ["callee"]
|
|
178
|
+
|
|
179
|
+
callee = MagicMock(spec=FunctionInfo)
|
|
180
|
+
callee.name = "callee"
|
|
181
|
+
callee.module = "module1"
|
|
182
|
+
callee.line = 20
|
|
183
|
+
callee.complexity = {"cyclomatic_complexity": 1}
|
|
184
|
+
callee.calls = []
|
|
185
|
+
|
|
186
|
+
result.functions = {
|
|
187
|
+
"module1.caller": caller,
|
|
188
|
+
"module1.callee": callee,
|
|
189
|
+
}
|
|
190
|
+
result.classes = {}
|
|
191
|
+
result.entry_points = []
|
|
192
|
+
|
|
193
|
+
exporter = YAMLExporter()
|
|
194
|
+
output_path = tmp_path / "calls.toon.yaml"
|
|
195
|
+
exporter.export_calls_toon(result, str(output_path))
|
|
196
|
+
|
|
197
|
+
content = output_path.read_text(encoding="utf-8")
|
|
198
|
+
assert "EDGES:" in content
|
|
199
|
+
assert "→" in content
|
|
200
|
+
assert "caller" in content
|
|
201
|
+
assert "callee" in content
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def test_export_calls_toon_header_stats(tmp_path):
|
|
205
|
+
"""Test that header contains correct statistics."""
|
|
206
|
+
result = MagicMock(spec=AnalysisResult)
|
|
207
|
+
result.project_path = "."
|
|
208
|
+
|
|
209
|
+
func1 = MagicMock(spec=FunctionInfo)
|
|
210
|
+
func1.name = "func1"
|
|
211
|
+
func1.module = "module1"
|
|
212
|
+
func1.line = 10
|
|
213
|
+
func1.complexity = {"cyclomatic_complexity": 5}
|
|
214
|
+
func1.calls = ["func2"]
|
|
215
|
+
|
|
216
|
+
func2 = MagicMock(spec=FunctionInfo)
|
|
217
|
+
func2.name = "func2"
|
|
218
|
+
func2.module = "module1"
|
|
219
|
+
func2.line = 20
|
|
220
|
+
func2.complexity = {"cyclomatic_complexity": 3}
|
|
221
|
+
func2.calls = []
|
|
222
|
+
|
|
223
|
+
result.functions = {
|
|
224
|
+
"module1.func1": func1,
|
|
225
|
+
"module1.func2": func2,
|
|
226
|
+
}
|
|
227
|
+
result.classes = {}
|
|
228
|
+
result.entry_points = []
|
|
229
|
+
|
|
230
|
+
exporter = YAMLExporter()
|
|
231
|
+
output_path = tmp_path / "calls.toon.yaml"
|
|
232
|
+
exporter.export_calls_toon(result, str(output_path))
|
|
233
|
+
|
|
234
|
+
content = output_path.read_text(encoding="utf-8")
|
|
235
|
+
# Check header lines
|
|
236
|
+
lines = content.split('\n')[:5]
|
|
237
|
+
assert any("# code2llm call graph" in line for line in lines)
|
|
238
|
+
assert any("nodes:" in line for line in lines)
|
|
239
|
+
assert any("edges:" in line for line in lines)
|
|
240
|
+
assert any("modules:" in line for line in lines)
|
|
241
|
+
assert any("CC̄=" in line for line in lines)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|