//! Tests for local-registry sources. use cargo_test_support::prelude::*; use cargo_test_support::project; use cargo_test_support::registry::{Package, RegistryBuilder, TestRegistry}; fn setup() -> (TestRegistry, String) { let alt = RegistryBuilder::new().alternative().build(); ( RegistryBuilder::new().http_index().build(), alt.index_url() .to_file_path() .unwrap() .into_os_string() .into_string() .unwrap(), ) } #[cargo_test] fn overlay_hit() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = "0.1.0" "#, ) .file("src/main.rs", "fn main() {}") .build(); // baz is only in the local registry, but it gets found Package::new("baz", "0.1.1") .alternative(true) .local(true) .publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .run(); } #[cargo_test] fn registry_version_wins() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = "0.1.0" "#, ) .file("src/main.rs", "fn main() {}") .build(); // The latest one is in the main registry, so it will get chosen. Package::new("baz", "0.1.1").publish(); Package::new("baz", "0.1.0") .alternative(true) .local(true) .publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .with_stderr_data( "\ [UPDATING] [..] [LOCKING] 2 packages to latest compatible versions [DOWNLOADING] crates ... [DOWNLOADED] baz v0.1.1 (registry [..]) [CHECKING] baz v0.1.1 [CHECKING] foo v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s ", ) .run(); } #[cargo_test] fn overlay_version_wins() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = "0.1.0" "#, ) .file("src/main.rs", "fn main() {}") .build(); // The latest one is in the overlay registry, so it will get chosen. Package::new("baz", "0.1.0").publish(); Package::new("baz", "0.1.1") .alternative(true) .local(true) .publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .with_stderr_data( "\ [UPDATING] [..] [LOCKING] 2 packages to latest compatible versions [UNPACKING] baz v0.1.1 (registry [..]) [CHECKING] baz v0.1.1 [CHECKING] foo v0.0.1 ([ROOT]/foo) [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s ", ) .run(); } #[cargo_test] fn version_collision() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = "0.1.0" "#, ) .file("src/main.rs", "fn main() {}") .build(); // The one we want is in the main registry. Package::new("baz", "0.1.1").publish(); Package::new("baz", "0.1.1") .alternative(true) .local(true) .publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .with_status(101) .with_stderr_data( "\ [UPDATING] [..] [ERROR] failed to get `baz` [..] Caused by: failed to query replaced source registry `crates-io` Caused by: found a package in the remote registry and the local overlay: baz@0.1.1 ", ) .run(); } #[cargo_test] fn local_depends_on_old_registry_package() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = "0.1.0" "#, ) .file("src/main.rs", "fn main() {}") .build(); Package::new("baz", "0.0.1").publish(); // A new local package can depend on an older version in the registry. Package::new("baz", "0.1.1") .dep("baz", "=0.0.1") .alternative(true) .local(true) .publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .run(); } #[cargo_test] fn registry_dep_depends_on_new_local_package() { let (reg, alt_path) = setup(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] registry-package = "0.1.0" workspace-package = "0.0.1" "#, ) .file("src/main.rs", "fn main() {}") .build(); Package::new("registry-package", "0.1.0") .dep("workspace-package", "0.1.0") .publish(); // The local overlay contains an updated version of workspace-package Package::new("workspace-package", "0.1.1") .alternative(true) .local(true) .publish(); // The registry contains older versions of workspace-package (one of which // we depend on directly). Package::new("workspace-package", "0.1.0").publish(); Package::new("workspace-package", "0.0.1").publish(); p.cargo("check") .overlay_registry(®.index_url(), &alt_path) .with_stderr_data( "\ [UPDATING] [..] [LOCKING] 4 packages to latest compatible versions [ADDING] workspace-package v0.0.1 (latest: v0.1.1) [DOWNLOADING] crates ... [UNPACKING] [..] [DOWNLOADED] [..] [DOWNLOADED] [..] [CHECKING] workspace-package v0.1.1 [CHECKING] workspace-package v0.0.1 [CHECKING] registry-package v0.1.0 [CHECKING] foo v0.0.1 [..] [FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s ", ) .run(); } // Test that we can overlay on top of alternate registries, not just crates-io. // Since the test framework only supports a single alternate registry, we repurpose // the dummy crates-io as the registry to overlay on top. #[cargo_test] fn alt_registry() { let alt = RegistryBuilder::new().http_index().alternative().build(); let crates_io = RegistryBuilder::new().build(); let crates_io_path = crates_io .index_url() .to_file_path() .unwrap() .into_os_string() .into_string() .unwrap(); let p = project() .file( "Cargo.toml", r#" [package] name = "foo" version = "0.0.1" edition = "2015" authors = [] [dependencies] baz = { version = "0.1.0", registry = "alternative" } "#, ) .file("src/main.rs", "fn main() {}") .build(); // This package isn't used, but publishing it forces the creation of the registry index. Package::new("bar", "0.0.1").local(true).publish(); Package::new("baz", "0.1.1").alternative(true).publish(); p.cargo("check") .overlay_registry(&alt.index_url(), &crates_io_path) .run(); }