use super::*;
const MINIMAL_CONFIG: &str = r#"
project = "p"
experiment_name = "e"
sample_rate = 8
clip_duration_seconds = 0.5
[source_data]
type = "tabular"
path = "m.json"
[target_audio]
path = "audio"
[data_encoder]
type = "vector"
latent_dim = 2
[audio_codec]
type = "pcm"
latent_type = "continuous"
[conditional_generator]
type = "mlp"
[training]
batch_size = 1
learning_rate = 0.001
max_steps = 1
"#;
fn recipe_fp(cfg: &RawExperimentConfig) -> RecipeFingerprint {
let spec = cfg.clone().resolve().expect("resolve");
RecipeFingerprint::of(&spec.recipe()).expect("recipe fingerprint")
}
fn config_fp(cfg: &RawExperimentConfig) -> ConfigFingerprint {
ConfigFingerprint::of(cfg).expect("config fingerprint")
}
#[test]
fn recipe_fingerprint_ignores_generation_but_tracks_recipe_fields() {
let base = RawExperimentConfig::from_toml_str(MINIMAL_CONFIG).unwrap();
let mut tuned = base.clone();
tuned.generation.guidance_scale = 9.0;
tuned.generation.temperature = 0.5;
tuned.generation.num_candidates = 4;
assert_eq!(recipe_fp(&base), recipe_fp(&tuned));
assert_ne!(config_fp(&base), config_fp(&tuned));
let mut rerecipe = base.clone();
rerecipe.training.learning_rate = 0.5;
assert_ne!(recipe_fp(&base), recipe_fp(&rerecipe));
}
#[test]
fn fingerprints_are_stable_across_load_save_cycles() {
let a = RawExperimentConfig::from_toml_str(MINIMAL_CONFIG).unwrap();
let b = RawExperimentConfig::from_toml_str(MINIMAL_CONFIG).unwrap();
assert_eq!(recipe_fp(&a), recipe_fp(&b));
assert_eq!(config_fp(&a), config_fp(&b));
let json = a.to_json_string().unwrap();
let reparsed = RawExperimentConfig::from_json_str(&json).unwrap();
assert_eq!(recipe_fp(&a), recipe_fp(&reparsed));
assert_eq!(config_fp(&a), config_fp(&reparsed));
}
#[test]
fn fingerprints_display_as_sha256() {
let cfg = RawExperimentConfig::from_toml_str(MINIMAL_CONFIG).unwrap();
assert!(config_fp(&cfg).to_string().starts_with("sha256:"));
assert!(recipe_fp(&cfg).to_string().starts_with("sha256:"));
}
#[test]
fn spec_convenience_methods_match_standalone_constructors() {
let cfg = RawExperimentConfig::from_toml_str(MINIMAL_CONFIG).unwrap();
let spec = cfg.clone().resolve().unwrap();
assert_eq!(spec.config_fingerprint().unwrap(), config_fp(&cfg));
assert_eq!(spec.recipe_fingerprint().unwrap(), recipe_fp(&cfg));
}