mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Rust project project model smoke tests
This commit is contained in:
parent
cb13e4a2ca
commit
d0b98060d4
14 changed files with 552 additions and 26 deletions
|
@ -1,12 +1,20 @@
|
||||||
use std::path::PathBuf;
|
use std::{
|
||||||
|
ops::Deref,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use base_db::FileId;
|
use base_db::{CrateGraph, FileId};
|
||||||
use expect_test::{expect, Expect};
|
use expect_test::{expect, Expect};
|
||||||
|
use paths::AbsPath;
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
|
||||||
use crate::{CargoWorkspace, CfgOverrides, ProjectWorkspace, Sysroot, WorkspaceBuildScripts};
|
use crate::{
|
||||||
|
CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot,
|
||||||
|
WorkspaceBuildScripts,
|
||||||
|
};
|
||||||
|
|
||||||
fn check(file: &str, expect: Expect) {
|
fn load_cargo(file: &str) -> CrateGraph {
|
||||||
let meta = get_test_metadata(file);
|
let meta = get_test_json_file(file);
|
||||||
let cargo_workspace = CargoWorkspace::new(meta);
|
let cargo_workspace = CargoWorkspace::new(meta);
|
||||||
let project_workspace = ProjectWorkspace::Cargo {
|
let project_workspace = ProjectWorkspace::Cargo {
|
||||||
cargo: cargo_workspace,
|
cargo: cargo_workspace,
|
||||||
|
@ -16,23 +24,21 @@ fn check(file: &str, expect: Expect) {
|
||||||
rustc_cfg: Vec::new(),
|
rustc_cfg: Vec::new(),
|
||||||
cfg_overrides: CfgOverrides::default(),
|
cfg_overrides: CfgOverrides::default(),
|
||||||
};
|
};
|
||||||
|
to_crate_graph(project_workspace)
|
||||||
let crate_graph = project_workspace.to_crate_graph(None, {
|
|
||||||
let mut counter = 0;
|
|
||||||
&mut move |_path| {
|
|
||||||
counter += 1;
|
|
||||||
Some(FileId(counter))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut crate_graph = format!("{:#?}", crate_graph);
|
|
||||||
replace_root(&mut crate_graph, false);
|
|
||||||
|
|
||||||
expect.assert_eq(&crate_graph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_test_metadata(file: &str) -> cargo_metadata::Metadata {
|
fn load_rust_project(file: &str) -> CrateGraph {
|
||||||
let mut json = get_test_data(file).parse::<serde_json::Value>().unwrap();
|
let data = get_test_json_file(file);
|
||||||
|
let project = rooted_project_json(data);
|
||||||
|
let sysroot = Some(get_fake_sysroot());
|
||||||
|
let project_workspace = ProjectWorkspace::Json { project, sysroot, rustc_cfg: Vec::new() };
|
||||||
|
to_crate_graph(project_workspace)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_test_json_file<T: DeserializeOwned>(file: &str) -> T {
|
||||||
|
let file = get_test_path(file);
|
||||||
|
let data = std::fs::read_to_string(file).unwrap();
|
||||||
|
let mut json = data.parse::<serde_json::Value>().unwrap();
|
||||||
fixup_paths(&mut json);
|
fixup_paths(&mut json);
|
||||||
return serde_json::from_value(json).unwrap();
|
return serde_json::from_value(json).unwrap();
|
||||||
|
|
||||||
|
@ -58,16 +64,46 @@ fn replace_root(s: &mut String, direction: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_test_data(file: &str) -> String {
|
fn get_test_path(file: &str) -> PathBuf {
|
||||||
let base = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
let base = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
let file = base.join("test_data").join(file);
|
base.join("test_data").join(file)
|
||||||
std::fs::read_to_string(file).unwrap()
|
}
|
||||||
|
|
||||||
|
fn get_fake_sysroot() -> Sysroot {
|
||||||
|
let sysroot_path = get_test_path("fake-sysroot");
|
||||||
|
let sysroot_src_dir = AbsPath::assert(&sysroot_path);
|
||||||
|
Sysroot::load(&sysroot_src_dir).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rooted_project_json(data: ProjectJsonData) -> ProjectJson {
|
||||||
|
let mut root = "$ROOT$".to_string();
|
||||||
|
replace_root(&mut root, true);
|
||||||
|
let path = Path::new(&root);
|
||||||
|
let base = AbsPath::assert(path);
|
||||||
|
ProjectJson::new(base, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
|
||||||
|
project_workspace.to_crate_graph(None, {
|
||||||
|
let mut counter = 0;
|
||||||
|
&mut move |_path| {
|
||||||
|
counter += 1;
|
||||||
|
Some(FileId(counter))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_crate_graph(crate_graph: CrateGraph, expect: Expect) {
|
||||||
|
let mut crate_graph = format!("{:#?}", crate_graph);
|
||||||
|
replace_root(&mut crate_graph, false);
|
||||||
|
expect.assert_eq(&crate_graph);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn hello_world_project_model() {
|
fn cargo_hello_world_project_model() {
|
||||||
check(
|
let crate_graph = load_cargo("hello-world-metadata.json");
|
||||||
"hello-world-metadata.json",
|
check_crate_graph(
|
||||||
|
crate_graph,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
CrateGraph {
|
CrateGraph {
|
||||||
arena: {
|
arena: {
|
||||||
|
@ -514,3 +550,468 @@ fn hello_world_project_model() {
|
||||||
}"#]],
|
}"#]],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_project_hello_world_project_model() {
|
||||||
|
let crate_graph = load_rust_project("hello-world-project.json");
|
||||||
|
check_crate_graph(
|
||||||
|
crate_graph,
|
||||||
|
expect![[r#"
|
||||||
|
CrateGraph {
|
||||||
|
arena: {
|
||||||
|
CrateId(
|
||||||
|
0,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"alloc",
|
||||||
|
),
|
||||||
|
canonical_name: "alloc",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"core",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
10,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
11,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"unwind",
|
||||||
|
),
|
||||||
|
canonical_name: "unwind",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
7,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
8,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"std_detect",
|
||||||
|
),
|
||||||
|
canonical_name: "std_detect",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
4,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
5,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"proc_macro",
|
||||||
|
),
|
||||||
|
canonical_name: "proc_macro",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
6,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"std",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
1,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"core",
|
||||||
|
),
|
||||||
|
canonical_name: "core",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
11,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
12,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"hello_world",
|
||||||
|
),
|
||||||
|
canonical_name: "hello_world",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"core",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"alloc",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
6,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"std",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
8,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
9,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"term",
|
||||||
|
),
|
||||||
|
canonical_name: "term",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
5,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
6,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"profiler_builtins",
|
||||||
|
),
|
||||||
|
canonical_name: "profiler_builtins",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
2,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"panic_abort",
|
||||||
|
),
|
||||||
|
canonical_name: "panic_abort",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
9,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
10,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"test",
|
||||||
|
),
|
||||||
|
canonical_name: "test",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
6,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
7,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"std",
|
||||||
|
),
|
||||||
|
canonical_name: "std",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
0,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"alloc",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
1,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"core",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"panic_abort",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
3,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"panic_unwind",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
5,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"profiler_builtins",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
7,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"std_detect",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
8,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"term",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
9,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"test",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
Dependency {
|
||||||
|
crate_id: CrateId(
|
||||||
|
10,
|
||||||
|
),
|
||||||
|
name: CrateName(
|
||||||
|
"unwind",
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
CrateId(
|
||||||
|
3,
|
||||||
|
): CrateData {
|
||||||
|
root_file_id: FileId(
|
||||||
|
4,
|
||||||
|
),
|
||||||
|
edition: Edition2018,
|
||||||
|
display_name: Some(
|
||||||
|
CrateDisplayName {
|
||||||
|
crate_name: CrateName(
|
||||||
|
"panic_unwind",
|
||||||
|
),
|
||||||
|
canonical_name: "panic_unwind",
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
potential_cfg_options: CfgOptions(
|
||||||
|
[],
|
||||||
|
),
|
||||||
|
env: Env {
|
||||||
|
entries: {},
|
||||||
|
},
|
||||||
|
dependencies: [],
|
||||||
|
proc_macro: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rust_project_is_proc_macro_has_proc_macro_dep() {
|
||||||
|
let crate_graph = load_rust_project("is-proc-macro-project.json");
|
||||||
|
// Since the project only defines one crate (outside the sysroot crates),
|
||||||
|
// it should be the one with the biggest Id.
|
||||||
|
let crate_id = crate_graph.iter().max().unwrap();
|
||||||
|
let crate_data = &crate_graph[crate_id];
|
||||||
|
// Assert that the project crate with `is_proc_macro` has a dependency
|
||||||
|
// on the proc_macro sysroot crate.
|
||||||
|
crate_data.dependencies.iter().find(|&dep| dep.name.deref() == "proc_macro").unwrap();
|
||||||
|
}
|
||||||
|
|
12
crates/project_model/test_data/hello-world-project.json
Normal file
12
crates/project_model/test_data/hello-world-project.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"sysroot_src": null,
|
||||||
|
"crates": [
|
||||||
|
{
|
||||||
|
"display_name": "hello_world",
|
||||||
|
"root_module": "$ROOT$src/lib.rs",
|
||||||
|
"edition": "2018",
|
||||||
|
"deps": [],
|
||||||
|
"is_workspace_member": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
13
crates/project_model/test_data/is-proc-macro-project.json
Normal file
13
crates/project_model/test_data/is-proc-macro-project.json
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"sysroot_src": null,
|
||||||
|
"crates": [
|
||||||
|
{
|
||||||
|
"display_name": "is_proc_macro",
|
||||||
|
"root_module": "$ROOT$src/lib.rs",
|
||||||
|
"edition": "2018",
|
||||||
|
"deps": [],
|
||||||
|
"is_workspace_member": true,
|
||||||
|
"is_proc_macro": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue