use super::*;
fn write_layout_fixture(root: &Path) {
std::fs::write(
root.join("package.json"),
r#"{"name":"root","private":true}"#,
)
.unwrap();
std::fs::write(
root.join("pnpm-workspace.yaml"),
"packages:\n - packages/*\n - vite\n - vite/packages/*\n",
)
.unwrap();
write_package(&root.join("packages/core"), r#"{"name":"@demo/core"}"#);
write_package(&root.join("bench"), r#"{"type":"module"}"#);
write_package(
&root.join("docs"),
r#"{"name":"demo-docs","private":true,"dependencies":{"vue":"^3.5.0"}}"#,
);
std::fs::write(root.join("docs/pnpm-workspace.yaml"), "packages:\n - .\n").unwrap();
write_package(&root.join("docs/theme"), r#"{"name":"docs-theme"}"#);
}
fn diagnostics_of_kind<'a>(
diagnostics: &'a [WorkspaceDiagnostic],
id: &str,
) -> Vec<&'a WorkspaceDiagnostic> {
diagnostics.iter().filter(|d| d.kind.id() == id).collect()
}
#[test]
fn undeclared_skips_manifest_without_name_or_dependencies() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let declared = discover_workspaces(dir.path());
let undeclared = find_undeclared_workspaces(dir.path(), &declared);
assert!(
undeclared.iter().all(|d| !d.path.ends_with("bench")),
"a manifest with no name and no dependencies is not a package: {undeclared:?}"
);
}
#[test]
fn undeclared_still_reports_nameless_manifest_with_dependencies() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
write_package(
&dir.path().join("bench"),
r#"{"type":"module","devDependencies":{"tinybench":"^2.0.0"}}"#,
);
let declared = discover_workspaces(dir.path());
let undeclared = find_undeclared_workspaces(dir.path(), &declared);
assert!(
undeclared.iter().any(|d| d.path.ends_with("bench")),
"{undeclared:?}"
);
}
#[test]
fn nested_pnpm_project_is_registered_with_diagnostic() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let (workspaces, diagnostics) =
discover_workspaces_with_diagnostics(dir.path(), &crate::IgnorePatternSet::empty())
.expect("valid root");
assert!(
workspaces.iter().any(|ws| ws.name == "demo-docs"),
"{workspaces:?}"
);
let nested = diagnostics_of_kind(&diagnostics, "nested-project-root");
let [diagnostic] = nested.as_slice() else {
panic!("expected one nested-project-root diagnostic: {diagnostics:?}");
};
assert_eq!(diagnostic.path, dir.path().join("docs"));
assert!(!diagnostic.degrades_analysis);
}
#[test]
fn nested_pnpm_project_children_are_not_undeclared() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let declared = discover_workspaces(dir.path());
let undeclared = find_undeclared_workspaces(dir.path(), &declared);
assert!(undeclared.is_empty(), "{undeclared:?}");
}
#[test]
fn nested_pnpm_project_declared_by_config_pattern_has_no_diagnostic() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let (workspaces, diagnostics) = discover_workspaces_with_diagnostics_and_patterns(
dir.path(),
&crate::IgnorePatternSet::empty(),
&["docs".to_owned()],
)
.expect("valid root");
assert_eq!(
workspaces
.iter()
.filter(|ws| ws.name == "demo-docs")
.count(),
1,
"{workspaces:?}"
);
assert!(
diagnostics_of_kind(&diagnostics, "nested-project-root").is_empty(),
"{diagnostics:?}"
);
}
#[test]
fn nested_pnpm_project_honors_ignore_patterns() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let (workspaces, diagnostics) =
discover_workspaces_with_diagnostics(dir.path(), &build_globset(&["docs/**"]))
.expect("valid root");
assert!(
workspaces.iter().all(|ws| ws.name != "demo-docs"),
"{workspaces:?}"
);
assert!(
diagnostics_of_kind(&diagnostics, "nested-project-root").is_empty(),
"{diagnostics:?}"
);
}
#[test]
fn nested_pnpm_project_is_not_independent_when_a_manifest_pattern_declares_it() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
std::fs::write(
dir.path().join("pnpm-workspace.yaml"),
"packages:\n - packages/*\n - docs\n",
)
.unwrap();
let (_, diagnostics) =
discover_workspaces_with_diagnostics(dir.path(), &crate::IgnorePatternSet::empty())
.expect("valid root");
assert!(
diagnostics_of_kind(&diagnostics, "nested-project-root").is_empty(),
"{diagnostics:?}"
);
assert!(!is_independent_pnpm_project(
dir.path(),
&dir.path().join("docs")
));
}
#[test]
fn independent_pnpm_project_detection() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
assert!(is_independent_pnpm_project(
dir.path(),
&dir.path().join("docs")
));
assert!(!is_independent_pnpm_project(
dir.path(),
&dir.path().join("packages/core")
));
assert!(!is_independent_pnpm_project(dir.path(), dir.path()));
}
#[test]
fn missing_pattern_dir_emits_diagnostic_with_declaring_file() {
let dir = tempfile::tempdir().expect("create temp dir");
write_layout_fixture(dir.path());
let (_, diagnostics) =
discover_workspaces_with_diagnostics(dir.path(), &crate::IgnorePatternSet::empty())
.expect("valid root");
let missing: Vec<(&Path, &WorkspaceDiagnosticKind)> =
diagnostics_of_kind(&diagnostics, "workspace-pattern-dir-missing")
.into_iter()
.map(|d| (d.path.as_path(), &d.kind))
.collect();
let yaml = dir.path().join("pnpm-workspace.yaml");
assert_eq!(
missing,
[
(
yaml.as_path(),
&WorkspaceDiagnosticKind::WorkspacePatternDirMissing {
pattern: "vite".to_owned()
}
),
(
yaml.as_path(),
&WorkspaceDiagnosticKind::WorkspacePatternDirMissing {
pattern: "vite/packages/*".to_owned()
}
),
]
);
assert!(has_missing_workspace_pattern_dirs(dir.path(), &[]));
}
#[test]
fn missing_configured_pattern_dir_is_anchored_at_the_root() {
let dir = tempfile::tempdir().expect("create temp dir");
std::fs::write(dir.path().join("package.json"), r#"{"name":"root"}"#).unwrap();
let (_, diagnostics) = discover_workspaces_with_diagnostics_and_patterns(
dir.path(),
&crate::IgnorePatternSet::empty(),
&["vendor/*".to_owned()],
)
.expect("valid root");
let [diagnostic] = diagnostics.as_slice() else {
panic!("expected one diagnostic: {diagnostics:?}");
};
assert_eq!(diagnostic.path, Path::new("."));
assert_eq!(diagnostic.kind.id(), "workspace-pattern-dir-missing");
assert!(has_missing_workspace_pattern_dirs(
dir.path(),
&["vendor/*".to_owned()]
));
assert!(!has_missing_workspace_pattern_dirs(dir.path(), &[]));
}
#[test]
fn existing_dir_with_no_match_emits_no_missing_dir_diagnostic() {
let dir = tempfile::tempdir().expect("create temp dir");
std::fs::write(
dir.path().join("package.json"),
r#"{"name":"root","workspaces":["packages/*","!vite"]}"#,
)
.unwrap();
std::fs::create_dir_all(dir.path().join("packages")).unwrap();
let (_, diagnostics) =
discover_workspaces_with_diagnostics(dir.path(), &crate::IgnorePatternSet::empty())
.expect("valid root");
assert!(
diagnostics_of_kind(&diagnostics, "workspace-pattern-dir-missing").is_empty(),
"{diagnostics:?}"
);
assert!(!has_missing_workspace_pattern_dirs(dir.path(), &[]));
}
#[test]
fn recursive_pattern_without_literal_prefix_is_never_missing() {
let dir = tempfile::tempdir().expect("create temp dir");
std::fs::write(
dir.path().join("package.json"),
r#"{"name":"root","workspaces":["**/pkg","{a,b}/*"]}"#,
)
.unwrap();
assert!(!has_missing_workspace_pattern_dirs(dir.path(), &[]));
}