#![allow(clippy::unwrap_used)]
use std::{fs, path::Path};
use tempfile::TempDir;
use super::{ConfigSource, PROJECT_CONFIG_FILE};
fn repo() -> TempDir {
let dir = tempfile::tempdir().unwrap();
fs::create_dir(dir.path().join(".git")).unwrap();
dir
}
fn touch(path: &Path) {
fs::create_dir_all(path.parent().unwrap()).unwrap();
fs::write(path, "").unwrap();
}
#[test]
fn a_schema_compiles_with_the_config_of_its_own_subgraph() {
let root = repo();
let alpha = root.path().join("alpha");
let beta = root.path().join("beta");
touch(&alpha.join(PROJECT_CONFIG_FILE));
touch(&beta.join(PROJECT_CONFIG_FILE));
touch(&alpha.join("schema/schema.json"));
let source = ConfigSource::resolve(&alpha.join("schema/schema.json"), None).unwrap();
assert_eq!(source, ConfigSource::Discovered(alpha.join(PROJECT_CONFIG_FILE)));
}
#[test]
fn the_nearest_config_wins() {
let root = repo();
touch(&root.path().join(PROJECT_CONFIG_FILE));
touch(&root.path().join("sub").join(PROJECT_CONFIG_FILE));
let schema = root.path().join("sub/schema.json");
touch(&schema);
let source = ConfigSource::resolve(&schema, None).unwrap();
assert_eq!(
source,
ConfigSource::Discovered(root.path().join("sub").join(PROJECT_CONFIG_FILE))
);
}
#[test]
fn discovery_stops_at_the_repository_root() {
let outer = tempfile::tempdir().unwrap();
touch(&outer.path().join(PROJECT_CONFIG_FILE));
let root = outer.path().join("repo");
fs::create_dir_all(root.join(".git")).unwrap();
let schema = root.join("schema.json");
touch(&schema);
let source = ConfigSource::resolve(&schema, None).unwrap();
assert_eq!(
source,
ConfigSource::Absent {
searched_from: root,
}
);
}
#[test]
fn an_explicit_config_wins_over_discovery() {
let root = repo();
touch(&root.path().join(PROJECT_CONFIG_FILE));
let other = root.path().join("other.toml");
touch(&other);
let schema = root.path().join("schema.json");
touch(&schema);
let source = ConfigSource::resolve(&schema, Some(&other)).unwrap();
assert_eq!(source, ConfigSource::Explicit(other));
}
#[test]
fn an_explicit_config_that_does_not_exist_is_refused() {
let root = repo();
let schema = root.path().join("schema.json");
touch(&schema);
let message = ConfigSource::resolve(&schema, Some(&root.path().join("missing.toml")))
.unwrap_err()
.to_string();
assert!(
message.contains("missing.toml") && message.contains("no such file"),
"{message}"
);
}
#[test]
fn a_toml_input_is_its_own_config_and_refuses_another() {
let root = repo();
let input = root.path().join(PROJECT_CONFIG_FILE);
touch(&input);
assert_eq!(ConfigSource::resolve(&input, None).unwrap(), ConfigSource::Input(input.clone()));
let message = ConfigSource::resolve(&input, Some(&input)).unwrap_err().to_string();
assert!(message.contains("already the project config"), "{message}");
}
#[test]
fn the_source_describes_itself() {
let absent = ConfigSource::Absent {
searched_from: "/srv/app".into(),
};
assert!(absent.to_string().contains("defaults apply"), "{absent}");
assert!(absent.project_config().is_none());
let found = ConfigSource::Discovered("/srv/app/fraiseql.toml".into());
assert_eq!(found.project_config(), Some(Path::new("/srv/app/fraiseql.toml")));
}