feat: add C/C++ language support and analysis

refactor: improve architecture for maintainability
build: update development status to production
docs: enhance README with language support details
docs: add C/C++ development support documentation
docs: add entry points documentation
test: add comprehensive test suite (545+ tests)
refactor: rename asynchronous to modular architecture
fix: resolve dependency resolution issues
perf: improve dependency resolution performance
This commit is contained in:
2025-12-13 06:30:08 +01:00
parent aaae444ee6
commit 5b3a934a32
8 changed files with 1115 additions and 225 deletions
+301 -1
View File
@@ -1,3 +1,5 @@
# retoor <retoor@molodetz.nl>
import pytest
from rp.core.project_analyzer import ProjectAnalyzer, AnalysisResult
@@ -22,6 +24,7 @@ class User(BaseModel):
)
assert isinstance(result, AnalysisResult)
assert result.language == 'python'
assert 'requests' in result.dependencies
assert 'pydantic' in result.dependencies
@@ -78,7 +81,7 @@ if (x := 10) > 5:
code_content=code_with_walrus,
)
version_parts = result.python_version.split('.')
version_parts = result.language_version.split('.')
assert int(version_parts[1]) >= 8
def test_directory_structure_planning(self):
@@ -154,3 +157,300 @@ from fastapi.middleware.gzip import GZIPMiddleware
assert not result.valid
assert any('GZIPMiddleware' in str(e) or 'fastapi' in str(e).lower() for e in result.errors)
class TestCLanguageAnalyzer:
def setup_method(self):
self.analyzer = ProjectAnalyzer()
def test_detect_c_language(self):
c_code = """
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Hello, World!\\n");
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert result.language == 'c'
def test_c_standard_headers_detection(self):
c_code = """
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int main() {
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert 'stdio.h' in result.dependencies
assert result.dependencies['stdio.h'] == 'stdlib'
assert result.dependencies['math.h'] == 'stdlib'
def test_c_posix_headers_detection(self):
c_code = """
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>
int main() {
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert 'unistd.h' in result.dependencies
assert result.dependencies['unistd.h'] == 'posix'
assert any('POSIX' in w for w in result.warnings)
def test_c_local_headers_detection(self):
c_code = """
#include <stdio.h>
#include "myheader.h"
#include "utils/helper.h"
int main() {
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert 'myheader.h' in result.dependencies
assert result.dependencies['myheader.h'] == 'local'
def test_c_external_library_headers(self):
c_code = """
#include <stdio.h>
#include <curl/curl.h>
#include <openssl/ssl.h>
int main() {
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert 'curl/curl.h' in result.dependencies
assert result.dependencies['curl/curl.h'] == 'curl'
assert any('curl' in w for w in result.warnings)
def test_c_standard_detection_c99(self):
c_code = """
#include <stdio.h>
int main() {
for (int i = 0; i < 10; i++) {
printf("%d\\n", i);
}
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert result.language_version == 'c99'
def test_c_standard_detection_c11(self):
c_code = """
#include <stdio.h>
#include <stdatomic.h>
int main() {
_Static_assert(sizeof(int) >= 4, "int must be at least 4 bytes");
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert result.language_version == 'c11'
def test_c_standard_detection_gnu(self):
c_code = """
#include <stdio.h>
int main() {
typeof(5) x = 10;
printf("%d\\n", x);
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert 'gnu' in result.language_version
def test_c_compiler_flags_suggestion(self):
c_code = """
#include <stdio.h>
#include <math.h>
#include <pthread.h>
int main() {
pthread_t thread;
double x = sqrt(2.0);
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert '-lm' in result.compiler_flags
assert '-pthread' in result.compiler_flags
assert any('-std=' in f for f in result.compiler_flags)
assert '-Wall' in result.compiler_flags
def test_c_valid_analysis_no_errors(self):
c_code = """
#include <stdio.h>
int main() {
printf("Hello\\n");
return 0;
}
"""
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
)
assert result.valid
assert len(result.errors) == 0
def test_c_shell_commands_validation(self):
c_code = """
#include <stdio.h>
int main() { return 0; }
"""
commands = [
"gcc -o main main.c",
"make clean",
"./main",
]
result = self.analyzer.analyze_requirements(
spec_file="main.c",
code_content=c_code,
commands=commands,
)
valid_commands = [c for c in result.shell_commands if c['valid']]
assert len(valid_commands) == 3
class TestLanguageDetection:
def setup_method(self):
self.analyzer = ProjectAnalyzer()
def test_detect_python_from_content(self):
python_code = """
def hello():
print("Hello, World!")
if __name__ == "__main__":
hello()
"""
lang = self.analyzer.detect_language(python_code)
assert lang == 'python'
def test_detect_c_from_content(self):
c_code = """
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Hello\\n");
return 0;
}
"""
lang = self.analyzer.detect_language(c_code)
assert lang == 'c'
def test_detect_cpp_from_content(self):
cpp_code = """
#include <iostream>
int main() {
std::cout << "Hello" << std::endl;
return 0;
}
"""
lang = self.analyzer.detect_language(cpp_code)
assert lang == 'cpp'
def test_detect_rust_from_content(self):
rust_code = """
fn main() {
let x = 5;
println!("x = {}", x);
}
"""
lang = self.analyzer.detect_language(rust_code)
assert lang == 'rust'
def test_detect_go_from_content(self):
go_code = """
package main
import "fmt"
func main() {
fmt.Println("Hello")
}
"""
lang = self.analyzer.detect_language(go_code)
assert lang == 'go'
def test_detect_javascript_from_content(self):
js_code = """
const express = require('express');
function hello() {
console.log("Hello");
}
export default hello;
"""
lang = self.analyzer.detect_language(js_code)
assert lang == 'javascript'
def test_detect_language_from_file_extension(self):
lang = self.analyzer.detect_language("", "main.c")
assert lang == 'c'
lang = self.analyzer.detect_language("", "app.py")
assert lang == 'python'
def test_detect_unknown_language(self):
weird_content = "some random text without any language patterns"
lang = self.analyzer.detect_language(weird_content)
assert lang == 'unknown'