use super::*;
mod go_resolver_extract {
use super::*;
#[test]
fn extracts_route_from_r_get() {
let result = GO_RESOLVER.extract("main.go", "r.GET(\"/users\", listUsers)\n");
assert_eq!(result.nodes[0].name, "GET /users");
assert_eq!(result.references[0].reference_name, "listUsers");
}
#[test]
fn extracts_route_from_router_handle_func() {
let result = GO_RESOLVER.extract("main.go", "router.HandleFunc(\"/items\", createItem)\n");
assert_eq!(result.references[0].reference_name, "createItem");
}
#[test]
fn extracts_gorilla_mux_handle_func_on_a_subrouter_var_ignoring_chained_methods() {
let result = GO_RESOLVER.extract(
"routes.go",
"s.HandleFunc(\"/users/{id}\", listUsers).Methods(\"GET\")\n",
);
assert_eq!(result.references[0].reference_name, "listUsers");
}
}
mod rust_resolver_extract {
use super::*;
#[test]
fn extracts_route_from_axum_route_with_get() {
let result = RUST_RESOLVER.extract(
"main.rs",
"let app = Router::new().route(\"/users\", get(list_users));\n",
);
assert_eq!(result.nodes[0].name, "GET /users");
assert_eq!(result.references[0].reference_name, "list_users");
}
#[test]
fn extracts_every_method_from_a_chained_axum_route_get_put() {
let result = RUST_RESOLVER.extract(
"main.rs",
"let app = Router::new().route(\"/user\", get(get_current_user).put(update_user));\n",
);
assert_eq!(names(&result.nodes), vec!["GET /user", "PUT /user"]);
assert_eq!(
reference_names(&result.references),
vec!["get_current_user", "update_user"]
);
}
#[test]
fn extracts_a_multi_line_axum_route_with_a_namespaced_handler() {
let src = r#"
let app = Router::new()
.route(
"/articles/feed",
get(listing::feed_articles),
);
"#;
let result = RUST_RESOLVER.extract("main.rs", src);
assert_eq!(result.nodes[0].name, "GET /articles/feed");
assert_eq!(result.references[0].reference_name, "feed_articles");
}
#[test]
fn extracts_actix_web_resource_route_web_method_to_handler() {
let result = RUST_RESOLVER.extract(
"main.rs",
"App::new().service(web::resource(\"/user/{id}\").route(web::get().to(get_user)))\n",
);
assert_eq!(result.nodes[0].name, "GET /user/{id}");
assert_eq!(result.references[0].reference_name, "get_user");
}
#[test]
fn extracts_actix_web_resource_to_handler_all_methods() {
let result = RUST_RESOLVER.extract(
"main.rs",
"App::new().service(web::resource(\"/\").to(index))\n",
);
assert_eq!(result.nodes[0].name, "ANY /");
assert_eq!(result.references[0].reference_name, "index");
}
#[test]
fn extracts_actix_app_level_route_path_web_method_to_handler() {
let result = RUST_RESOLVER.extract(
"main.rs",
"App::new().route(\"/health\", web::get().to(health_check))\n",
);
assert_eq!(result.nodes[0].name, "GET /health");
assert_eq!(result.references[0].reference_name, "health_check");
}
}
mod rust_resolver_resolve_cargo_workspace_crates {
use super::*;
fn rust_module(id: &str, name: &str, file_path: &str) -> Node {
node(
id,
NodeKind::Module,
name,
&format!("{file_path}::{name}"),
file_path,
Language::Rust,
1,
1,
)
}
#[test]
fn resolves_crate_name_from_workspace_member_lib_rs() {
let lib_node = rust_module(
"module:crates/mytool-core/src/lib.rs:mytool_core:1",
"mytool_core",
"crates/mytool-core/src/lib.rs",
);
let mut context = MockResolutionContext::with_nodes(vec![lib_node.clone()])
.with_file_contents(&[
(
"Cargo.toml",
r#"
[workspace]
members = ["crates/mytool-core", "crates/mytool-fetcher"]
"#,
),
(
"crates/mytool-core/Cargo.toml",
r#"
[package]
name = "mytool-core"
version = "0.1.0"
"#,
),
])
.with_files(&["crates/mytool-core/src/lib.rs"])
.with_all_files(&[
"Cargo.toml",
"crates/mytool-core/Cargo.toml",
"crates/mytool-core/src/lib.rs",
]);
let reference = unresolved_ref(
"fn:crates/mytool-fetcher/src/main.rs:main:1",
"mytool_core",
ReferenceKind::References,
"crates/mytool-fetcher/src/main.rs",
Language::Rust,
);
let result = RUST_RESOLVER
.resolve(&reference, &mut context)
.expect("workspace lib crate should resolve");
assert_eq!(result.target_node_id, lib_node.id);
assert_eq!(result.resolved_by, ResolvedBy::Framework);
assert!(result.confidence >= 0.9);
}
#[test]
fn resolves_crate_name_from_workspace_member_main_rs_when_lib_rs_is_absent() {
let main_node = rust_module(
"module:crates/mytool-runner/src/main.rs:mytool_runner:1",
"mytool_runner",
"crates/mytool-runner/src/main.rs",
);
let mut context = MockResolutionContext::with_nodes(vec![main_node.clone()])
.with_file_contents(&[
(
"Cargo.toml",
r#"
[workspace]
members = [
"crates/mytool-runner",
]
"#,
),
(
"crates/mytool-runner/Cargo.toml",
r#"
[package]
name = "mytool-runner"
version = "0.1.0"
"#,
),
])
.with_files(&["crates/mytool-runner/src/main.rs"])
.with_all_files(&[
"Cargo.toml",
"crates/mytool-runner/Cargo.toml",
"crates/mytool-runner/src/main.rs",
]);
let reference = unresolved_ref(
"fn:crates/mytool-runner/src/main.rs:main:1",
"mytool_runner",
ReferenceKind::References,
"crates/mytool-runner/src/main.rs",
Language::Rust,
);
let result = RUST_RESOLVER
.resolve(&reference, &mut context)
.expect("workspace bin crate should resolve");
assert_eq!(result.target_node_id, main_node.id);
assert_eq!(result.resolved_by, ResolvedBy::Framework);
}
#[test]
fn resolves_crate_name_when_members_uses_a_glob_crates_star() {
let foo_lib = rust_module(
"module:crates/mytool-foo/src/lib.rs:mytool_foo:1",
"mytool_foo",
"crates/mytool-foo/src/lib.rs",
);
let bar_lib = rust_module(
"module:crates/mytool-bar/src/lib.rs:mytool_bar:1",
"mytool_bar",
"crates/mytool-bar/src/lib.rs",
);
let mut context = cargo_workspace_context(
&[
(
"Cargo.toml",
r#"
[workspace]
members = ["crates/*"]
"#,
),
(
"crates/mytool-foo/Cargo.toml",
r#"
[package]
name = "mytool-foo"
version = "0.1.0"
"#,
),
(
"crates/mytool-bar/Cargo.toml",
r#"
[package]
name = "mytool-bar"
version = "0.1.0"
"#,
),
],
&[
("crates/mytool-foo/src/lib.rs", vec![foo_lib.clone()]),
("crates/mytool-bar/src/lib.rs", vec![bar_lib.clone()]),
],
&[
(".", &["crates"]),
("crates", &["mytool-foo", "mytool-bar"]),
("crates/mytool-foo", &["src"]),
("crates/mytool-bar", &["src"]),
],
);
let foo_ref = unresolved_ref(
"fn:crates/mytool-bar/src/lib.rs:other:1",
"mytool_foo",
ReferenceKind::References,
"crates/mytool-bar/src/lib.rs",
Language::Rust,
);
let bar_ref = unresolved_ref(
"fn:crates/mytool-foo/src/lib.rs:other:1",
"mytool_bar",
ReferenceKind::References,
"crates/mytool-foo/src/lib.rs",
Language::Rust,
);
assert_eq!(
RUST_RESOLVER
.resolve(&foo_ref, &mut context)
.expect("foo crate should resolve")
.target_node_id,
foo_lib.id
);
assert_eq!(
RUST_RESOLVER
.resolve(&bar_ref, &mut context)
.expect("bar crate should resolve")
.target_node_id,
bar_lib.id
);
}
#[test]
fn resolves_crate_name_when_members_uses_a_name_glob_at_root_helix_star() {
let core_lib = rust_module(
"module:helix-core/src/lib.rs:helix_core:1",
"helix_core",
"helix-core/src/lib.rs",
);
let mut context = cargo_workspace_context(
&[
(
"Cargo.toml",
r#"
[workspace]
members = ["helix-*"]
"#,
),
(
"helix-core/Cargo.toml",
r#"
[package]
name = "helix-core"
version = "0.1.0"
"#,
),
],
&[("helix-core/src/lib.rs", vec![core_lib.clone()])],
&[
(".", &["helix-core", "docs", "target"]),
("helix-core", &["src"]),
],
);
let reference = unresolved_ref(
"fn:helix-core/src/lib.rs:other:1",
"helix_core",
ReferenceKind::References,
"helix-core/src/lib.rs",
Language::Rust,
);
assert_eq!(
RUST_RESOLVER
.resolve(&reference, &mut context)
.expect("helix-core should resolve")
.target_node_id,
core_lib.id
);
}
}