#[test]
fn test_java_kotlin_resolver_wrong_languages() {
let resolver = JavaKotlinResolver;
let java_node = create_test_node(
"Java:class:User",
NodeKind::Class,
"User",
"com.example.User",
Language::Java,
);
let python_node = create_test_node(
"Python:class:User",
NodeKind::Class,
"User",
"user.User",
Language::Python,
);
let reference = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Inherits,
target_id: String::new(),
target_name: "User".to_string(),
target_language: Some(Language::Python),
};
assert!(!resolver.can_resolve(
Language::Java,
Language::Python,
&java_node,
&reference,
&python_node,
));
}
#[test]
fn test_kotlin_to_java_resolver() {
let resolver = JavaKotlinResolver;
let kotlin_node = create_test_node(
"Kotlin:class:KotlinUser",
NodeKind::Class,
"KotlinUser",
"com.example.KotlinUser",
Language::Kotlin,
);
let java_node = create_test_node(
"Java:class:JavaService",
NodeKind::Class,
"JavaService",
"com.example.JavaService",
Language::Java,
);
let reference = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Uses,
target_id: String::new(),
target_name: "JavaService".to_string(),
target_language: Some(Language::Java),
};
assert!(resolver.can_resolve(
Language::Kotlin,
Language::Java,
&kotlin_node,
&reference,
&java_node,
));
}
#[test]
fn test_java_kotlin_resolver_package_name_conversion() {
let resolver = JavaKotlinResolver;
let java_node = create_test_node(
"Java:class:User",
NodeKind::Class,
"User",
"com.example.User",
Language::Java,
);
let kotlin_node = create_test_node(
"Kotlin:class:Service",
NodeKind::Class,
"Service",
"com.example.Service",
Language::Kotlin,
);
let reference = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Uses,
target_id: String::new(),
target_name: "com.example.Service".to_string(),
target_language: Some(Language::Kotlin),
};
assert!(resolver.can_resolve(
Language::Java,
Language::Kotlin,
&java_node,
&reference,
&kotlin_node,
));
}
#[test]
fn test_is_reference_match_direct_id() {
let deps = CrossLanguageDependencies::new();
let source = create_test_node(
"Java:class:User",
NodeKind::Class,
"User",
"com.example.User",
Language::Java,
);
let target = create_test_node(
"Kotlin:class:KotlinUser",
NodeKind::Class,
"KotlinUser",
"com.example.KotlinUser",
Language::Kotlin,
);
let reference = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Inherits,
target_id: "Kotlin:class:KotlinUser".to_string(),
target_name: "".to_string(),
target_language: Some(Language::Kotlin),
};
assert!(deps.is_reference_match(
&source,
&reference,
&target,
Language::Java,
Language::Kotlin
));
}
#[test]
fn test_resolve_references_by_name() {
let java_ref = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Uses,
target_id: String::new(), target_name: "SharedComponent".to_string(),
target_language: None,
};
let java_node = create_test_node_with_references(
"Java:class:JavaClient",
NodeKind::Class,
"JavaClient",
"com.example.JavaClient",
Language::Java,
vec![java_ref],
);
let ts_node = create_test_node(
"TypeScript:class:SharedComponent",
NodeKind::Class,
"SharedComponent",
"SharedComponent",
Language::TypeScript,
);
let mut deps = CrossLanguageDependencies::new();
deps.add_nodes(vec![java_node, ts_node]);
deps.detect_all();
let resolved_deps = deps.get_dependencies();
assert!(!resolved_deps.is_empty());
let dep = resolved_deps.iter().find(|d| {
d.source_id == "Java:class:JavaClient"
&& d.target_id == "TypeScript:class:SharedComponent"
});
assert!(dep.is_some());
let confidence = dep.unwrap().confidence;
assert!(
(0.8..=1.0).contains(&confidence),
"Confidence should be in valid range, got: {confidence}"
);
}
#[test]
fn test_resolve_references_by_fqn() {
let java_ref = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Imports,
target_id: String::new(), target_name: "com.example.SharedModule".to_string(),
target_language: None,
};
let java_node = create_test_node_with_references(
"Java:class:JavaClient",
NodeKind::Class,
"JavaClient",
"com.example.JavaClient",
Language::Java,
vec![java_ref],
);
let kotlin_node = create_test_node(
"Kotlin:module:SharedModule",
NodeKind::Module,
"SharedModule",
"com.example.SharedModule", Language::Kotlin,
);
let mut deps = CrossLanguageDependencies::new();
deps.add_nodes(vec![java_node, kotlin_node]);
deps.detect_all();
let resolved_deps = deps.get_dependencies();
assert!(!resolved_deps.is_empty());
}
#[test]
fn test_dependency_deduplication() {
let ref1 = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Uses,
target_id: String::new(),
target_name: "SharedService".to_string(),
target_language: None,
};
let ref2 = crate::ast::polyglot::unified_node::NodeReference {
kind: ReferenceKind::Uses,
target_id: String::new(),
target_name: "SharedService".to_string(), target_language: None,
};
let java_node = create_test_node_with_references(
"Java:class:JavaClient",
NodeKind::Class,
"JavaClient",
"com.example.JavaClient",
Language::Java,
vec![ref1, ref2],
);
let kotlin_node = create_test_node(
"Kotlin:class:SharedService",
NodeKind::Class,
"SharedService",
"com.example.SharedService",
Language::Kotlin,
);
let mut deps = CrossLanguageDependencies::new();
deps.add_nodes(vec![java_node, kotlin_node]);
deps.detect_all();
let uses_deps: Vec<_> = deps
.get_dependencies()
.iter()
.filter(|d| {
d.source_id == "Java:class:JavaClient"
&& d.target_id == "Kotlin:class:SharedService"
&& d.kind == ReferenceKind::Uses
})
.collect();
assert_eq!(uses_deps.len(), 1);
}
#[test]
fn test_multiple_languages() {
let mut java_node = create_test_node(
"Java:class:JavaService",
NodeKind::Class,
"JavaService",
"com.example.JavaService",
Language::Java,
);
java_node.add_reference(ReferenceKind::Uses, "KotlinHelper".to_string(), None);
java_node.add_reference(ReferenceKind::Uses, "ScalaProcessor".to_string(), None);
let kotlin_node = create_test_node(
"Kotlin:class:KotlinHelper",
NodeKind::Class,
"KotlinHelper",
"com.example.KotlinHelper",
Language::Kotlin,
);
let scala_node = create_test_node(
"Scala:class:ScalaProcessor",
NodeKind::Class,
"ScalaProcessor",
"com.example.ScalaProcessor",
Language::Scala,
);
let mut deps = CrossLanguageDependencies::new();
deps.add_nodes(vec![java_node, kotlin_node, scala_node]);
deps.detect_all();
let java_to_kotlin = deps.get_dependencies_between(Language::Java, Language::Kotlin);
let java_to_scala = deps.get_dependencies_between(Language::Java, Language::Scala);
assert!(!java_to_kotlin.is_empty());
assert!(!java_to_scala.is_empty());
}
#[test]
fn test_empty_nodes() {
let deps = CrossLanguageDependencies::detect(&[], &[]);
assert!(deps.is_empty());
}
#[test]
fn test_same_language_no_cross_deps() {
let mut java1 = create_test_node(
"Java:class:User",
NodeKind::Class,
"User",
"com.example.User",
Language::Java,
);
java1.add_reference(ReferenceKind::Uses, "Service".to_string(), None);
let java2 = create_test_node(
"Java:class:Service",
NodeKind::Class,
"Service",
"com.example.Service",
Language::Java,
);
let deps = CrossLanguageDependencies::detect(&[java1], &[java2]);
assert!(deps.is_empty());
}