412 lines
10 KiB
Rust
412 lines
10 KiB
Rust
//! Integration Tests for Phase 5.4: Summarization
|
|||
|
|
//!
|
||
|
|
//! Tests result abstraction, key fact extraction, coherence optimization,
|
||
|
|
//! and length-controlled summarization.
|
||
|
|
|
||
|
|
#[cfg(test)]
|
||
|
|
mod tests {
|
||
|
|
/// Test: Summarization strategy - extractive
|
||
|
|
#[test]
|
||
|
|
fn test_strategy_extractive() {
|
||
|
|
let strategy = "extractive";
|
||
|
|
assert_eq!(strategy, "extractive");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summarization strategy - abstractive
|
||
|
|
#[test]
|
||
|
|
fn test_strategy_abstractive() {
|
||
|
|
let strategy = "abstractive";
|
||
|
|
assert_eq!(strategy, "abstractive");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summarization strategy - hybrid
|
||
|
|
#[test]
|
||
|
|
fn test_strategy_hybrid() {
|
||
|
|
let strategy = "hybrid";
|
||
|
|
assert_eq!(strategy, "hybrid");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summary compression ratio
|
||
|
|
#[test]
|
||
|
|
fn test_compression_ratio_valid() {
|
||
|
|
let original = 1000;
|
||
|
|
let compressed = 250;
|
||
|
|
let ratio = compressed as f32 / original as f32;
|
||
|
|
assert!(ratio < 1.0 && ratio > 0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Key fact structure
|
||
|
|
#[test]
|
||
|
|
fn test_key_fact_importance() {
|
||
|
|
let importance = 0.85;
|
||
|
|
assert!(importance >= 0.0 && importance <= 1.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Coherence score range
|
||
|
|
#[test]
|
||
|
|
fn test_coherence_score_range() {
|
||
|
|
let coherence = 0.78;
|
||
|
|
assert!(coherence >= 0.0 && coherence <= 1.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summary text not empty
|
||
|
|
#[test]
|
||
|
|
fn test_summary_not_empty() {
|
||
|
|
let summary = "This is a summary";
|
||
|
|
assert!(!summary.is_empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Original length tracking
|
||
|
|
#[test]
|
||
|
|
fn test_original_length_tracked() {
|
||
|
|
let original_length = 5000;
|
||
|
|
assert!(original_length > 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summary length less than max
|
||
|
|
#[test]
|
||
|
|
fn test_summary_length_respects_max() {
|
||
|
|
let summary_len = 150;
|
||
|
|
let max_len = 200;
|
||
|
|
assert!(summary_len <= max_len);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Compression ratio calculation
|
||
|
|
#[test]
|
||
|
|
fn test_compression_ratio_calculation() {
|
||
|
|
let original = 1000;
|
||
|
|
let summary = 200;
|
||
|
|
let expected = 0.2;
|
||
|
|
let actual = summary as f32 / original as f32;
|
||
|
|
assert!((actual - expected).abs() < 0.01);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Multiple key facts extracted
|
||
|
|
#[test]
|
||
|
|
fn test_multiple_key_facts() {
|
||
|
|
let facts = vec!["fact1", "fact2", "fact3"];
|
||
|
|
assert_eq!(facts.len(), 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Fact type classification
|
||
|
|
#[test]
|
||
|
|
fn test_fact_type_entity() {
|
||
|
|
let fact_type = "entity";
|
||
|
|
assert_eq!(fact_type, "entity");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Fact type classification - relation
|
||
|
|
#[test]
|
||
|
|
fn test_fact_type_relation() {
|
||
|
|
let fact_type = "relation";
|
||
|
|
assert_eq!(fact_type, "relation");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Coherence metrics structure
|
||
|
|
#[test]
|
||
|
|
fn test_coherence_metrics() {
|
||
|
|
let entity_coherence = 0.75;
|
||
|
|
let flow_coherence = 0.82;
|
||
|
|
let semantic_coherence = 0.88;
|
||
|
|
|
||
|
|
assert!(entity_coherence >= 0.0);
|
||
|
|
assert!(flow_coherence >= 0.0);
|
||
|
|
assert!(semantic_coherence >= 0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Entity coherence calculation
|
||
|
|
#[test]
|
||
|
|
fn test_entity_coherence() {
|
||
|
|
let coherence = 0.8;
|
||
|
|
assert!(coherence > 0.7);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Flow coherence calculation
|
||
|
|
#[test]
|
||
|
|
fn test_flow_coherence() {
|
||
|
|
let coherence = 0.85;
|
||
|
|
assert!(coherence > 0.8);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Semantic coherence calculation
|
||
|
|
#[test]
|
||
|
|
fn test_semantic_coherence() {
|
||
|
|
let coherence = 0.9;
|
||
|
|
assert!(coherence > 0.8);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Sentence splitting
|
||
|
|
#[test]
|
||
|
|
fn test_sentence_splitting() {
|
||
|
|
let text = "First sentence. Second sentence. Third sentence.";
|
||
|
|
let count = text.split('.').filter(|s| !s.trim().is_empty()).count();
|
||
|
|
assert_eq!(count, 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Sentence scoring
|
||
|
|
#[test]
|
||
|
|
fn test_sentence_scoring() {
|
||
|
|
let score = 0.65;
|
||
|
|
assert!(score >= 0.0 && score <= 1.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: TF-IDF like scoring
|
||
|
|
#[test]
|
||
|
|
fn test_tfidf_scoring() {
|
||
|
|
let tf = 0.5;
|
||
|
|
let idf = 2.0;
|
||
|
|
let score = tf * idf;
|
||
|
|
assert!(score > 0.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Entity extraction from text
|
||
|
|
#[test]
|
||
|
|
fn test_entity_extraction() {
|
||
|
|
let text = "Kubernetes Docker Microservices";
|
||
|
|
let words: Vec<&str> = text.split_whitespace().collect();
|
||
|
|
let entities: Vec<_> = words.iter()
|
||
|
|
.filter(|w| w.chars().next().map_or(false, |c| c.is_uppercase()))
|
||
|
|
.collect();
|
||
|
|
assert_eq!(entities.len(), 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Phrase extraction
|
||
|
|
#[test]
|
||
|
|
fn test_phrase_extraction() {
|
||
|
|
let phrases = vec!["Kubernetes Platform", "Docker Container"];
|
||
|
|
assert_eq!(phrases.len(), 2);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Coherence improvement
|
||
|
|
#[test]
|
||
|
|
fn test_coherence_improvement() {
|
||
|
|
let original = "Sentence one. Sentence two.";
|
||
|
|
let improved = "Sentence one. Furthermore, Sentence two.";
|
||
|
|
|
||
|
|
assert!(improved.len() > original.len());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Transition words insertion
|
||
|
|
#[test]
|
||
|
|
fn test_transition_insertion() {
|
||
|
|
let transitions = vec!["Furthermore", "Moreover", "Additionally"];
|
||
|
|
assert!(transitions.len() > 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Content validation - empty
|
||
|
|
#[test]
|
||
|
|
fn test_content_validation_empty() {
|
||
|
|
let content = "";
|
||
|
|
assert!(content.is_empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Content validation - too long
|
||
|
|
#[test]
|
||
|
|
fn test_content_validation_too_long() {
|
||
|
|
let content = "x".repeat(60000);
|
||
|
|
assert!(content.len() > 50000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Max length validation - too short
|
||
|
|
#[test]
|
||
|
|
fn test_max_length_too_short() {
|
||
|
|
let max_length = 10;
|
||
|
|
assert!(max_length < 50);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Max length validation - too long
|
||
|
|
#[test]
|
||
|
|
fn test_max_length_too_long() {
|
||
|
|
let max_length = 15000;
|
||
|
|
assert!(max_length > 10000);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Default max length
|
||
|
|
#[test]
|
||
|
|
fn test_default_max_length() {
|
||
|
|
let default_len = 200;
|
||
|
|
assert_eq!(default_len, 200);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Default strategy
|
||
|
|
#[test]
|
||
|
|
fn test_default_strategy() {
|
||
|
|
let default_strat = "hybrid";
|
||
|
|
assert_eq!(default_strat, "hybrid");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Rate limiting for summarization
|
||
|
|
#[test]
|
||
|
|
fn test_summarization_rate_limit() {
|
||
|
|
let limit = 100;
|
||
|
|
let requests = 80;
|
||
|
|
|
||
|
|
assert!(requests < limit);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Performance tracking
|
||
|
|
#[test]
|
||
|
|
fn test_summarization_performance_tracking() {
|
||
|
|
let process_time_ms = 150;
|
||
|
|
assert!(process_time_ms > 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summary metadata completeness
|
||
|
|
#[test]
|
||
|
|
fn test_summary_metadata_complete() {
|
||
|
|
let has_original_length = true;
|
||
|
|
let has_summary_length = true;
|
||
|
|
let has_compression_ratio = true;
|
||
|
|
|
||
|
|
assert!(has_original_length && has_summary_length && has_compression_ratio);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Key fact importance ordering
|
||
|
|
#[test]
|
||
|
|
fn test_key_fact_importance_ordering() {
|
||
|
|
let importance1 = 0.9;
|
||
|
|
let importance2 = 0.7;
|
||
|
|
|
||
|
|
assert!(importance1 > importance2);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Fact source tracking
|
||
|
|
#[test]
|
||
|
|
fn test_fact_source_tracking() {
|
||
|
|
let source_id = "entity_kubernetes";
|
||
|
|
assert!(!source_id.is_empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Extractive vs abstractive
|
||
|
|
#[test]
|
||
|
|
fn test_extractive_vs_abstractive() {
|
||
|
|
let extractive_type = "extractive";
|
||
|
|
let abstractive_type = "abstractive";
|
||
|
|
|
||
|
|
assert_ne!(extractive_type, abstractive_type);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Hybrid combines both approaches
|
||
|
|
#[test]
|
||
|
|
fn test_hybrid_strategy() {
|
||
|
|
let hybrid = "hybrid";
|
||
|
|
assert_eq!(hybrid, "hybrid");
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Sentence length variation
|
||
|
|
#[test]
|
||
|
|
fn test_sentence_length_variation() {
|
||
|
|
let short_sent = "Brief.";
|
||
|
|
let long_sent = "This is a much longer sentence with many details.";
|
||
|
|
|
||
|
|
assert!(long_sent.len() > short_sent.len());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Vocabulary richness
|
||
|
|
#[test]
|
||
|
|
fn test_vocabulary_richness() {
|
||
|
|
let unique_words = 15;
|
||
|
|
let total_words = 20;
|
||
|
|
|
||
|
|
assert!(unique_words as f32 / total_words as f32 < 1.0);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Key fact count limit
|
||
|
|
#[test]
|
||
|
|
fn test_key_fact_count_limit() {
|
||
|
|
let extracted_facts = 7;
|
||
|
|
let max_facts = 5;
|
||
|
|
|
||
|
|
assert!(extracted_facts >= max_facts); // Should be limited
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Compression consistency
|
||
|
|
#[test]
|
||
|
|
fn test_compression_consistency() {
|
||
|
|
let ratio1 = 0.25;
|
||
|
|
let ratio2 = 0.25;
|
||
|
|
|
||
|
|
assert_eq!(ratio1, ratio2);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Coherence metric averaging
|
||
|
|
#[test]
|
||
|
|
fn test_coherence_averaging() {
|
||
|
|
let c1 = 0.8;
|
||
|
|
let c2 = 0.9;
|
||
|
|
let c3 = 0.7;
|
||
|
|
let avg = (c1 + c2 + c3) / 3.0;
|
||
|
|
|
||
|
|
assert!((avg - 0.8).abs() < 0.1);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Content length calculation
|
||
|
|
#[test]
|
||
|
|
fn test_content_length_calculation() {
|
||
|
|
let content = "Hello world";
|
||
|
|
let length = content.len();
|
||
|
|
|
||
|
|
assert_eq!(length, 11);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summary POST request structure
|
||
|
|
#[test]
|
||
|
|
fn test_summarize_request_structure() {
|
||
|
|
let project = "poimen";
|
||
|
|
let content_len = 1000;
|
||
|
|
let max_length = 200;
|
||
|
|
|
||
|
|
assert!(!project.is_empty());
|
||
|
|
assert!(content_len > max_length);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summarize response structure
|
||
|
|
#[test]
|
||
|
|
fn test_summarize_response_structure() {
|
||
|
|
let has_original = true;
|
||
|
|
let has_summary = true;
|
||
|
|
let has_ratio = true;
|
||
|
|
|
||
|
|
assert!(has_original && has_summary && has_ratio);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Long content handling
|
||
|
|
#[test]
|
||
|
|
fn test_long_content_handling() {
|
||
|
|
let content_len = 45000;
|
||
|
|
let max_allowed = 50000;
|
||
|
|
|
||
|
|
assert!(content_len < max_allowed);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Short content handling
|
||
|
|
#[test]
|
||
|
|
fn test_short_content_handling() {
|
||
|
|
let content_len = 100;
|
||
|
|
let min_allowed = 1;
|
||
|
|
|
||
|
|
assert!(content_len >= min_allowed);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Summarization error handling
|
||
|
|
#[test]
|
||
|
|
fn test_summarization_error_cases() {
|
||
|
|
let empty_content = "";
|
||
|
|
assert!(empty_content.is_empty());
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Fact type enumeration
|
||
|
|
#[test]
|
||
|
|
fn test_fact_types() {
|
||
|
|
let types = vec!["entity", "relation", "property"];
|
||
|
|
assert_eq!(types.len(), 3);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// Test: Response serialization
|
||
|
|
#[test]
|
||
|
|
fn test_response_json_serializable() {
|
||
|
|
let compression_ratio = 0.25;
|
||
|
|
assert!(compression_ratio > 0.0 && compression_ratio < 1.0);
|
||
|
|
}
|
||
|
|
}
|