use cqlite_core::cql::config::{ParserBackend, ParserConfig, ParserFeature};
use cqlite_core::cql::factory::{ParserFactory, ParserRegistry, UseCase};
use cqlite_core::cql::traits::CqlParserFactory;
use std::time::Duration;
#[test]
fn test_parser_factory_public_api() {
let result = ParserFactory::create_default();
assert!(result.is_ok());
let factory = ParserFactory;
let parser_result = factory.create_parser();
assert!(parser_result.is_ok());
let config = ParserConfig::default();
let parser_with_config = factory.create_parser_with_config(config);
assert!(parser_with_config.is_ok());
let info = factory.factory_info();
assert_eq!(info.name, "DefaultParserFactory");
assert!(!info.supported_backends.is_empty());
assert_eq!(info.default_backend, "auto");
assert!(info.supported_backends.contains(&"nom".to_string()));
assert!(!info.supported_backends.contains(&"antlr".to_string()));
}
#[test]
fn test_parser_factory_error_conditions() {
let mut invalid_config = ParserConfig::default();
invalid_config = invalid_config.with_timeout(Duration::ZERO);
let result = ParserFactory::create(invalid_config);
assert!(result.is_err());
let custom_config =
ParserConfig::default().with_backend(ParserBackend::Custom("unknown".to_string()));
let result = ParserFactory::create(custom_config);
assert!(result.is_err());
assert!(ParserFactory::is_backend_available(&ParserBackend::Nom));
assert!(ParserFactory::is_backend_available(&ParserBackend::Auto));
assert!(!ParserFactory::is_backend_available(
&ParserBackend::Custom("nonexistent".to_string())
));
}
#[test]
fn test_parser_factory_configuration_validation() {
let valid_config = ParserConfig::default();
let result = ParserFactory::create(valid_config);
assert!(result.is_ok());
let timeout_config = ParserConfig::default().with_timeout(Duration::from_secs(10));
let result = ParserFactory::create(timeout_config);
assert!(result.is_ok());
let feature_config = ParserConfig::default()
.with_feature(ParserFeature::ErrorRecovery)
.with_feature(ParserFeature::Caching);
let result = ParserFactory::create(feature_config);
assert!(result.is_ok());
let nom_config = ParserConfig::default().with_backend(ParserBackend::Nom);
let result = ParserFactory::create(nom_config);
assert!(result.is_ok());
let auto_config = ParserConfig::default().with_backend(ParserBackend::Auto);
let result = ParserFactory::create(auto_config);
assert!(result.is_ok());
}
#[tokio::test]
async fn test_use_case_recommendations() {
let use_cases = [
UseCase::HighPerformance,
UseCase::Development,
UseCase::Production,
UseCase::Embedded,
UseCase::Interactive,
UseCase::Batch,
];
for use_case in use_cases {
assert_eq!(
ParserFactory::recommend_backend(use_case.clone()),
ParserBackend::Nom,
"use case {:?} should recommend nom",
use_case
);
let parser = ParserFactory::create_for_use_case(use_case.clone())
.unwrap_or_else(|e| panic!("create_for_use_case({:?}) failed: {}", use_case, e));
assert_eq!(parser.backend_info().name, "nom", "use case {:?}", use_case);
let statement = parser
.parse("CREATE TABLE ks.t (id uuid PRIMARY KEY)")
.await
.unwrap_or_else(|e| panic!("parse failed for {:?}: {}", use_case, e));
assert!(matches!(
statement,
cqlite_core::cql::ast::CqlStatement::CreateTable(_)
));
}
}
#[tokio::test]
async fn test_strict_validation_config_parses() {
let config = ParserConfig::default().with_strict_validation(true);
let parser = ParserFactory::create(config).expect("strict config should create a parser");
assert_eq!(parser.backend_info().name, "nom");
let statement = parser
.parse("CREATE TABLE ks.t (id uuid PRIMARY KEY)")
.await
.expect("strict-validation parse should succeed");
assert!(matches!(
statement,
cqlite_core::cql::ast::CqlStatement::CreateTable(_)
));
}
#[test]
fn test_parser_registry_functionality() {
let registry = ParserRegistry::new();
assert!(registry.list_factories().is_empty());
let result = registry.get_factory("nonexistent");
assert!(result.is_none());
let config = ParserConfig::default();
let result = registry.create_with_factory("nonexistent", config);
assert!(result.is_err());
}
#[test]
fn test_available_backends_info() {
let backends = ParserFactory::get_available_backends();
assert!(!backends.is_empty());
let backend_names: Vec<String> = backends.iter().map(|b| b.name.clone()).collect();
assert!(backend_names.contains(&"nom".to_string()));
assert!(!backend_names.contains(&"antlr".to_string()));
for backend_info in backends {
assert!(!backend_info.name.is_empty());
assert!(!backend_info.version.is_empty());
assert!(!backend_info.features.is_empty());
}
}
#[test]
fn test_auto_parser_creation_flow() {
let auto_config = ParserConfig::default().with_backend(ParserBackend::Auto);
let result = ParserFactory::create(auto_config);
assert!(result.is_ok());
let error_recovery_auto = ParserConfig::default()
.with_backend(ParserBackend::Auto)
.with_feature(ParserFeature::ErrorRecovery);
let result = ParserFactory::create(error_recovery_auto);
assert!(result.is_ok());
let cache_auto = ParserConfig::default()
.with_backend(ParserBackend::Auto)
.with_feature(ParserFeature::Caching);
let result = ParserFactory::create(cache_auto);
assert!(result.is_ok());
}
#[test]
fn test_parser_wrapper_functionality() {
let factory = ParserFactory;
let parser = factory.create_parser().expect("Should create parser");
let backend_info = parser.backend_info();
assert!(!backend_info.name.is_empty());
let valid_sql = "SELECT * FROM users";
let _is_valid = parser.validate_syntax(valid_sql);
let invalid_sql = "INVALID SQL SYNTAX HERE";
let _is_invalid = parser.validate_syntax(invalid_sql);
}
#[test]
fn test_complex_configuration_scenarios() {
let complex_config = ParserConfig::default()
.with_backend(ParserBackend::Auto)
.with_feature(ParserFeature::ErrorRecovery)
.with_feature(ParserFeature::Caching)
.with_feature(ParserFeature::Streaming)
.with_timeout(Duration::from_secs(30));
let result = ParserFactory::create(complex_config);
assert!(result.is_ok());
let unsupported = ParserConfig::default()
.with_backend(ParserBackend::Auto)
.with_feature(ParserFeature::SyntaxHighlighting);
assert!(ParserFactory::create(unsupported).is_err());
let mut perf_config = ParserConfig::default();
perf_config.performance.optimization_level = 3;
perf_config.performance.enable_caching = true;
let result = ParserFactory::create(perf_config);
assert!(result.is_ok());
let strict_config = ParserConfig::strict().with_timeout(Duration::from_secs(120));
let result = ParserFactory::create(strict_config);
assert!(result.is_ok());
}
#[tokio::test]
async fn test_benchmark_functionality() {
use cqlite_core::cql::factory::benchmarks::{benchmark_parsers, BenchmarkConfig};
let mut config = BenchmarkConfig::default();
assert_eq!(config.iterations, 100);
assert_eq!(config.timeout, Duration::from_secs(1));
assert!(!config.test_cases.is_empty());
config.iterations = 1;
config.timeout = Duration::from_millis(100);
config.test_cases = vec!["SELECT 1".to_string()];
let results = benchmark_parsers(config).await;
assert!(!results.is_empty());
for result in results {
assert!(!result.backend.is_empty());
assert!(result.success_rate >= 0.0 && result.success_rate <= 1.0);
}
}