From 2aadc03ef15cb5ca5cc2af8a7c08e070742f0ac4 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 4 May 2024 14:47:55 +0200 Subject: Adding upstream version 0.70.1+ds1. Signed-off-by: Daniel Baumann --- tests/testsuite/path.rs | 1139 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1139 insertions(+) create mode 100644 tests/testsuite/path.rs (limited to 'tests/testsuite/path.rs') diff --git a/tests/testsuite/path.rs b/tests/testsuite/path.rs new file mode 100644 index 0000000..ebbb72f --- /dev/null +++ b/tests/testsuite/path.rs @@ -0,0 +1,1139 @@ +//! Tests for `path` dependencies. + +use cargo_test_support::paths::{self, CargoPathExt}; +use cargo_test_support::registry::Package; +use cargo_test_support::{basic_lib_manifest, basic_manifest, main_file, project}; +use cargo_test_support::{sleep_ms, t}; +use std::fs; + +#[cargo_test] +// I have no idea why this is failing spuriously on Windows; +// for more info, see #3466. +#[cfg(not(windows))] +fn cargo_compile_with_nested_deps_shorthand() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + version = "0.5.0" + path = "bar" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.baz] + + version = "0.5.0" + path = "baz" + + [lib] + + name = "bar" + "#, + ) + .file( + "bar/src/bar.rs", + r#" + extern crate baz; + + pub fn gimme() -> String { + baz::gimme() + } + "#, + ) + .file("bar/baz/Cargo.toml", &basic_lib_manifest("baz")) + .file( + "bar/baz/src/baz.rs", + r#" + pub fn gimme() -> String { + "test passed".to_string() + } + "#, + ) + .build(); + + p.cargo("build") + .with_stderr( + "[COMPILING] baz v0.5.0 ([CWD]/bar/baz)\n\ + [COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + + assert!(p.bin("foo").is_file()); + + p.process(&p.bin("foo")).with_stdout("test passed\n").run(); + + println!("cleaning"); + p.cargo("clean -v").with_stdout("").run(); + println!("building baz"); + p.cargo("build -p baz") + .with_stderr( + "[COMPILING] baz v0.5.0 ([CWD]/bar/baz)\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + println!("building foo"); + p.cargo("build -p foo") + .with_stderr( + "[COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); +} + +#[cargo_test] +fn cargo_compile_with_root_dev_deps() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dev-dependencies.bar] + + version = "0.5.0" + path = "../bar" + + [[bin]] + name = "foo" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .build(); + let _p2 = project() + .at("bar") + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file( + "src/lib.rs", + r#" + pub fn gimme() -> &'static str { + "zoidberg" + } + "#, + ) + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr_contains("[..]can't find crate for `bar`") + .run(); +} + +#[cargo_test] +fn cargo_compile_with_root_dev_deps_with_testing() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dev-dependencies.bar] + + version = "0.5.0" + path = "../bar" + + [[bin]] + name = "foo" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .build(); + let _p2 = project() + .at("bar") + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file( + "src/lib.rs", + r#" + pub fn gimme() -> &'static str { + "zoidberg" + } + "#, + ) + .build(); + + p.cargo("test") + .with_stderr( + "\ +[COMPILING] [..] v0.5.0 ([..]) +[COMPILING] [..] v0.5.0 ([..]) +[FINISHED] test [unoptimized + debuginfo] target(s) in [..] +[RUNNING] [..] (target/debug/deps/foo-[..][EXE])", + ) + .with_stdout_contains("running 0 tests") + .run(); +} + +#[cargo_test] +fn cargo_compile_with_transitive_dev_deps() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + version = "0.5.0" + path = "bar" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dev-dependencies.baz] + + git = "git://example.com/path/to/nowhere" + + [lib] + + name = "bar" + "#, + ) + .file( + "bar/src/bar.rs", + r#" + pub fn gimme() -> &'static str { + "zoidberg" + } + "#, + ) + .build(); + + p.cargo("build") + .with_stderr( + "[COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) in \ + [..]\n", + ) + .run(); + + assert!(p.bin("foo").is_file()); + + p.process(&p.bin("foo")).with_stdout("zoidberg\n").run(); +} + +#[cargo_test] +fn no_rebuild_dependency() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + path = "bar" + "#, + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + .file("bar/Cargo.toml", &basic_lib_manifest("bar")) + .file("bar/src/bar.rs", "pub fn bar() {}") + .build(); + // First time around we should compile both foo and bar + p.cargo("check") + .with_stderr( + "[CHECKING] bar v0.5.0 ([CWD]/bar)\n\ + [CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + + sleep_ms(1000); + p.change_file( + "src/main.rs", + r#" + extern crate bar; + fn main() { bar::bar(); } + "#, + ); + // Don't compile bar, but do recompile foo. + p.cargo("check") + .with_stderr( + "[CHECKING] foo v0.5.0 ([..])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); +} + +#[cargo_test] +fn deep_dependencies_trigger_rebuild() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + path = "bar" + "#, + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [lib] + name = "bar" + [dependencies.baz] + path = "../baz" + "#, + ) + .file( + "bar/src/bar.rs", + "extern crate baz; pub fn bar() { baz::baz() }", + ) + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) + .file("baz/src/baz.rs", "pub fn baz() {}") + .build(); + p.cargo("check") + .with_stderr( + "[CHECKING] baz v0.5.0 ([CWD]/baz)\n\ + [CHECKING] bar v0.5.0 ([CWD]/bar)\n\ + [CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + p.cargo("check").with_stdout("").run(); + + // Make sure an update to baz triggers a rebuild of bar + // + // We base recompilation off mtime, so sleep for at least a second to ensure + // that this write will change the mtime. + sleep_ms(1000); + p.change_file("baz/src/baz.rs", r#"pub fn baz() { println!("hello!"); }"#); + sleep_ms(1000); + p.cargo("check") + .with_stderr( + "[CHECKING] baz v0.5.0 ([CWD]/baz)\n\ + [CHECKING] bar v0.5.0 ([CWD]/bar)\n\ + [CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + + // Make sure an update to bar doesn't trigger baz + sleep_ms(1000); + p.change_file( + "bar/src/bar.rs", + r#" + extern crate baz; + pub fn bar() { println!("hello!"); baz::baz(); } + "#, + ); + sleep_ms(1000); + p.cargo("check") + .with_stderr( + "[CHECKING] bar v0.5.0 ([CWD]/bar)\n\ + [CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); +} + +#[cargo_test] +fn no_rebuild_two_deps() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + path = "bar" + [dependencies.baz] + path = "baz" + "#, + ) + .file("src/main.rs", "extern crate bar; fn main() { bar::bar() }") + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + + [lib] + name = "bar" + [dependencies.baz] + path = "../baz" + "#, + ) + .file("bar/src/bar.rs", "pub fn bar() {}") + .file("baz/Cargo.toml", &basic_lib_manifest("baz")) + .file("baz/src/baz.rs", "pub fn baz() {}") + .build(); + p.cargo("build") + .with_stderr( + "[COMPILING] baz v0.5.0 ([CWD]/baz)\n\ + [COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + assert!(p.bin("foo").is_file()); + p.cargo("build").with_stdout("").run(); + assert!(p.bin("foo").is_file()); +} + +#[cargo_test] +fn nested_deps_recompile() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + version = "0.5.0" + path = "src/bar" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .file("src/bar/Cargo.toml", &basic_lib_manifest("bar")) + .file("src/bar/src/bar.rs", "pub fn gimme() -> i32 { 92 }") + .build(); + + p.cargo("check") + .with_stderr( + "[CHECKING] bar v0.5.0 ([CWD]/src/bar)\n\ + [CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + sleep_ms(1000); + + p.change_file("src/main.rs", r#"fn main() {}"#); + + // This shouldn't recompile `bar` + p.cargo("check") + .with_stderr( + "[CHECKING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); +} + +#[cargo_test] +fn error_message_for_missing_manifest() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + path = "src/bar" + "#, + ) + .file("src/lib.rs", "") + .file("src/bar/not-a-manifest", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to get `bar` as a dependency of package `foo v0.5.0 [..]` + +Caused by: + failed to load source for dependency `bar` + +Caused by: + Unable to update [CWD]/src/bar + +Caused by: + failed to read `[..]bar/Cargo.toml` + +Caused by: + [..] (os error [..]) +", + ) + .run(); +} + +#[cargo_test] +fn override_relative() { + let bar = project() + .at("bar") + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file("src/lib.rs", "") + .build(); + + fs::create_dir(&paths::root().join(".cargo")).unwrap(); + fs::write(&paths::root().join(".cargo/config"), r#"paths = ["bar"]"#).unwrap(); + + let p = project() + .file( + "Cargo.toml", + &format!( + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + path = '{}' + "#, + bar.root().display() + ), + ) + .file("src/lib.rs", "") + .build(); + p.cargo("check -v").run(); +} + +#[cargo_test] +fn override_self() { + let bar = project() + .at("bar") + .file("Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file("src/lib.rs", "") + .build(); + + let p = project(); + let root = p.root(); + let p = p + .file(".cargo/config", &format!("paths = ['{}']", root.display())) + .file( + "Cargo.toml", + &format!( + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + path = '{}' + + "#, + bar.root().display() + ), + ) + .file("src/lib.rs", "") + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("check").run(); +} + +#[cargo_test] +fn override_path_dep() { + let bar = project() + .at("bar") + .file( + "p1/Cargo.toml", + r#" + [package] + name = "p1" + version = "0.5.0" + authors = [] + + [dependencies.p2] + path = "../p2" + "#, + ) + .file("p1/src/lib.rs", "") + .file("p2/Cargo.toml", &basic_manifest("p2", "0.5.0")) + .file("p2/src/lib.rs", "") + .build(); + + let p = project() + .file( + ".cargo/config", + &format!( + "paths = ['{}', '{}']", + bar.root().join("p1").display(), + bar.root().join("p2").display() + ), + ) + .file( + "Cargo.toml", + &format!( + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.p2] + path = '{}' + + "#, + bar.root().join("p2").display() + ), + ) + .file("src/lib.rs", "") + .build(); + + p.cargo("check -v").run(); +} + +#[cargo_test] +fn path_dep_build_cmd() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + + name = "foo" + version = "0.5.0" + authors = ["wycats@example.com"] + + [dependencies.bar] + + version = "0.5.0" + path = "bar" + "#, + ) + .file("src/main.rs", &main_file(r#""{}", bar::gimme()"#, &["bar"])) + .file( + "bar/Cargo.toml", + r#" + [package] + + name = "bar" + version = "0.5.0" + authors = ["wycats@example.com"] + build = "build.rs" + + [lib] + name = "bar" + path = "src/bar.rs" + "#, + ) + .file( + "bar/build.rs", + r#" + use std::fs; + fn main() { + fs::copy("src/bar.rs.in", "src/bar.rs").unwrap(); + } + "#, + ) + .file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 0 }") + .build(); + p.root().join("bar").move_into_the_past(); + + p.cargo("build") + .with_stderr( + "[COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) in \ + [..]\n", + ) + .run(); + + assert!(p.bin("foo").is_file()); + + p.process(&p.bin("foo")).with_stdout("0\n").run(); + + // Touching bar.rs.in should cause the `build` command to run again. + p.change_file("bar/src/bar.rs.in", "pub fn gimme() -> i32 { 1 }"); + + p.cargo("build") + .with_stderr( + "[COMPILING] bar v0.5.0 ([CWD]/bar)\n\ + [COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) in \ + [..]\n", + ) + .run(); + + p.process(&p.bin("foo")).with_stdout("1\n").run(); +} + +#[cargo_test] +fn dev_deps_no_rebuild_lib() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [dev-dependencies.bar] + path = "bar" + + [lib] + name = "foo" + doctest = false + "#, + ) + .file( + "src/lib.rs", + r#" + #[cfg(test)] #[allow(unused_extern_crates)] extern crate bar; + #[cfg(not(test))] pub fn foo() { env!("FOO"); } + "#, + ) + .file("bar/Cargo.toml", &basic_manifest("bar", "0.5.0")) + .file("bar/src/lib.rs", "pub fn bar() {}") + .build(); + p.cargo("build") + .env("FOO", "bar") + .with_stderr( + "[COMPILING] foo v0.5.0 ([CWD])\n\ + [FINISHED] dev [unoptimized + debuginfo] target(s) \ + in [..]\n", + ) + .run(); + + p.cargo("test") + .with_stderr( + "\ +[COMPILING] [..] v0.5.0 ([CWD][..]) +[COMPILING] [..] v0.5.0 ([CWD][..]) +[FINISHED] test [unoptimized + debuginfo] target(s) in [..] +[RUNNING] [..] (target/debug/deps/foo-[..][EXE])", + ) + .with_stdout_contains("running 0 tests") + .run(); +} + +#[cargo_test] +fn custom_target_no_rebuild() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + [dependencies] + a = { path = "a" } + [workspace] + members = ["a", "b"] + "#, + ) + .file("src/lib.rs", "") + .file("a/Cargo.toml", &basic_manifest("a", "0.5.0")) + .file("a/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.5.0" + authors = [] + [dependencies] + a = { path = "../a" } + "#, + ) + .file("b/src/lib.rs", "") + .build(); + p.cargo("check") + .with_stderr( + "\ +[CHECKING] a v0.5.0 ([..]) +[CHECKING] foo v0.5.0 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); + + t!(fs::rename( + p.root().join("target"), + p.root().join("target_moved") + )); + p.cargo("check --manifest-path=b/Cargo.toml") + .env("CARGO_TARGET_DIR", "target_moved") + .with_stderr( + "\ +[CHECKING] b v0.5.0 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); +} + +#[cargo_test] +fn override_and_depend() { + let p = project() + .no_manifest() + .file( + "a/a1/Cargo.toml", + r#" + [package] + name = "a1" + version = "0.5.0" + authors = [] + [dependencies] + a2 = { path = "../a2" } + "#, + ) + .file("a/a1/src/lib.rs", "") + .file("a/a2/Cargo.toml", &basic_manifest("a2", "0.5.0")) + .file("a/a2/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.5.0" + authors = [] + [dependencies] + a1 = { path = "../a/a1" } + a2 = { path = "../a/a2" } + "#, + ) + .file("b/src/lib.rs", "") + .file("b/.cargo/config", r#"paths = ["../a"]"#) + .build(); + p.cargo("check") + .cwd("b") + .with_stderr( + "\ +[WARNING] skipping duplicate package `a2` found at `[..]` +[CHECKING] a2 v0.5.0 ([..]) +[CHECKING] a1 v0.5.0 ([..]) +[CHECKING] b v0.5.0 ([..]) +[FINISHED] dev [unoptimized + debuginfo] target(s) in [..] +", + ) + .run(); +} + +#[cargo_test] +fn missing_path_dependency() { + let p = project() + .file("Cargo.toml", &basic_manifest("a", "0.5.0")) + .file("src/lib.rs", "") + .file( + ".cargo/config", + r#"paths = ["../whoa-this-does-not-exist"]"#, + ) + .build(); + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to update path override `[..]../whoa-this-does-not-exist` \ +(defined in `[..]`) + +Caused by: + failed to read directory `[..]` + +Caused by: + [..] (os error [..]) +", + ) + .run(); +} + +#[cargo_test] +fn invalid_path_dep_in_workspace_with_lockfile() { + Package::new("bar", "1.0.0").publish(); + + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "top" + version = "0.5.0" + authors = [] + + [workspace] + + [dependencies] + foo = { path = "foo" } + "#, + ) + .file("src/lib.rs", "") + .file( + "foo/Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + bar = "*" + "#, + ) + .file("foo/src/lib.rs", "") + .build(); + + // Generate a lock file + p.cargo("check").run(); + + // Change the dependency on `bar` to an invalid path + p.change_file( + "foo/Cargo.toml", + r#" + [package] + name = "foo" + version = "0.5.0" + authors = [] + + [dependencies] + bar = { path = "" } + "#, + ); + + // Make sure we get a nice error. In the past this actually stack + // overflowed! + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +error: no matching package found +searched package name: `bar` +perhaps you meant: foo +location searched: [..] +required by package `foo v0.5.0 ([..])` +", + ) + .run(); +} + +#[cargo_test] +fn workspace_produces_rlib() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "top" + version = "0.5.0" + authors = [] + + [workspace] + + [dependencies] + foo = { path = "foo" } + "#, + ) + .file("src/lib.rs", "") + .file("foo/Cargo.toml", &basic_manifest("foo", "0.5.0")) + .file("foo/src/lib.rs", "") + .build(); + + p.cargo("build").run(); + + assert!(p.root().join("target/debug/libtop.rlib").is_file()); + assert!(!p.root().join("target/debug/libfoo.rlib").is_file()); +} + +#[cargo_test] +fn deep_path_error() { + // Test for an error loading a path deep in the dependency graph. + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.1.0" + [dependencies] + a = {path="a"} + "#, + ) + .file("src/lib.rs", "") + .file( + "a/Cargo.toml", + r#" + [package] + name = "a" + version = "0.1.0" + [dependencies] + b = {path="../b"} + "#, + ) + .file("a/src/lib.rs", "") + .file( + "b/Cargo.toml", + r#" + [package] + name = "b" + version = "0.1.0" + [dependencies] + c = {path="../c"} + "#, + ) + .file("b/src/lib.rs", "") + .build(); + + p.cargo("check") + .with_status(101) + .with_stderr( + "\ +[ERROR] failed to get `c` as a dependency of package `b v0.1.0 [..]` + ... which satisfies path dependency `b` of package `a v0.1.0 [..]` + ... which satisfies path dependency `a` of package `foo v0.1.0 [..]` + +Caused by: + failed to load source for dependency `c` + +Caused by: + Unable to update [..]/foo/c + +Caused by: + failed to read `[..]/foo/c/Cargo.toml` + +Caused by: + [..] +", + ) + .run(); +} + +#[cargo_test] +fn catch_tricky_cycle() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "message" + version = "0.1.0" + + [dev-dependencies] + test = { path = "test" } + "#, + ) + .file("src/lib.rs", "") + .file( + "tangle/Cargo.toml", + r#" + [package] + name = "tangle" + version = "0.1.0" + + [dependencies] + message = { path = ".." } + snapshot = { path = "../snapshot" } + "#, + ) + .file("tangle/src/lib.rs", "") + .file( + "snapshot/Cargo.toml", + r#" + [package] + name = "snapshot" + version = "0.1.0" + + [dependencies] + ledger = { path = "../ledger" } + "#, + ) + .file("snapshot/src/lib.rs", "") + .file( + "ledger/Cargo.toml", + r#" + [package] + name = "ledger" + version = "0.1.0" + + [dependencies] + tangle = { path = "../tangle" } + "#, + ) + .file("ledger/src/lib.rs", "") + .file( + "test/Cargo.toml", + r#" + [package] + name = "test" + version = "0.1.0" + + [dependencies] + snapshot = { path = "../snapshot" } + "#, + ) + .file("test/src/lib.rs", "") + .build(); + + p.cargo("test") + .with_stderr_contains("[..]cyclic package dependency[..]") + .with_status(101) + .run(); +} -- cgit v1.2.3