#![cfg_attr(coverage_nightly, coverage(off))]
use crate::services::configuration_service::{
AnalysisConfig, ConfigurationService, McpConfig, PerformanceConfig, PmatConfig, QualityConfig,
SystemConfig, TelemetryConfig,
};
use std::path::PathBuf;
#[test]
fn test_default_config_creates_valid_config() {
let config = ConfigurationService::default_config();
assert!(!config.system.project_name.is_empty());
}
#[test]
fn test_default_config_system_defaults() {
let config = ConfigurationService::default_config();
assert_eq!(config.system.project_name, "pmat");
assert_eq!(config.system.output_dir, PathBuf::from("target/pmat"));
assert!(config.system.max_concurrent_operations > 0);
assert!(!config.system.verbose);
assert!(!config.system.debug);
assert_eq!(config.system.default_toolchain, "rust");
}
#[test]
fn test_default_config_quality_defaults() {
let config = ConfigurationService::default_config();
assert_eq!(config.quality.max_complexity, 30);
assert_eq!(config.quality.max_cognitive_complexity, 25);
assert!((config.quality.min_coverage - 80.0).abs() < f64::EPSILON);
assert!(!config.quality.allow_satd);
assert!(config.quality.require_docs);
assert!(config.quality.lint_compliance);
assert!(config.quality.fail_on_violation);
}
#[test]
fn test_default_config_analysis_defaults() {
let config = ConfigurationService::default_config();
assert!(!config.analysis.include_patterns.is_empty());
assert!(config
.analysis
.include_patterns
.contains(&"**/*.rs".to_string()));
assert!(config
.analysis
.include_patterns
.contains(&"**/*.ts".to_string()));
assert!(!config.analysis.exclude_patterns.is_empty());
assert!(config
.analysis
.exclude_patterns
.contains(&"**/target/**".to_string()));
assert!(config
.analysis
.exclude_patterns
.contains(&"**/node_modules/**".to_string()));
assert_eq!(config.analysis.max_file_size, 1024 * 1024); assert_eq!(config.analysis.max_line_length, 100);
assert!(config.analysis.skip_vendor);
assert!(config.analysis.parallel);
assert_eq!(config.analysis.thread_count, 0); assert_eq!(config.analysis.timeout_seconds, 300); }
#[test]
fn test_default_config_performance_defaults() {
let config = ConfigurationService::default_config();
assert!(config.performance.enable_regression_tests);
assert!(config.performance.enable_memory_tests);
assert!(config.performance.enable_throughput_tests);
assert_eq!(config.performance.test_iterations, 10);
assert_eq!(config.performance.timeout_ms, 30000);
assert_eq!(config.performance.target_startup_latency_ms, 127);
assert_eq!(config.performance.target_throughput_loc_per_sec, 487000);
assert_eq!(config.performance.target_memory_mb, 47);
}
#[test]
fn test_default_config_mcp_defaults() {
let config = ConfigurationService::default_config();
assert_eq!(config.mcp.server_name, "pmat-mcp-server");
assert!(!config.mcp.server_version.is_empty());
assert!(config.mcp.enable_compression);
assert_eq!(config.mcp.request_timeout_seconds, 30);
assert_eq!(config.mcp.max_request_size, 10 * 1024 * 1024); assert!(!config.mcp.log_requests);
assert!(!config.mcp.enabled_tools.is_empty());
assert!(config
.mcp
.enabled_tools
.contains(&"analyze_complexity".to_string()));
assert!(config
.mcp
.enabled_tools
.contains(&"analyze_dead_code".to_string()));
assert!(config
.mcp
.enabled_tools
.contains(&"quality_gate".to_string()));
assert!(config
.mcp
.enabled_tools
.contains(&"refactor_start".to_string()));
}
#[test]
fn test_default_config_roadmap_defaults() {
let config = ConfigurationService::default_config();
assert_eq!(
config.roadmap.roadmap_path,
PathBuf::from("docs/execution/roadmap.md")
);
assert!(config.roadmap.auto_generate_todos);
assert!(config.roadmap.enforce_quality_gates);
assert!(config.roadmap.require_task_ids);
assert_eq!(config.roadmap.task_id_pattern, "PMAT-[0-9]{4}");
assert!(config.roadmap.velocity_tracking);
assert!(config.roadmap.burndown_charts);
}
#[test]
fn test_default_config_git_defaults() {
let config = ConfigurationService::default_config();
assert!(
!config.roadmap.git.create_branches,
"Zero-branching policy must be enforced"
);
assert_eq!(config.roadmap.git.branch_pattern, "feature/{task_id}");
assert_eq!(config.roadmap.git.commit_pattern, "{task_id}: {message}");
assert!(config.roadmap.git.require_quality_check);
}
#[test]
fn test_default_config_telemetry_defaults() {
let config = ConfigurationService::default_config();
assert!(config.telemetry.enabled);
assert_eq!(config.telemetry.collection_interval_seconds, 60);
assert_eq!(config.telemetry.max_data_age_days, 30);
assert!(config.telemetry.enable_aggregation);
assert!(!config.telemetry.enable_export);
assert_eq!(config.telemetry.export_format, "json");
}
#[test]
fn test_default_config_semantic_defaults() {
let config = ConfigurationService::default_config();
assert!(!config.semantic.enabled);
assert!(config.semantic.vector_db_path.is_none());
assert!(config.semantic.workspace_path.is_none());
assert_eq!(config.semantic.embedding_model, "aprender-tfidf-local");
assert_eq!(config.semantic.embedding_dimensions, 256);
assert_eq!(config.semantic.default_search_mode, "hybrid");
assert_eq!(config.semantic.default_limit, 10);
assert!(!config.semantic.auto_sync);
assert_eq!(config.semantic.sync_interval_seconds, 300);
assert_eq!(config.semantic.max_chunk_tokens, 500);
assert!(!config.semantic.supported_languages.is_empty());
}
#[test]
fn test_default_config_custom_is_empty() {
let config = ConfigurationService::default_config();
assert!(config.custom.is_empty());
}
#[test]
fn test_pmat_config_serialization_roundtrip() {
let config = ConfigurationService::default_config();
let json = serde_json::to_string(&config).unwrap();
let deserialized: PmatConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.system.project_name, config.system.project_name);
assert_eq!(
deserialized.quality.max_complexity,
config.quality.max_complexity
);
assert_eq!(
deserialized.analysis.max_file_size,
config.analysis.max_file_size
);
}
#[test]
fn test_quality_config_serialization() {
let config = QualityConfig {
max_complexity: 25,
max_cognitive_complexity: 20,
min_coverage: 90.0,
allow_satd: true,
require_docs: false,
lint_compliance: true,
fail_on_violation: false,
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: QualityConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.max_complexity, 25);
assert_eq!(deserialized.max_cognitive_complexity, 20);
assert!((deserialized.min_coverage - 90.0).abs() < f64::EPSILON);
assert!(deserialized.allow_satd);
assert!(!deserialized.require_docs);
}
#[test]
fn test_analysis_config_serialization() {
let config = AnalysisConfig {
include_patterns: vec!["**/*.py".to_string()],
exclude_patterns: vec!["**/__pycache__/**".to_string()],
max_file_size: 500_000,
max_line_length: 120,
skip_vendor: false,
parallel: false,
thread_count: 4,
timeout_seconds: 60,
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: AnalysisConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.include_patterns, vec!["**/*.py".to_string()]);
assert_eq!(deserialized.max_file_size, 500_000);
assert_eq!(deserialized.thread_count, 4);
}
#[test]
fn test_performance_config_serialization() {
let config = PerformanceConfig {
enable_regression_tests: false,
enable_memory_tests: false,
enable_throughput_tests: true,
test_iterations: 5,
timeout_ms: 15000,
target_startup_latency_ms: 100,
target_throughput_loc_per_sec: 100000,
target_memory_mb: 64,
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: PerformanceConfig = serde_json::from_str(&json).unwrap();
assert!(!deserialized.enable_regression_tests);
assert!(deserialized.enable_throughput_tests);
assert_eq!(deserialized.target_memory_mb, 64);
}
#[test]
fn test_mcp_config_serialization() {
let config = McpConfig {
server_name: "test-server".to_string(),
server_version: "1.0.0".to_string(),
enable_compression: false,
request_timeout_seconds: 60,
max_request_size: 5_000_000,
log_requests: true,
enabled_tools: vec!["tool1".to_string(), "tool2".to_string()],
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: McpConfig = serde_json::from_str(&json).unwrap();
assert_eq!(deserialized.server_name, "test-server");
assert!(!deserialized.enable_compression);
assert!(deserialized.log_requests);
assert_eq!(deserialized.enabled_tools.len(), 2);
}
#[test]
fn test_telemetry_config_serialization() {
let config = TelemetryConfig {
enabled: false,
collection_interval_seconds: 120,
max_data_age_days: 7,
enable_aggregation: false,
enable_export: true,
export_format: "csv".to_string(),
};
let json = serde_json::to_string(&config).unwrap();
let deserialized: TelemetryConfig = serde_json::from_str(&json).unwrap();
assert!(!deserialized.enabled);
assert_eq!(deserialized.collection_interval_seconds, 120);
assert!(deserialized.enable_export);
assert_eq!(deserialized.export_format, "csv");
}
#[test]
fn test_quality_config_threshold_boundaries() {
let config = ConfigurationService::default_config();
assert!(config.quality.max_complexity > 0);
assert!(config.quality.max_cognitive_complexity > 0);
assert!(config.quality.min_coverage >= 0.0);
assert!(config.quality.min_coverage <= 100.0);
}
#[test]
fn test_analysis_config_reasonable_defaults() {
let config = ConfigurationService::default_config();
assert!(config.analysis.max_file_size >= 1024);
assert!(config.analysis.max_file_size <= 100 * 1024 * 1024);
assert!(config.analysis.max_line_length >= 40);
assert!(config.analysis.max_line_length <= 500);
assert!(config.analysis.timeout_seconds >= 1);
assert!(config.analysis.timeout_seconds <= 3600);
}
#[test]
fn test_performance_config_reasonable_defaults() {
let config = ConfigurationService::default_config();
assert!(config.performance.test_iterations >= 1);
assert!(config.performance.timeout_ms >= 1000);
assert!(config.performance.timeout_ms <= 600_000);
assert!(config.performance.target_startup_latency_ms > 0);
assert!(config.performance.target_throughput_loc_per_sec > 0);
assert!(config.performance.target_memory_mb > 0);
}
#[test]
fn test_mcp_config_reasonable_defaults() {
let config = ConfigurationService::default_config();
assert!(config.mcp.max_request_size >= 1024); assert!(config.mcp.max_request_size <= 100 * 1024 * 1024);
assert!(config.mcp.request_timeout_seconds >= 1);
assert!(config.mcp.request_timeout_seconds <= 300);
}
#[test]
fn test_semantic_config_reasonable_defaults() {
let config = ConfigurationService::default_config();
assert!(config.semantic.embedding_dimensions > 0);
assert!(config.semantic.embedding_dimensions <= 4096);
assert!(config.semantic.default_limit >= 1);
assert!(config.semantic.default_limit <= 100);
assert!(config.semantic.sync_interval_seconds >= 10);
assert!(config.semantic.max_chunk_tokens >= 100);
assert!(config.semantic.max_chunk_tokens <= 100_000);
}
#[test]
fn test_system_config_clone() {
let config = SystemConfig {
project_name: "test".to_string(),
project_path: PathBuf::from("/test"),
output_dir: PathBuf::from("/output"),
max_concurrent_operations: 8,
verbose: true,
debug: true,
default_toolchain: "python".to_string(),
};
let cloned = config.clone();
assert_eq!(cloned.project_name, config.project_name);
assert_eq!(
cloned.max_concurrent_operations,
config.max_concurrent_operations
);
}
#[test]
fn test_system_config_debug_format() {
let config = SystemConfig {
project_name: "test".to_string(),
project_path: PathBuf::from("/test"),
output_dir: PathBuf::from("/output"),
max_concurrent_operations: 8,
verbose: false,
debug: false,
default_toolchain: "rust".to_string(),
};
let debug_str = format!("{:?}", config);
assert!(debug_str.contains("test"));
assert!(debug_str.contains("rust"));
}
#[test]
fn test_roadmap_config_task_id_pattern_is_valid_regex() {
let config = ConfigurationService::default_config();
let result = regex::Regex::new(&config.roadmap.task_id_pattern);
assert!(result.is_ok(), "Task ID pattern should be valid regex");
let regex = result.unwrap();
assert!(regex.is_match("PMAT-1234"));
assert!(regex.is_match("PMAT-0001"));
assert!(regex.is_match("PMAT-9999"));
assert!(regex.is_match("PMAT-12345")); assert!(!regex.is_match("PMAT-123")); assert!(!regex.is_match("INVALID")); }
#[test]
fn test_roadmap_git_config_patterns() {
let config = ConfigurationService::default_config();
assert!(config.roadmap.git.branch_pattern.contains("{task_id}"));
assert!(config.roadmap.git.commit_pattern.contains("{task_id}"));
assert!(config.roadmap.git.commit_pattern.contains("{message}"));
}