Rust project project model smoke tests

This commit is contained in:
Toby Fleming 2021-07-31 22:47:21 -07:00
parent cb13e4a2ca
commit d0b98060d4
No known key found for this signature in database
GPG key ID: 0282BB3D7A935102
14 changed files with 552 additions and 26 deletions

View file

@ -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();
}

View 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
}
]
}

View 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
}
]
}