use faucet_cli::config::PipelineConfig;
use faucet_cli::error::CliError;
use faucet_cli::expand::expand;
use std::path::PathBuf;
fn examples_dir() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("examples")
}
fn is_credential_error(e: &CliError) -> bool {
matches!(
e,
CliError::MissingEnvVar { .. }
| CliError::ReadInterpolatedFile { .. }
| CliError::SecretsRequireAsyncLoad
)
}
#[test]
fn every_example_loads_and_expands() {
let dir = examples_dir();
let mut count = 0;
let mut skipped = 0;
let mut failures: Vec<String> = Vec::new();
for entry in std::fs::read_dir(&dir).expect("examples dir exists") {
let path = entry.expect("readable dir entry").path();
let Some(ext) = path.extension().and_then(|e| e.to_str()) else {
continue;
};
if !matches!(ext, "yaml" | "yml" | "json") {
continue;
}
if path.file_name().and_then(|f| f.to_str()) == Some("serve_minimal.yaml") {
skipped += 1;
continue;
}
#[cfg(not(feature = "schedule"))]
{
let yaml_text = std::fs::read_to_string(&path).unwrap_or_default();
if yaml_text.contains("\nschedule:") || yaml_text.starts_with("schedule:") {
skipped += 1;
continue;
}
}
count += 1;
let cfg = match PipelineConfig::from_path(&path) {
Ok(c) => c,
Err(ref e) if is_credential_error(e) => {
skipped += 1;
continue;
}
Err(e) => {
failures.push(format!("load {}: {e}", path.display()));
continue;
}
};
if let Err(e) = expand(&cfg) {
failures.push(format!("expand {}: {e}", path.display()));
}
}
assert!(count > 10, "expected to find >10 examples, found {count}");
eprintln!(
"examples: {count} total, {skipped} skipped (missing credentials), {} checked",
count - skipped
);
assert!(
failures.is_empty(),
"{} example(s) failed:\n{}",
failures.len(),
failures.join("\n")
);
}
#[test]
fn serve_minimal_default_config_parses() {
let path = examples_dir().join("serve_minimal.yaml");
PipelineConfig::from_path(&path)
.expect("serve_minimal.yaml must parse as a valid PipelineConfig");
}