pub mod extraction;
pub mod resolver;
pub mod types;
use std::path::Path;
use crate::engine::diff_parser::FileChunk;
use types::{ContextChain, ContextConfig};
pub fn build_context_chain(
chunks: &[FileChunk],
config: &ContextConfig,
project_root: &Path,
ignore_patterns: &[String],
) -> ContextChain {
let symbols = extraction::extract_symbols_from_diff(chunks);
let defs = extraction::extract_definitions_from_diff(chunks);
if (symbols.is_empty() && defs.is_empty()) || !config.enabled {
return ContextChain::default();
}
resolver::build_context_chain(&symbols, &defs, config, project_root, ignore_patterns)
}
#[cfg(test)]
mod tests {
use super::*;
fn default_config() -> ContextConfig {
ContextConfig::default()
}
#[test]
fn empty_chunks_returns_empty() {
let chain = build_context_chain(&[], &default_config(), Path::new("/tmp"), &[]);
assert!(chain.text.is_empty());
}
#[test]
fn disabled_returns_empty() {
let config = ContextConfig {
enabled: false,
..default_config()
};
let chunks = crate::engine::diff_parser::parse_diff(
"diff --git a/src/main.rs b/src/main.rs\n--- a/src/main.rs\n+++ b/src/main.rs\n@@ -1,1 +1,2 @@\n fn main() {\n+ foo();\n }\n",
);
let chain = build_context_chain(&chunks, &config, Path::new("/tmp"), &[]);
assert!(chain.text.is_empty());
}
#[test]
fn extracts_from_real_diff() {
let diff = r#"diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,8 @@
fn main() {
println!("hello");
+ let config = load_config();
+ authenticate(&config);
}
"#;
let chunks = crate::engine::diff_parser::parse_diff(diff);
let chain = build_context_chain(&chunks, &default_config(), Path::new("/nonexistent"), &[]);
assert_eq!(chain.stats.symbols_extracted, 2);
}
}