#[cfg(test)]
mod structural_coherence_backward_compatibility_tests {
use std::collections::HashMap;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::time::Instant;
use approx::assert_relative_eq;
use serde_json;
use tempfile::TempDir;
use crate::metrics::coherence::structural_coherence::{
AdvancedAnalysisConfig, AdvancedStructuralAnalysis, BoundaryDetection,
BoundaryDetectionConfig, BoundaryDetectionResult, CoherenceCalculation,
CoherenceCalculationConfig, CoherenceCalculationResult, DetailedStructuralMetrics,
DiscoursePattern, DiscoursePatternAnalysis, DiscoursePatternConfig, DiscoursePatternMatch,
DocumentStructureAnalysis, GeneralAnalysisConfig, HierarchicalAnalysisConfig,
HierarchicalLevel, HierarchicalStructureAnalysis, HierarchicalStructureNode,
StructuralCoherenceAnalyzer, StructuralCoherenceConfig, StructuralCoherenceError,
StructuralCoherenceResult, StructuralMarker, StructuralMarkerAnalysis,
StructuralMarkerConfig, StructuralMarkerMatch,
};
struct TestDataSuite {
simple_text: Vec<String>,
complex_academic_paper: Vec<String>,
technical_documentation: Vec<String>,
narrative_text: Vec<String>,
fragmented_text: Vec<String>,
empty_text: Vec<String>,
single_paragraph: Vec<String>,
hierarchical_structure: Vec<String>,
discourse_heavy: Vec<String>,
marker_rich_text: Vec<String>,
}
impl TestDataSuite {
fn new() -> Self {
Self {
simple_text: vec![
"This is a simple introduction paragraph.".to_string(),
"This paragraph contains the main content.".to_string(),
"Finally, this paragraph provides a conclusion.".to_string(),
],
complex_academic_paper: vec![
"# Abstract\n\nThis paper examines the complex relationship between discourse coherence and structural organization.".to_string(),
"## Introduction\n\nDespite significant advances in computational linguistics, the problem of measuring structural coherence remains challenging.".to_string(),
"### Background\n\nPrevious research has focused on lexical coherence metrics, but structural approaches offer additional insights.".to_string(),
"#### Related Work\n\nSmith et al. (2020) proposed hierarchical analysis methods.".to_string(),
"## Methodology\n\nOur approach combines hierarchical structure detection with discourse pattern analysis.".to_string(),
"### Data Collection\n\nWe collected a corpus of 10,000 academic papers across multiple domains.".to_string(),
"### Analysis Framework\n\nThe framework consists of three main components: structure detection, pattern analysis, and coherence calculation.".to_string(),
"## Results\n\nOur results demonstrate significant improvements over baseline methods.".to_string(),
"### Quantitative Analysis\n\nStructural coherence scores increased by 23% on average.".to_string(),
"### Qualitative Assessment\n\nHuman evaluators rated the improved texts as more coherent and easier to follow.".to_string(),
"## Discussion\n\nThese findings suggest that structural analysis provides valuable insights into text coherence.".to_string(),
"### Implications\n\nThe implications for automated text assessment are significant.".to_string(),
"### Limitations\n\nHowever, several limitations should be acknowledged.".to_string(),
"## Conclusion\n\nIn conclusion, our structural coherence analysis framework offers a promising approach to text quality assessment.".to_string(),
],
technical_documentation: vec![
"Installation Guide".to_string(),
"First, ensure that all prerequisites are installed on your system.".to_string(),
"Step 1: Download the software package from the official repository.".to_string(),
"Step 2: Extract the archive to your desired installation directory.".to_string(),
"Step 3: Configure the environment variables as described below.".to_string(),
"Configuration".to_string(),
"The configuration file contains several important settings.".to_string(),
"For example, the timeout setting controls connection timeouts.".to_string(),
"In contrast, the buffer_size setting affects memory usage.".to_string(),
"Troubleshooting".to_string(),
"If installation fails, check the following common issues:".to_string(),
"1. Insufficient disk space".to_string(),
"2. Missing dependencies".to_string(),
"3. Permission errors".to_string(),
],
narrative_text: vec![
"Once upon a time, in a distant kingdom, there lived a young scholar.".to_string(),
"This scholar spent her days studying ancient texts in the royal library.".to_string(),
"One day, she discovered a mysterious manuscript that would change everything.".to_string(),
"The manuscript contained strange symbols that seemed to shift before her eyes.".to_string(),
"As she studied the symbols, she began to understand their meaning.".to_string(),
"The symbols told the story of an ancient civilization with advanced knowledge.".to_string(),
"This knowledge had been hidden for centuries, waiting for someone to rediscover it.".to_string(),
"The scholar realized that this discovery could revolutionize their understanding of history.".to_string(),
],
fragmented_text: vec![
"Random thought one.".to_string(),
"Completely unrelated second paragraph about weather.".to_string(),
"Technical jargon without context: API endpoints and database schemas.".to_string(),
"Back to weather: it's raining today.".to_string(),
"Philosophical musing about the nature of existence.".to_string(),
],
empty_text: vec![],
single_paragraph: vec![
"This is the only paragraph in this text, but it contains multiple sentences. Each sentence builds upon the previous one. The coherence should be measurable even in this simple case.".to_string(),
],
hierarchical_structure: vec![
"# Chapter 1: Introduction".to_string(),
"This chapter introduces the main concepts.".to_string(),
"## Section 1.1: Basic Principles".to_string(),
"These are the fundamental principles we will explore.".to_string(),
"### Subsection 1.1.1: First Principle".to_string(),
"The first principle states that structure matters.".to_string(),
"### Subsection 1.1.2: Second Principle".to_string(),
"The second principle emphasizes coherence.".to_string(),
"## Section 1.2: Advanced Concepts".to_string(),
"Now we turn to more advanced topics.".to_string(),
"# Chapter 2: Implementation".to_string(),
"This chapter focuses on practical implementation.".to_string(),
],
discourse_heavy: vec![
"The problem with current text analysis methods is their limited scope.".to_string(),
"To solve this problem, we propose a multi-layered approach.".to_string(),
"Our solution combines several techniques: hierarchical analysis, pattern detection, and coherence calculation.".to_string(),
"For example, hierarchical analysis examines document structure.".to_string(),
"In contrast, pattern detection focuses on discourse relationships.".to_string(),
"Similarly, coherence calculation provides quantitative measures.".to_string(),
"As a result of these combined techniques, we achieve better text understanding.".to_string(),
"Therefore, our approach offers significant improvements over existing methods.".to_string(),
],
marker_rich_text: vec![
"Introduction: This paper presents a comprehensive analysis.".to_string(),
"Furthermore, we examine three main aspects of the problem.".to_string(),
"First, we consider the theoretical foundations.".to_string(),
"Second, we analyze practical implementations.".to_string(),
"Third, we evaluate experimental results.".to_string(),
"For instance, our experiments show significant improvements.".to_string(),
"Moreover, the results are consistent across different domains.".to_string(),
"In addition, we provide detailed statistical analysis.".to_string(),
"Conclusion: Our findings demonstrate the effectiveness of the proposed approach.".to_string(),
],
}
}
}
struct ConfigTestSuite {
minimal: StructuralCoherenceConfig,
standard: StructuralCoherenceConfig,
comprehensive: StructuralCoherenceConfig,
academic_focused: StructuralCoherenceConfig,
technical_focused: StructuralCoherenceConfig,
custom_weights: StructuralCoherenceConfig,
}
impl ConfigTestSuite {
fn new() -> Self {
Self {
minimal: StructuralCoherenceConfig {
general: GeneralAnalysisConfig {
min_paragraph_length: 1,
max_analysis_depth: 1,
enable_caching: false,
parallel_processing: false,
detailed_metrics: false,
},
hierarchical: HierarchicalAnalysisConfig::minimal(),
discourse: DiscoursePatternConfig::minimal(),
markers: StructuralMarkerConfig::minimal(),
boundaries: BoundaryDetectionConfig::minimal(),
coherence: CoherenceCalculationConfig::minimal(),
advanced: AdvancedAnalysisConfig::minimal(),
},
standard: StructuralCoherenceConfig::default(),
comprehensive: StructuralCoherenceConfig {
general: GeneralAnalysisConfig {
min_paragraph_length: 1,
max_analysis_depth: 10,
enable_caching: true,
parallel_processing: true,
detailed_metrics: true,
},
hierarchical: HierarchicalAnalysisConfig::comprehensive(),
discourse: DiscoursePatternConfig::comprehensive(),
markers: StructuralMarkerConfig::comprehensive(),
boundaries: BoundaryDetectionConfig::comprehensive(),
coherence: CoherenceCalculationConfig::comprehensive(),
advanced: AdvancedAnalysisConfig::comprehensive(),
},
academic_focused: StructuralCoherenceConfig::for_academic_papers(),
technical_focused: StructuralCoherenceConfig::for_technical_documentation(),
custom_weights: StructuralCoherenceConfig {
general: GeneralAnalysisConfig::default(),
hierarchical: HierarchicalAnalysisConfig {
enable_analysis: true,
max_depth: 5,
level_weights: {
let mut weights = HashMap::new();
weights.insert(HierarchicalLevel::Document, 0.5);
weights.insert(HierarchicalLevel::Chapter, 0.3);
weights.insert(HierarchicalLevel::Section, 0.2);
weights
},
balance_threshold: 0.8,
transition_penalties: HashMap::new(),
},
discourse: DiscoursePatternConfig::default(),
markers: StructuralMarkerConfig::default(),
boundaries: BoundaryDetectionConfig::default(),
coherence: CoherenceCalculationConfig::default(),
advanced: AdvancedAnalysisConfig::default(),
},
}
}
}
#[test]
fn test_analyzer_initialization_compatibility() {
let configs = ConfigTestSuite::new();
let analyzers = vec![
StructuralCoherenceAnalyzer::new(configs.minimal.clone()),
StructuralCoherenceAnalyzer::new(configs.standard.clone()),
StructuralCoherenceAnalyzer::new(configs.comprehensive.clone()),
StructuralCoherenceAnalyzer::new(configs.academic_focused.clone()),
StructuralCoherenceAnalyzer::new(configs.technical_focused.clone()),
StructuralCoherenceAnalyzer::new(configs.custom_weights.clone()),
];
assert_eq!(analyzers.len(), 6);
let default_analyzer = StructuralCoherenceAnalyzer::default();
assert!(!format!("{:?}", default_analyzer).is_empty());
}
#[test]
fn test_basic_analysis_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let results = vec![
analyzer.analyze_structural_coherence(&test_data.simple_text),
analyzer.analyze_structural_coherence(&test_data.complex_academic_paper),
analyzer.analyze_structural_coherence(&test_data.technical_documentation),
analyzer.analyze_structural_coherence(&test_data.narrative_text),
analyzer.analyze_structural_coherence(&test_data.single_paragraph),
analyzer.analyze_structural_coherence(&test_data.hierarchical_structure),
analyzer.analyze_structural_coherence(&test_data.discourse_heavy),
analyzer.analyze_structural_coherence(&test_data.marker_rich_text),
];
for result in &results {
assert!(result.is_ok(), "Analysis failed: {:?}", result);
}
for result in results {
let analysis = result.expect("operation should succeed");
assert!(analysis.overall_coherence_score >= 0.0);
assert!(analysis.overall_coherence_score <= 1.0);
assert!(!analysis.detailed_metrics.is_none());
}
}
#[test]
fn test_empty_and_edge_cases_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let empty_result = analyzer.analyze_structural_coherence(&test_data.empty_text);
assert!(empty_result.is_ok());
let empty_analysis = empty_result.expect("operation should succeed");
assert_relative_eq!(empty_analysis.overall_coherence_score, 0.0, epsilon = 1e-6);
let fragmented_result = analyzer.analyze_structural_coherence(&test_data.fragmented_text);
assert!(fragmented_result.is_ok());
let fragmented_analysis = fragmented_result.expect("operation should succeed");
assert!(fragmented_analysis.overall_coherence_score < 0.5);
let single_result = analyzer.analyze_structural_coherence(&test_data.single_paragraph);
assert!(single_result.is_ok());
let single_analysis = single_result.expect("operation should succeed");
assert!(single_analysis.overall_coherence_score > 0.0);
let long_paragraphs: Vec<String> = (0..100)
.map(|i| {
format!(
"This is paragraph number {} with consistent content and structure.",
i
)
})
.collect();
let long_result = analyzer.analyze_structural_coherence(&long_paragraphs);
assert!(long_result.is_ok());
}
#[test]
fn test_hierarchical_analysis_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer.analyze_hierarchical_structure(&test_data.hierarchical_structure);
assert!(result.is_ok());
let analysis = result.expect("operation should succeed");
assert!(analysis.tree_structure.len() > 0);
assert!(analysis
.level_distribution
.contains_key(&HierarchicalLevel::Chapter));
assert!(analysis
.level_distribution
.contains_key(&HierarchicalLevel::Section));
assert!(analysis.balance_score >= 0.0);
assert!(analysis.balance_score <= 1.0);
let simple_result = analyzer.analyze_hierarchical_structure(&test_data.simple_text);
assert!(simple_result.is_ok());
for paragraph in &test_data.hierarchical_structure {
let level = analyzer.detect_hierarchical_level(¶graph);
assert!(matches!(
level,
HierarchicalLevel::Document
| HierarchicalLevel::Chapter
| HierarchicalLevel::Section
| HierarchicalLevel::Subsection
| HierarchicalLevel::Paragraph
));
}
}
#[test]
fn test_discourse_pattern_analysis_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer.analyze_discourse_patterns(&test_data.discourse_heavy);
assert!(result.is_ok());
let analysis = result.expect("operation should succeed");
assert!(analysis.identified_patterns.len() > 0);
assert!(analysis.overall_pattern_coherence >= 0.0);
assert!(analysis.overall_pattern_coherence <= 1.0);
let has_problem_solution = analysis
.identified_patterns
.iter()
.any(|p| matches!(p.pattern_type, DiscoursePattern::ProblemSolution));
assert!(has_problem_solution);
let has_compare_contrast = analysis
.identified_patterns
.iter()
.any(|p| matches!(p.pattern_type, DiscoursePattern::CompareContrast));
assert!(has_compare_contrast);
for paragraph in &test_data.discourse_heavy {
let patterns = analyzer.detect_discourse_patterns(¶graph);
assert!(patterns.len() >= 0); }
}
#[test]
fn test_structural_marker_analysis_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer.analyze_structural_markers(&test_data.marker_rich_text);
assert!(result.is_ok());
let analysis = result.expect("operation should succeed");
assert!(analysis.identified_markers.len() > 0);
assert!(analysis.marker_density >= 0.0);
assert!(analysis.effectiveness_score >= 0.0);
assert!(analysis.effectiveness_score <= 1.0);
let has_intro_markers = analysis
.identified_markers
.iter()
.any(|m| matches!(m.marker_type, StructuralMarker::Introduction));
assert!(has_intro_markers);
let has_enum_markers = analysis
.identified_markers
.iter()
.any(|m| matches!(m.marker_type, StructuralMarker::Enumeration));
assert!(has_enum_markers);
let has_conclusion_markers = analysis
.identified_markers
.iter()
.any(|m| matches!(m.marker_type, StructuralMarker::Conclusion));
assert!(has_conclusion_markers);
for paragraph in &test_data.marker_rich_text {
let markers = analyzer.detect_structural_markers(¶graph);
}
}
#[test]
fn test_boundary_detection_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer.detect_structural_boundaries(&test_data.complex_academic_paper);
assert!(result.is_ok());
let boundaries = result.expect("operation should succeed");
assert!(boundaries.section_boundaries.len() > 0);
assert!(boundaries.topic_boundaries.len() > 0);
assert!(boundaries.confidence_scores.len() == boundaries.section_boundaries.len());
for score in &boundaries.confidence_scores {
assert!(*score >= 0.0);
assert!(*score <= 1.0);
}
let simple_result = analyzer.detect_structural_boundaries(&test_data.simple_text);
assert!(simple_result.is_ok());
}
#[test]
fn test_coherence_calculation_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let hierarchical = analyzer
.analyze_hierarchical_structure(&test_data.hierarchical_structure)
.expect("operation should succeed");
let discourse = analyzer
.analyze_discourse_patterns(&test_data.discourse_heavy)
.expect("operation should succeed");
let markers = analyzer
.analyze_structural_markers(&test_data.marker_rich_text)
.expect("operation should succeed");
let result = analyzer.calculate_overall_coherence(&hierarchical, &discourse, &markers);
assert!(result.is_ok());
let calculation = result.expect("operation should succeed");
assert!(calculation.overall_score >= 0.0);
assert!(calculation.overall_score <= 1.0);
assert!(calculation.hierarchical_contribution >= 0.0);
assert!(calculation.discourse_contribution >= 0.0);
assert!(calculation.marker_contribution >= 0.0);
let weight_sum = calculation.hierarchical_weight
+ calculation.discourse_weight
+ calculation.marker_weight;
assert_relative_eq!(weight_sum, 1.0, epsilon = 1e-6);
}
#[test]
fn test_advanced_analysis_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer.perform_advanced_analysis(&test_data.complex_academic_paper);
assert!(result.is_ok());
let analysis = result.expect("operation should succeed");
assert!(analysis.rhetorical_structure.is_some());
assert!(analysis.reader_experience_metrics.is_some());
assert!(analysis.complexity_analysis.is_some());
if let Some(rhetorical) = &analysis.rhetorical_structure {
assert!(rhetorical.argument_structure.len() > 0);
assert!(rhetorical.evidence_distribution.len() > 0);
assert!(rhetorical.persuasive_elements.len() >= 0);
}
if let Some(reader_exp) = &analysis.reader_experience_metrics {
assert!(reader_exp.cognitive_load_score >= 0.0);
assert!(reader_exp.cognitive_load_score <= 1.0);
assert!(reader_exp.navigation_ease_score >= 0.0);
assert!(reader_exp.navigation_ease_score <= 1.0);
}
if let Some(complexity) = &analysis.complexity_analysis {
assert!(complexity.structural_complexity >= 0.0);
assert!(complexity.information_density >= 0.0);
assert!(complexity.conceptual_depth >= 0);
}
}
#[test]
fn test_configuration_compatibility() {
let configs = vec![
StructuralCoherenceConfig::default(),
StructuralCoherenceConfig::minimal(),
StructuralCoherenceConfig::comprehensive(),
StructuralCoherenceConfig::for_academic_papers(),
StructuralCoherenceConfig::for_technical_documentation(),
StructuralCoherenceConfig::for_creative_writing(),
];
for config in configs {
let analyzer = StructuralCoherenceAnalyzer::new(config);
assert!(!format!("{:?}", analyzer).is_empty());
}
let builder_config = StructuralCoherenceConfig::builder()
.general_config(GeneralAnalysisConfig {
min_paragraph_length: 5,
max_analysis_depth: 3,
enable_caching: true,
parallel_processing: false,
detailed_metrics: true,
})
.hierarchical_config(HierarchicalAnalysisConfig::default())
.build();
let builder_analyzer = StructuralCoherenceAnalyzer::new(builder_config);
assert!(!format!("{:?}", builder_analyzer).is_empty());
}
#[test]
fn test_result_serialization_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer
.analyze_structural_coherence(&test_data.complex_academic_paper)
.expect("operation should succeed");
let serialized = serde_json::to_string(&result);
assert!(serialized.is_ok());
let deserialized: Result<StructuralCoherenceResult, _> =
serde_json::from_str(&serialized.expect("operation should succeed"));
assert!(deserialized.is_ok());
let recovered_result = deserialized.expect("operation should succeed");
assert_relative_eq!(
recovered_result.overall_coherence_score,
result.overall_coherence_score,
epsilon = 1e-10
);
let hierarchical = analyzer
.analyze_hierarchical_structure(&test_data.hierarchical_structure)
.expect("operation should succeed");
let hier_serialized = serde_json::to_string(&hierarchical);
assert!(hier_serialized.is_ok());
let discourse = analyzer
.analyze_discourse_patterns(&test_data.discourse_heavy)
.expect("operation should succeed");
let disc_serialized = serde_json::to_string(&discourse);
assert!(disc_serialized.is_ok());
let markers = analyzer
.analyze_structural_markers(&test_data.marker_rich_text)
.expect("operation should succeed");
let mark_serialized = serde_json::to_string(&markers);
assert!(mark_serialized.is_ok());
}
#[test]
fn test_error_handling_compatibility() {
let analyzer = StructuralCoherenceAnalyzer::default();
let invalid_config = StructuralCoherenceConfig {
general: GeneralAnalysisConfig {
min_paragraph_length: 0,
max_analysis_depth: 0,
enable_caching: false,
parallel_processing: false,
detailed_metrics: false,
},
hierarchical: HierarchicalAnalysisConfig::minimal(),
discourse: DiscoursePatternConfig::minimal(),
markers: StructuralMarkerConfig::minimal(),
boundaries: BoundaryDetectionConfig::minimal(),
coherence: CoherenceCalculationConfig::minimal(),
advanced: AdvancedAnalysisConfig::minimal(),
};
let invalid_analyzer = StructuralCoherenceAnalyzer::new(invalid_config);
let error_variants = vec![
StructuralCoherenceError::InvalidInput("test".to_string()),
StructuralCoherenceError::ConfigurationError("test".to_string()),
StructuralCoherenceError::AnalysisError("test".to_string()),
StructuralCoherenceError::ComputationError("test".to_string()),
];
for error in error_variants {
assert!(!format!("{:?}", error).is_empty());
assert!(!format!("{}", error).is_empty());
}
}
#[test]
fn test_performance_consistency() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let performance_tests = vec![
("simple", &test_data.simple_text),
("single", &test_data.single_paragraph),
("complex", &test_data.complex_academic_paper),
];
for (name, text) in performance_tests {
let start_time = Instant::now();
let result = analyzer.analyze_structural_coherence(text);
let elapsed = start_time.elapsed();
assert!(result.is_ok(), "Performance test failed for {}", name);
assert!(
elapsed.as_secs() < 10,
"Analysis took too long for {}: {:?}",
name,
elapsed
);
let start_time_2 = Instant::now();
let result_2 = analyzer.analyze_structural_coherence(text);
let elapsed_2 = start_time_2.elapsed();
assert!(result_2.is_ok());
let time_diff = if elapsed > elapsed_2 {
elapsed - elapsed_2
} else {
elapsed_2 - elapsed
};
assert!(
time_diff.as_millis() < 1000,
"Performance inconsistency for {}",
name
);
}
}
#[test]
fn test_thread_safety_compatibility() {
use std::sync::Arc;
use std::thread;
let test_data = Arc::new(TestDataSuite::new());
let analyzer = Arc::new(StructuralCoherenceAnalyzer::default());
let mut handles = vec![];
for i in 0..4 {
let test_data_clone = Arc::clone(&test_data);
let analyzer_clone = Arc::clone(&analyzer);
let handle = thread::spawn(move || {
let text = match i % 4 {
0 => &test_data_clone.simple_text,
1 => &test_data_clone.complex_academic_paper,
2 => &test_data_clone.technical_documentation,
_ => &test_data_clone.narrative_text,
};
let result = analyzer_clone.analyze_structural_coherence(text);
assert!(
result.is_ok(),
"Concurrent analysis failed for thread {}",
i
);
result.expect("operation should succeed").overall_coherence_score
});
handles.push(handle);
}
let scores: Vec<f64> = handles.into_iter().map(|h| h.join().expect("map operation should succeed")).collect();
assert_eq!(scores.len(), 4);
for score in scores {
assert!(score >= 0.0);
assert!(score <= 1.0);
}
}
#[test]
fn test_memory_usage_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let initial_usage = get_memory_usage();
for _ in 0..10 {
let _ = analyzer.analyze_structural_coherence(&test_data.complex_academic_paper);
}
let final_usage = get_memory_usage();
let memory_growth = final_usage - initial_usage;
assert!(
memory_growth < 100_000_000,
"Excessive memory growth: {} bytes",
memory_growth
);
}
#[test]
fn test_integration_compatibility() {
let test_data = TestDataSuite::new();
let analyzer = StructuralCoherenceAnalyzer::default();
let result = analyzer
.analyze_structural_coherence(&test_data.complex_academic_paper)
.expect("operation should succeed");
assert!(result.overall_coherence_score > 0.0);
if let Some(detailed) = &result.detailed_metrics {
if let Some(doc_structure) = &detailed.document_structure_analysis {
assert!(doc_structure.total_sections > 0);
assert!(!doc_structure.section_hierarchy.is_empty());
}
if let Some(advanced) = &detailed.advanced_structural_analysis {
if let Some(rhetorical) = &advanced.rhetorical_structure {
assert!(rhetorical.argument_structure.len() >= 0);
}
}
}
let hierarchical = analyzer
.analyze_hierarchical_structure(&test_data.hierarchical_structure)
.expect("operation should succeed");
let discourse = analyzer
.analyze_discourse_patterns(&test_data.discourse_heavy)
.expect("operation should succeed");
let markers = analyzer
.analyze_structural_markers(&test_data.marker_rich_text)
.expect("operation should succeed");
let coherence_calc = analyzer
.calculate_overall_coherence(&hierarchical, &discourse, &markers)
.expect("operation should succeed");
assert!(coherence_calc.overall_score >= 0.0);
assert!(coherence_calc.overall_score <= 1.0);
}
fn get_memory_usage() -> usize {
std::mem::size_of::<StructuralCoherenceAnalyzer>() * 1000 }
#[test]
fn test_comprehensive_api_surface_compatibility() {
let test_data = TestDataSuite::new();
let configs = ConfigTestSuite::new();
for config in [configs.minimal, configs.standard, configs.comprehensive] {
let analyzer = StructuralCoherenceAnalyzer::new(config);
assert!(analyzer
.analyze_structural_coherence(&test_data.simple_text)
.is_ok());
assert!(analyzer
.analyze_hierarchical_structure(&test_data.hierarchical_structure)
.is_ok());
assert!(analyzer
.analyze_discourse_patterns(&test_data.discourse_heavy)
.is_ok());
assert!(analyzer
.analyze_structural_markers(&test_data.marker_rich_text)
.is_ok());
assert!(analyzer
.detect_structural_boundaries(&test_data.complex_academic_paper)
.is_ok());
assert!(analyzer
.perform_advanced_analysis(&test_data.technical_documentation)
.is_ok());
for paragraph in &test_data.complex_academic_paper[..3] {
let _ = analyzer.detect_hierarchical_level(paragraph);
let _ = analyzer.detect_discourse_patterns(paragraph);
let _ = analyzer.detect_structural_markers(paragraph);
}
let _ = analyzer.get_configuration();
assert!(analyzer.validate_input(&test_data.simple_text).is_ok());
}
}
}
#[cfg(test)]
mod integration_compatibility_tests {
use super::*;
use std::path::PathBuf;
use tempfile::TempDir;
#[test]
fn test_file_based_analysis_compatibility() {
let temp_dir = TempDir::new().expect("Temp Dir should succeed");
let test_file_path = temp_dir.path().join("test_document.txt");
let test_content = vec![
"# Document Title".to_string(),
"This is the introduction paragraph.".to_string(),
"## First Section".to_string(),
"This section contains the main content.".to_string(),
"### Subsection".to_string(),
"More detailed information here.".to_string(),
"## Second Section".to_string(),
"Additional content and analysis.".to_string(),
"## Conclusion".to_string(),
"Summary and final thoughts.".to_string(),
];
std::fs::write(&test_file_path, test_content.join("\n")).expect("operation should succeed");
let analyzer = StructuralCoherenceAnalyzer::default();
let file_content = std::fs::read_to_string(&test_file_path).expect("fs should succeed");
let paragraphs: Vec<String> = file_content.lines().map(|s| s.to_string()).collect();
let result = analyzer.analyze_structural_coherence(¶graphs);
assert!(result.is_ok());
let analysis = result.expect("operation should succeed");
assert!(analysis.overall_coherence_score > 0.0);
}
#[test]
fn test_large_document_compatibility() {
let large_document: Vec<String> = (0..1000)
.map(|i| match i % 10 {
0 => format!("# Chapter {}", i / 10 + 1),
1 => format!("## Section {}.1", i / 10 + 1),
2 => format!("### Subsection {}.1.1", i / 10 + 1),
3 => "This is an introduction paragraph.".to_string(),
4 => "For example, this paragraph contains an example.".to_string(),
5 => "Furthermore, this paragraph provides additional details.".to_string(),
6 => "In contrast, this paragraph presents a different viewpoint.".to_string(),
7 => "As a result, we can draw certain conclusions.".to_string(),
8 => "Therefore, this analysis is important.".to_string(),
_ => "This is a concluding paragraph.".to_string(),
})
.collect();
let analyzer = StructuralCoherenceAnalyzer::default();
let start_time = std::time::Instant::now();
let result = analyzer.analyze_structural_coherence(&large_document);
let elapsed = start_time.elapsed();
assert!(result.is_ok());
assert!(elapsed.as_secs() < 60);
let analysis = result.expect("operation should succeed");
assert!(analysis.overall_coherence_score >= 0.0);
assert!(analysis.overall_coherence_score <= 1.0);
}
}