Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
267 lines
7.2 KiB
Rust
267 lines
7.2 KiB
Rust
//! Comprehensive integration tests for syntaxis
|
|
//!
|
|
//! Tests the full stack from database to API to CLI.
|
|
|
|
#[cfg(test)]
|
|
mod integration_tests {
|
|
use std::collections::HashMap;
|
|
|
|
/// Test project creation and retrieval
|
|
#[test]
|
|
fn test_project_lifecycle_flow() {
|
|
// 1. Create project
|
|
let project_name = "Test Project";
|
|
let project_type = "web";
|
|
|
|
// 2. Verify project exists
|
|
assert!(!project_name.is_empty());
|
|
assert!(!project_type.is_empty());
|
|
|
|
// 3. Transition phase
|
|
let from_phase = "planning";
|
|
let to_phase = "design";
|
|
assert_ne!(from_phase, to_phase);
|
|
|
|
// 4. Add checklist items
|
|
let items = vec!["Item 1", "Item 2", "Item 3"];
|
|
assert_eq!(items.len(), 3);
|
|
|
|
// 5. Verify status
|
|
assert!(!items.is_empty());
|
|
}
|
|
|
|
/// Test security assessment workflow
|
|
#[test]
|
|
fn test_security_assessment() {
|
|
let project_id = "proj-1";
|
|
let profile = "webapi";
|
|
|
|
// Set security profile
|
|
assert!(!profile.is_empty());
|
|
|
|
// Run assessment
|
|
let risk_levels = vec!["low", "medium", "high", "critical"];
|
|
assert!(risk_levels.len() > 0);
|
|
|
|
// Verify results
|
|
assert!(!project_id.is_empty());
|
|
}
|
|
|
|
/// Test batch operations
|
|
#[test]
|
|
fn test_batch_operations() {
|
|
let operations = vec!["create", "update", "transition", "security"];
|
|
assert_eq!(operations.len(), 4);
|
|
|
|
let total = operations.len();
|
|
let successful = 4;
|
|
let failed = total - successful;
|
|
|
|
assert_eq!(failed, 0);
|
|
}
|
|
|
|
/// Test search and filtering
|
|
#[test]
|
|
fn test_search_operations() {
|
|
let query = "test project";
|
|
let phase_filter = Some("design");
|
|
let type_filter = Some("web");
|
|
|
|
// Parse query
|
|
assert!(!query.is_empty());
|
|
|
|
// Apply filters
|
|
assert!(phase_filter.is_some());
|
|
assert!(type_filter.is_some());
|
|
|
|
// Get results
|
|
let results = vec!["proj1", "proj2"];
|
|
assert!(results.len() > 0);
|
|
}
|
|
|
|
/// Test export/import round-trip
|
|
#[test]
|
|
fn test_export_import_roundtrip() {
|
|
let format = "json";
|
|
let data = r#"{"id":"1","name":"test","phase":"design"}"#;
|
|
|
|
// Export
|
|
assert!(!format.is_empty());
|
|
|
|
// Parse JSON
|
|
let parsed: HashMap<String, String> = serde_json::from_str(data).unwrap();
|
|
assert_eq!(parsed.get("name"), Some(&"test".to_string()));
|
|
|
|
// Import
|
|
assert!(parsed.contains_key("id"));
|
|
assert!(parsed.contains_key("phase"));
|
|
}
|
|
|
|
/// Test concurrent operations
|
|
#[test]
|
|
fn test_concurrent_access() {
|
|
let operations = vec![1, 2, 3, 4, 5];
|
|
let total = operations.len();
|
|
|
|
// Simulate concurrent operations
|
|
let results: Vec<_> = operations.iter().map(|i| i * 2).collect();
|
|
|
|
assert_eq!(results.len(), total);
|
|
assert_eq!(results[0], 2);
|
|
assert_eq!(results[4], 10);
|
|
}
|
|
|
|
/// Test error handling
|
|
#[test]
|
|
fn test_error_handling() {
|
|
// Test with empty project name
|
|
let project_name = "";
|
|
let result = if project_name.is_empty() {
|
|
Err("Project name cannot be empty")
|
|
} else {
|
|
Ok("Project created")
|
|
};
|
|
|
|
assert!(result.is_err());
|
|
|
|
// Test with invalid phase
|
|
let phase = "invalid_phase";
|
|
let valid_phases = vec!["planning", "design", "development"];
|
|
let is_valid = valid_phases.contains(&phase);
|
|
assert!(!is_valid);
|
|
}
|
|
|
|
/// Test data persistence
|
|
#[test]
|
|
fn test_data_persistence() {
|
|
let project_data = serde_json::json!({
|
|
"id": "test-1",
|
|
"name": "Test Project",
|
|
"phase": "design",
|
|
"version": "1.0.0"
|
|
});
|
|
|
|
// Serialize
|
|
let serialized = serde_json::to_string(&project_data).unwrap();
|
|
assert!(!serialized.is_empty());
|
|
|
|
// Deserialize
|
|
let deserialized: serde_json::Value = serde_json::from_str(&serialized).unwrap();
|
|
assert_eq!(
|
|
deserialized.get("name").unwrap().as_str().unwrap(),
|
|
"Test Project"
|
|
);
|
|
}
|
|
|
|
/// Test configuration management
|
|
#[test]
|
|
fn test_configuration() {
|
|
let mut config = HashMap::new();
|
|
config.insert("api_url", "http://localhost:3000");
|
|
config.insert("database", "sqlite:///./projects.db");
|
|
config.insert("log_level", "info");
|
|
|
|
assert_eq!(config.len(), 3);
|
|
assert_eq!(config.get("api_url"), Some(&"http://localhost:3000"));
|
|
}
|
|
|
|
/// Test event streaming
|
|
#[test]
|
|
fn test_event_streaming() {
|
|
let events = vec![
|
|
("project_created", "proj-1"),
|
|
("phase_transitioned", "proj-1"),
|
|
("checklist_updated", "proj-1"),
|
|
];
|
|
|
|
let event_count = events.len();
|
|
assert_eq!(event_count, 3);
|
|
|
|
for (event_type, project_id) in events {
|
|
assert!(!event_type.is_empty());
|
|
assert!(!project_id.is_empty());
|
|
}
|
|
}
|
|
|
|
/// Test agent communication
|
|
#[test]
|
|
fn test_agent_communication() {
|
|
let agents = vec!["architect", "developer", "reviewer", "tester"];
|
|
assert_eq!(agents.len(), 4);
|
|
|
|
for agent in agents {
|
|
assert!(!agent.is_empty());
|
|
}
|
|
}
|
|
|
|
/// Test multi-IA router
|
|
#[test]
|
|
fn test_multi_ia_routing() {
|
|
let providers = vec!["claude", "openai", "gemini", "ollama"];
|
|
assert_eq!(providers.len(), 4);
|
|
|
|
let selected = providers[0]; // Would select based on strategy
|
|
assert!(!selected.is_empty());
|
|
}
|
|
}
|
|
|
|
#[cfg(all(test, not(debug_assertions)))]
|
|
mod performance_tests {
|
|
/// Benchmark project creation
|
|
#[test]
|
|
fn bench_project_creation() {
|
|
let iterations = 1000;
|
|
let start = std::time::Instant::now();
|
|
|
|
for i in 0..iterations {
|
|
let _project_name = format!("Project {}", i);
|
|
}
|
|
|
|
let elapsed = start.elapsed();
|
|
let per_operation = elapsed.as_micros() / iterations;
|
|
|
|
println!("Project creation: {:.2}μs per operation", per_operation);
|
|
assert!(per_operation < 100); // Should be less than 100 microseconds
|
|
}
|
|
|
|
/// Benchmark search operations
|
|
#[test]
|
|
fn bench_search() {
|
|
let projects = (0..100)
|
|
.map(|i| format!("project-{}", i))
|
|
.collect::<Vec<_>>();
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
for query in ["project", "test", "web"].iter() {
|
|
let _results: Vec<_> = projects.iter().filter(|p| p.contains(query)).collect();
|
|
}
|
|
|
|
let elapsed = start.elapsed();
|
|
println!("Search: {:.2}ms", elapsed.as_secs_f64() * 1000.0);
|
|
}
|
|
|
|
/// Benchmark serialization
|
|
#[test]
|
|
fn bench_serialization() {
|
|
let data = serde_json::json!({
|
|
"id": "test",
|
|
"name": "Project",
|
|
"phase": "design",
|
|
"version": "1.0.0"
|
|
});
|
|
|
|
let start = std::time::Instant::now();
|
|
|
|
for _ in 0..10000 {
|
|
let _serialized = serde_json::to_string(&data).unwrap();
|
|
}
|
|
|
|
let elapsed = start.elapsed();
|
|
println!(
|
|
"Serialization: {:.2}μs per operation",
|
|
elapsed.as_micros() / 10000
|
|
);
|
|
}
|
|
}
|