use super::{floor_against, requirement_floor};
const RENDERED: &str = r#"# Generated by alef. Do not edit by hand.
[package]
name = "demo-lib-jni"
version.workspace = true
# This crate deliberately does not use `[lints]` / `workspace = true`. ~keep
[lints.clippy]
dbg_macro = "deny"
[dependencies]
async-trait = "0.1"
base64 = "0.22"
demo-lib = { version = "1.0.0", path = "../demo-lib" }
serde_json = "1"
"#;
fn dependency_line(manifest: &str, name: &str) -> String {
manifest
.lines()
.find(|line| line.starts_with(&format!("{name} ")))
.unwrap_or_else(|| panic!("`{name}` must appear in:\n{manifest}"))
.to_string()
}
#[test]
fn floor_raises_an_emitted_requirement_to_the_higher_committed_one() {
let committed = "[dependencies]\nbase64 = \"0.23\"\n";
let floored = floor_against(RENDERED, committed);
assert_eq!(dependency_line(&floored, "base64"), "base64 = \"0.23\"");
}
#[test]
fn floor_never_lowers_an_emitted_requirement_to_a_lower_committed_one() {
let rendered = "[dependencies]\nbase64 = \"0.23\"\n";
let committed = "[dependencies]\nbase64 = \"0.22\"\n";
let floored = floor_against(rendered, committed);
assert_eq!(dependency_line(&floored, "base64"), "base64 = \"0.23\"");
}
#[test]
fn floor_is_a_no_op_once_the_committed_manifest_already_matches() {
let committed = "[dependencies]\nbase64 = \"0.23\"\n";
let once = floor_against(RENDERED, committed);
let twice = floor_against(&once, &once);
assert_eq!(twice, once, "a second pass over its own output must change nothing");
}
#[test]
fn floor_returns_the_rendered_manifest_verbatim_when_nothing_is_behind() {
let committed = "[dependencies]\nbase64 = \"0.22\"\n";
assert_eq!(floor_against(RENDERED, committed), RENDERED);
}
#[test]
fn floor_preserves_comments_and_layout_around_the_requirement_it_raises() {
let committed = "[dependencies]\nbase64 = \"0.23\"\n";
let floored = floor_against(RENDERED, committed);
assert!(
floored.contains("# This crate deliberately does not use `[lints]` / `workspace = true`. ~keep"),
"the marked rationale comment must survive a raise:\n{floored}"
);
assert!(
floored.contains("# Generated by alef. Do not edit by hand."),
"the header comment must survive a raise:\n{floored}"
);
assert_eq!(dependency_line(&floored, "async-trait"), "async-trait = \"0.1\"");
assert_eq!(dependency_line(&floored, "serde_json"), "serde_json = \"1\"");
}
#[test]
fn floor_raises_a_table_entry_version_and_leaves_its_features_alone() {
let rendered = "[dependencies]\ntokio = { version = \"1.0\", features = [\"sync\"] }\n";
let committed = "[dependencies]\ntokio = { version = \"1.40\", features = [\"full\"] }\n";
let floored = floor_against(rendered, committed);
assert_eq!(
dependency_line(&floored, "tokio"),
"tokio = { version = \"1.40\", features = [\"sync\"] }"
);
}
#[test]
fn floor_ignores_a_committed_entry_that_declares_no_version() {
let committed = "[dependencies]\nbase64.workspace = true\n";
assert_eq!(floor_against(RENDERED, committed), RENDERED);
}
#[test]
fn floor_declines_to_rule_on_a_requirement_with_no_lower_bound() {
let committed = "[dependencies]\nbase64 = \"*\"\n";
assert_eq!(floor_against(RENDERED, committed), RENDERED);
}
#[test]
fn floor_leaves_the_rendered_manifest_alone_when_the_committed_one_is_not_valid_toml() {
assert_eq!(floor_against(RENDERED, "[dependencies\nbase64 = "), RENDERED);
}
#[test]
fn floor_raises_requirements_nested_under_a_target_cfg_table() {
let rendered = "[target.'cfg(target_arch = \"wasm32\")'.dependencies]\ngetrandom = \"0.2\"\n";
let committed = "[target.'cfg(target_arch = \"wasm32\")'.dependencies]\ngetrandom = \"0.3\"\n";
let floored = floor_against(rendered, committed);
assert_eq!(dependency_line(&floored, "getrandom"), "getrandom = \"0.3\"");
}
#[test]
fn floor_covers_dev_and_build_dependency_tables() {
let rendered = "[build-dependencies]\ncbindgen = \"0.28\"\n\n[dev-dependencies]\ntempfile = \"3\"\n";
let committed = "[build-dependencies]\ncbindgen = \"0.29\"\n\n[dev-dependencies]\ntempfile = \"3.10\"\n";
let floored = floor_against(rendered, committed);
assert_eq!(dependency_line(&floored, "cbindgen"), "cbindgen = \"0.29\"");
assert_eq!(dependency_line(&floored, "tempfile"), "tempfile = \"3.10\"");
}
#[test]
fn floor_does_not_import_a_dependency_the_emitter_did_not_declare() {
let committed = "[dependencies]\nbase64 = \"0.22\"\nuuid = \"1\"\n";
let floored = floor_against(RENDERED, committed);
assert!(
!floored.contains("uuid"),
"an unemitted dependency must not appear:\n{floored}"
);
}
#[test]
fn requirement_floor_reads_the_lower_bound_of_each_requirement_form() {
let cases = [
("0.22", Some("0.22.0")),
("0.23", Some("0.23.0")),
("1", Some("1.0.0")),
("1.2.3", Some("1.2.3")),
("^1.4", Some("1.4.0")),
("~0.9.1", Some("0.9.1")),
("=2.0.4", Some("2.0.4")),
(">=0.9, <0.9.128", Some("0.9.0")),
("*", None),
("<2", None),
("not a requirement", None),
];
for (requirement, expected) in cases {
let actual = requirement_floor(requirement).map(|version| version.to_string());
assert_eq!(
actual.as_deref(),
expected,
"lower bound of `{requirement}` must be {expected:?}"
);
}
}
#[test]
fn requirement_floor_orders_two_disjoint_caret_ranges() {
let behind = requirement_floor("0.22").expect("0.22 is bounded below");
let ahead = requirement_floor("0.23").expect("0.23 is bounded below");
assert!(ahead > behind, "0.23 must order above 0.22");
}