#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use std::path::{Path, PathBuf};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use rustc_hash::{FxHashMap, FxHashSet};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use fallow_config::{
BoundaryConfig, FallowConfig, OutputFormat, PackageJson, ResolvedConfig, WorkspaceInfo,
};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use fallow_types::discover::{DiscoveredFile, EntryPoint, EntryPointSource, FileId};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use fallow_types::extract::{ImportInfo, ImportedName};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use crate::graph::ModuleGraph;
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use crate::plugins::AggregatedPluginResult;
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use crate::resolve::{ResolveResult, ResolvedImport, ResolvedModule};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use crate::results::*;
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use crate::suppress::{self, Suppression, SuppressionContext};
#[allow(unused_imports, reason = "shared re-export for sibling test modules")]
pub(super) use super::super::{
DepCategoryConfig, LineOffsetsMap, SharedDepSets, collect_unused_for_category,
find_import_location, find_test_only_dependencies, find_type_only_dependencies,
find_unlisted_dependencies, find_unresolved_imports, find_unused_dependencies,
is_package_listed_for_file, should_skip_dependency,
};
pub(super) fn test_config(root: PathBuf) -> ResolvedConfig {
FallowConfig::default().resolve(root, OutputFormat::Human, 1, true, true)
}
pub(super) fn make_pkg(deps: &[&str], dev_deps: &[&str], optional_deps: &[&str]) -> PackageJson {
let to_obj = |names: &[&str]| -> serde_json::Value {
let map: serde_json::Map<String, serde_json::Value> = names
.iter()
.map(|n| {
(
n.to_string(),
serde_json::Value::String("^1.0.0".to_string()),
)
})
.collect();
serde_json::Value::Object(map)
};
let mut obj = serde_json::Map::new();
obj.insert(
"name".to_string(),
serde_json::Value::String("test-project".to_string()),
);
if !deps.is_empty() {
obj.insert("dependencies".to_string(), to_obj(deps));
}
if !dev_deps.is_empty() {
obj.insert("devDependencies".to_string(), to_obj(dev_deps));
}
if !optional_deps.is_empty() {
obj.insert("optionalDependencies".to_string(), to_obj(optional_deps));
}
serde_json::from_value(serde_json::Value::Object(obj))
.expect("test PackageJson should deserialize")
}
#[expect(
clippy::cast_possible_truncation,
reason = "test span values are trivially small"
)]
pub(super) fn build_graph_with_npm_imports(
npm_packages: &[(&str, bool)], ) -> (ModuleGraph, Vec<ResolvedModule>) {
let files = vec![DiscoveredFile {
id: FileId(0),
path: PathBuf::from("/project/src/index.ts"),
size_bytes: 100,
}];
let entry_points = vec![EntryPoint {
path: PathBuf::from("/project/src/index.ts"),
source: EntryPointSource::PackageJsonMain,
}];
let resolved_imports: Vec<ResolvedImport> = npm_packages
.iter()
.enumerate()
.map(|(i, (name, is_type_only))| ResolvedImport {
info: ImportInfo {
source: name.to_string(),
imported_name: ImportedName::Named("default".to_string()),
local_name: format!("import_{i}"),
is_type_only: *is_type_only,
span: oxc_span::Span::new((i * 20) as u32, (i * 20 + 15) as u32),
source_span: oxc_span::Span::default(),
},
target: ResolveResult::NpmPackage(name.to_string()),
})
.collect();
let resolved_modules = vec![ResolvedModule {
file_id: FileId(0),
path: PathBuf::from("/project/src/index.ts"),
exports: vec![],
re_exports: vec![],
resolved_imports,
resolved_dynamic_imports: vec![],
resolved_dynamic_patterns: vec![],
member_accesses: vec![],
whole_object_uses: vec![],
has_cjs_exports: false,
unused_import_bindings: FxHashSet::default(),
}];
let graph = ModuleGraph::build(&resolved_modules, &entry_points, &files);
(graph, resolved_modules)
}
pub(super) type SkipDepSets = (
FxHashSet<String>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
);
pub(super) fn empty_sets() -> SkipDepSets {
(
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
)
}
pub(super) type SharedSets = (
FxHashSet<&'static str>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
FxHashSet<&'static str>,
);
pub(super) fn empty_shared_sets() -> SharedSets {
(
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
FxHashSet::default(),
)
}