use crate::services::simple_deep_context::{SimpleAnalysisConfig, SimpleDeepContext};
use std::fs;
use tempfile::TempDir;
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod extreme_tdd_tests {
use super::*;
#[tokio::test]
async fn red_test_unified_context_must_show_functions() {
let temp_dir = TempDir::new().unwrap();
let ts_content = "function testFunction() { return 42; }";
let ts_file = temp_dir.path().join("test.ts");
fs::write(&ts_file, ts_content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec![], exclude_patterns: vec![],
enable_verbose: false,
};
let analysis_result = analyzer.analyze(config).await.unwrap();
assert!(
analysis_result.complexity_metrics.total_functions >= 1,
"Unified context failed to extract functions! Found: {}",
analysis_result.complexity_metrics.total_functions
);
}
#[tokio::test]
async fn green_test_unified_context_handles_multiple_languages() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("test.rs"), "fn rust_func() {}").unwrap();
fs::write(temp_dir.path().join("test.ts"), "function tsFunc() {}").unwrap();
fs::write(temp_dir.path().join("test.js"), "function jsFunc() {}").unwrap();
fs::write(
temp_dir.path().join("test.py"),
"def python_func():\n pass",
)
.unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec![
"**/*.rs".to_string(),
"**/*.ts".to_string(),
"**/*.js".to_string(),
"**/*.py".to_string(),
],
exclude_patterns: vec![],
enable_verbose: false,
};
let analysis_result = analyzer.analyze(config).await.unwrap();
assert!(
analysis_result.file_count >= 4,
"Should detect all language files"
);
assert!(
analysis_result.complexity_metrics.total_functions >= 4,
"Should detect functions in all languages"
);
}
#[tokio::test]
async fn refactor_test_context_consistency() {
let temp_dir = TempDir::new().unwrap();
fs::write(temp_dir.path().join("test.ts"), "function test() {}").unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.ts".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
let result1 = analyzer.analyze(config.clone()).await.unwrap();
let result2 = analyzer.analyze(config).await.unwrap();
assert_eq!(
result1.file_count, result2.file_count,
"File count should be consistent across runs"
);
assert_eq!(
result1.complexity_metrics.total_functions, result2.complexity_metrics.total_functions,
"Function count should be consistent across runs"
);
}
#[tokio::test]
#[cfg(feature = "wasm-ast")]
async fn test_wasm_function_extraction() {
let temp_dir = TempDir::new().unwrap();
let wasm_content = r#"(module
(func $add (param $a i32) (param $b i32) (result i32)
local.get $a
local.get $b
i32.add
)
(export "add" (func $add))
)"#;
fs::write(temp_dir.path().join("test.wat"), wasm_content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.wat".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
let analysis_result = analyzer.analyze(config).await.unwrap();
assert!(analysis_result.file_count >= 1, "Should detect WASM file");
assert!(
analysis_result.complexity_metrics.total_functions >= 1,
"Should detect WASM functions"
);
}
#[tokio::test]
async fn test_javascript_descriptive_names() {
let temp_dir = TempDir::new().unwrap();
let js_content = r#"
function calculateTotal() {
return 42;
}
const processData = () => {
return "processed";
};
class UserService {
createUser() {
return {};
}
static validateUser() {
return true;
}
}
const utils = {
formatMessage() {
return "formatted";
}
};
"#;
fs::write(temp_dir.path().join("test.js"), js_content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.js".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
let analysis_result = analyzer.analyze(config).await.unwrap();
assert!(analysis_result.complexity_metrics.total_functions >= 5,
"Should detect all JavaScript functions: calculateTotal, processData, createUser, validateUser, formatMessage. Found: {}",
analysis_result.complexity_metrics.total_functions);
}
#[tokio::test]
async fn test_typescript_interface_detection() {
let temp_dir = TempDir::new().unwrap();
let ts_content = r#"
interface User {
id: number;
name: string;
getProfile(): UserProfile;
}
enum Status {
Active,
Inactive,
Pending
}
function processUser(user: User): Status {
return Status.Active;
}
class UserManager {
updateUser(user: User): void {
// implementation
}
}
"#;
fs::write(temp_dir.path().join("test.ts"), ts_content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.ts".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
let analysis_result = analyzer.analyze(config).await.unwrap();
assert!(
analysis_result.complexity_metrics.total_functions >= 2,
"Should detect TypeScript functions: processUser, updateUser. Found: {}",
analysis_result.complexity_metrics.total_functions
);
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn property_function_count_non_negative(content in ".+") {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let temp_dir = TempDir::new().unwrap();
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, &content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.ts".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
let _ = analyzer.analyze(config).await;
});
}
#[test]
fn property_analysis_deterministic(valid_function in "[a-zA-Z][a-zA-Z0-9]{1,20}") {
let rt = tokio::runtime::Runtime::new().unwrap();
rt.block_on(async {
let temp_dir = TempDir::new().unwrap();
let content = format!(
"function {}() {{ return 42; }}",
valid_function
);
let file_path = temp_dir.path().join("test.ts");
fs::write(&file_path, &content).unwrap();
let analyzer = SimpleDeepContext::new();
let config = SimpleAnalysisConfig {
project_path: temp_dir.path().to_path_buf(),
include_features: vec![],
include_patterns: vec!["**/*.ts".to_string()],
exclude_patterns: vec![],
enable_verbose: false,
};
if let (Ok(result1), Ok(result2)) = (
analyzer.analyze(config.clone()).await,
analyzer.analyze(config).await,
) {
assert_eq!(
result1.complexity_metrics.total_functions,
result2.complexity_metrics.total_functions,
);
}
});
}
}
}