mod common;
use common::{touch, write};
use projectdetect::Registry;
use tempfile::tempdir;
fn detects(reg: &Registry, dir: &std::path::Path, want_type: &str) -> bool {
reg.detect(dir).iter().any(|m| m.r#type == want_type)
}
#[test]
fn mixed_indicators() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
r#"
project_types:
- name: helm-chart
indicators:
- has_file: Chart.yaml
- name: tf-stack
indicators:
- has_glob: "*.tf"
"#,
);
let mut reg = Registry::new();
let n = reg.load_from_file(tmp.path().join("types.yaml")).unwrap();
assert_eq!(n, 2);
let chart = tempdir().unwrap();
touch(chart.path(), "Chart.yaml");
assert!(detects(®, chart.path(), "helm-chart"));
let tf = tempdir().unwrap();
touch(tf.path(), "main.tf");
assert!(detects(®, tf.path(), "tf-stack"));
}
#[test]
fn subdir_glob_indicator() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
"project_types:\n - name: xcode-app\n indicators:\n - has_subdir_glob: \"*.xcodeproj\"\n",
);
let mut reg = Registry::new();
assert_eq!(
reg.load_from_file(tmp.path().join("types.yaml")).unwrap(),
1
);
let bundle = tempdir().unwrap();
common::mkdir(bundle.path(), "MyApp.xcodeproj");
assert!(detects(®, bundle.path(), "xcode-app"));
let as_file = tempdir().unwrap();
touch(as_file.path(), "MyApp.xcodeproj");
assert!(!detects(®, as_file.path(), "xcode-app"));
}
#[test]
fn missing_indicators_errors() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
"project_types:\n - name: missing\n",
);
let mut reg = Registry::new();
assert!(reg.load_from_file(tmp.path().join("types.yaml")).is_err());
}
#[cfg(not(feature = "cel"))]
#[test]
fn cel_disabled_errors() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
"project_types:\n - name: c\n indicators:\n - cel: '\"x\" in files'\n",
);
let mut reg = Registry::new();
assert!(reg.load_from_file(tmp.path().join("types.yaml")).is_err());
}
#[cfg(feature = "cel")]
#[test]
fn cel_indicator_and_semantics() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
"project_types:\n - name: my-app\n indicators:\n - cel: '\"services\" in subdirs && \"foo.yaml\" in files'\n",
);
let mut reg = Registry::new();
assert_eq!(
reg.load_from_file(tmp.path().join("types.yaml")).unwrap(),
1
);
let yes = tempdir().unwrap();
common::mkdir(yes.path(), "services");
touch(yes.path(), "foo.yaml");
assert!(detects(®, yes.path(), "my-app"));
let no = tempdir().unwrap();
touch(no.path(), "foo.yaml");
assert!(!detects(®, no.path(), "my-app"));
}
#[cfg(feature = "cel")]
#[test]
fn bad_cel_errors() {
let tmp = tempdir().unwrap();
write(
tmp.path(),
"types.yaml",
"project_types:\n - name: broken\n indicators:\n - cel: 'this is not valid cel ((('\n",
);
let mut reg = Registry::new();
assert!(reg.load_from_file(tmp.path().join("types.yaml")).is_err());
}