use super::fixture::{Fixture, app, command, write}; use dever::compiler::project::Project; use std::process::Command; #[test] fn api_baselines_are_checked_before_build_and_cli_never_overwrites_them() { let fixture = Fixture::new(&[]); let root = &fixture.directory.0; let app_path = "module/demo/value/app.dever"; write(root, app_path, app("input + 1")); write(root, "module/demo/value/api.dever", command()); let baseline = root.join("dever.api"); let output = Command::new(env!("CARGO_BIN_EXE_dever")) .arg("api") .arg(root) .arg("--output") .arg(&baseline) .output() .unwrap(); assert!( output.status.success(), "{}", String::from_utf8_lossy(&output.stderr) ); let before = std::fs::read(&baseline).unwrap(); let output = Command::new(env!("CARGO_BIN_EXE_dever")) .arg("api") .arg(root) .arg("--output") .arg(&baseline) .output() .unwrap(); assert!(!output.status.success()); assert_eq!(before, std::fs::read(&baseline).unwrap()); write(root, app_path, app("input + 2")); assert!(Project::load(root).unwrap().check().is_ok()); write(root, app_path, app("input + 2").replace("input", "renamed")); let output_path = root.join("must_not_build"); for verb in ["check", "run", "build"] { let mut command = Command::new(env!("CARGO_BIN_EXE_dever")); command.arg(verb).arg(root); if verb == "build" { command.arg("--output").arg(&output_path); } let output = command.output().unwrap(); assert!(!output.status.success()); let error = String::from_utf8(output.stderr).unwrap(); assert!( error.contains("public API differs") && error.contains("+ cmd"), "{verb}: {error}" ); } assert!(!output_path.exists()); let reviewed = root.join("proposed.api"); assert!( Command::new(env!("CARGO_BIN_EXE_dever")) .arg("api") .arg(root) .arg("--output") .arg(&reviewed) .output() .unwrap() .status .success() ); assert_eq!(before, std::fs::read(&baseline).unwrap()); assert_ne!(before, std::fs::read(reviewed).unwrap()); std::fs::remove_file(&baseline).unwrap(); std::os::unix::fs::symlink("proposed.api", &baseline).unwrap(); assert!( Project::load(root) .unwrap() .check() .unwrap_err() .contains("project input links") ); } #[test] fn locked_dependency_contract_changes_are_included_in_project_baseline() { let mut fixture = Fixture::new(&["numbers@*"]); fixture.package( "numbers", &[], &[ ("module/numbers/value/app.dever", &app("input")), ("module/numbers/value/api.dever", &command()), ], ); let baseline = fixture.load().unwrap().api_snapshot().unwrap(); write(&fixture.directory.0, "dever.api", &baseline); assert!(fixture.load().unwrap().check().is_ok()); fixture.entries.clear(); fixture.package( "numbers", &[], &[ ( "module/numbers/value/app.dever", &app("input").replace("input", "renamed"), ), ("module/numbers/value/api.dever", &command()), ], ); assert!( fixture .load() .unwrap() .check() .unwrap_err() .contains("public API differs") ); }