extern crate cargotest; extern crate hamcrest; use cargotest::support::{project, execs}; use cargotest::support::registry::Package; use hamcrest::assert_that; #[test] fn bad1() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [target] nonexistent-target = "foo" "#); assert_that(foo.cargo_process("build").arg("-v") .arg("--target=nonexistent-target"), execs().with_status(101).with_stderr("\ [ERROR] expected table for configuration key `target.nonexistent-target`, \ but found string in [..]config ")); } #[test] fn bad2() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [http] proxy = 3.0 "#); assert_that(foo.cargo_process("publish").arg("-v"), execs().with_status(101).with_stderr("\ [ERROR] Couldn't load Cargo configuration Caused by: failed to load TOML configuration from `[..]config` Caused by: failed to parse key `http` Caused by: failed to parse key `proxy` Caused by: found TOML configuration value of unknown type `float` ")); } #[test] fn bad3() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [http] proxy = true "#); Package::new("foo", "1.0.0").publish(); assert_that(foo.cargo_process("publish").arg("-v"), execs().with_status(101).with_stderr("\ error: failed to update registry [..] Caused by: invalid configuration for key `http.proxy` expected a string, but found a boolean for `http.proxy` in [..]config ")); } #[test] fn bad4() { let foo = project("foo") .file(".cargo/config", r#" [cargo-new] name = false "#); assert_that(foo.cargo_process("new").arg("-v").arg("foo"), execs().with_status(101).with_stderr("\ [ERROR] Failed to create project `foo` at `[..]` Caused by: invalid configuration for key `cargo-new.name` expected a string, but found a boolean for `cargo-new.name` in [..]config ")); } #[test] fn bad5() { let foo = project("foo") .file(".cargo/config", r#" foo = "" "#) .file("foo/.cargo/config", r#" foo = 2 "#); foo.build(); assert_that(foo.cargo("new") .arg("-v").arg("foo").cwd(&foo.root().join("foo")), execs().with_status(101).with_stderr("\ [ERROR] Failed to create project `foo` at `[..]` Caused by: Couldn't load Cargo configuration Caused by: failed to merge configuration at `[..]` Caused by: failed to merge key `foo` between files: file 1: [..]foo[..]foo[..]config file 2: [..]foo[..]config Caused by: expected integer, but found string ")); } #[test] fn bad_cargo_config_jobs() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [build] jobs = -1 "#); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr("\ [ERROR] build.jobs must be positive, but found -1 in [..] ")); } #[test] fn default_cargo_config_jobs() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [build] jobs = 1 "#); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(0)); } #[test] fn good_cargo_config_jobs() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [build] jobs = 4 "#); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(0)); } #[test] fn invalid_global_config() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] foo = "0.1.0" "#) .file(".cargo/config", "4") .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr("\ [ERROR] Couldn't load Cargo configuration Caused by: could not parse TOML configuration in `[..]` Caused by: could not parse input as TOML Caused by: expected an equals, found eof at line 1 ")); } #[test] fn bad_cargo_lock() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("Cargo.lock", "[[package]]\nfoo = 92") .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse lock file at: [..]Cargo.lock Caused by: missing field `name` for key `package` ")); } #[test] fn duplicate_packages_in_cargo_lock() { Package::new("foo", "0.1.0").publish(); let p = project("bar") .file("Cargo.toml", r#" [project] name = "bar" version = "0.0.1" authors = [] [dependencies] foo = "0.1.0" "#) .file("src/lib.rs", "") .file("Cargo.lock", r#" [root] name = "bar" version = "0.0.1" dependencies = [ "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "foo" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "foo" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" "#); p.build(); assert_that(p.cargo("build").arg("--verbose"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse lock file at: [..] Caused by: package `foo` is specified twice in the lockfile ")); } #[test] fn bad_source_in_cargo_lock() { Package::new("foo", "0.1.0").publish(); let p = project("bar") .file("Cargo.toml", r#" [project] name = "bar" version = "0.0.1" authors = [] [dependencies] foo = "0.1.0" "#) .file("src/lib.rs", "") .file("Cargo.lock", r#" [root] name = "bar" version = "0.0.1" dependencies = [ "foo 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "foo" version = "0.1.0" source = "You shall not parse" "#); p.build(); assert_that(p.cargo("build").arg("--verbose"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse lock file at: [..] Caused by: invalid source `You shall not parse` for key `package.source` ")); } #[test] fn bad_dependency_in_lockfile() { let p = project("foo") .file("Cargo.toml", r#" [project] name = "foo" version = "0.0.1" authors = [] "#) .file("src/lib.rs", "") .file("Cargo.lock", r#" [root] name = "foo" version = "0.0.1" dependencies = [ "bar 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] "#); p.build(); assert_that(p.cargo("build").arg("--verbose"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse lock file at: [..] Caused by: package `bar 0.1.0 ([..])` is specified as a dependency, but is missing from the package list ")); } #[test] fn bad_git_dependency() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] foo = { git = "file:.." } "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr("\ [UPDATING] git repository `file:///` [ERROR] failed to load source for a dependency on `foo` Caused by: Unable to update file:/// Caused by: failed to clone into: [..] Caused by: [[..]] 'file:///' is not a valid local file URI ")); } #[test] fn bad_crate_type() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [lib] crate-type = ["bad_type", "rlib"] "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_status(101).with_stderr_contains("\ error: failed to run `rustc` to learn about target-specific information ")); } #[test] fn malformed_override() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [target.x86_64-apple-darwin.freetype] native = { foo: "bar" } "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: could not parse input as TOML Caused by: expected a table key, found a newline at line 8 ")); } #[test] fn duplicate_binary_names() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "qqq" version = "0.1.0" authors = ["A "] [[bin]] name = "e" path = "a.rs" [[bin]] name = "e" path = "b.rs" "#) .file("a.rs", r#"fn main() -> () {}"#) .file("b.rs", r#"fn main() -> () {}"#); assert_that(foo.cargo_process("build"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: found duplicate binary name e, but all binary targets must have a unique name ")); } #[test] fn duplicate_example_names() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "qqq" version = "0.1.0" authors = ["A "] [[example]] name = "ex" path = "examples/ex.rs" [[example]] name = "ex" path = "examples/ex2.rs" "#) .file("examples/ex.rs", r#"fn main () -> () {}"#) .file("examples/ex2.rs", r#"fn main () -> () {}"#); assert_that(foo.cargo_process("build").arg("--example").arg("ex"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: found duplicate example name ex, but all binary targets must have a unique name ")); } #[test] fn duplicate_bench_names() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "qqq" version = "0.1.0" authors = ["A "] [[bench]] name = "ex" path = "benches/ex.rs" [[bench]] name = "ex" path = "benches/ex2.rs" "#) .file("benches/ex.rs", r#"fn main () {}"#) .file("benches/ex2.rs", r#"fn main () {}"#); assert_that(foo.cargo_process("bench"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: found duplicate bench name ex, but all binary targets must have a unique name ")); } #[test] fn duplicate_deps() { let foo = project("foo") .file("shim-bar/Cargo.toml", r#" [package] name = "bar" version = "0.0.1" authors = [] "#) .file("shim-bar/src/lib.rs", r#" pub fn a() {} "#) .file("linux-bar/Cargo.toml", r#" [package] name = "bar" version = "0.0.1" authors = [] "#) .file("linux-bar/src/lib.rs", r#" pub fn a() {} "#) .file("Cargo.toml", r#" [package] name = "qqq" version = "0.0.1" authors = [] [dependencies] bar = { path = "shim-bar" } [target.x86_64-unknown-linux-gnu.dependencies] bar = { path = "linux-bar" } "#) .file("src/main.rs", r#"fn main () {}"#); assert_that(foo.cargo_process("build"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: Dependency 'bar' has different source paths depending on the build target. Each dependency must \ have a single canonical source path irrespective of build target. ")); } #[test] fn duplicate_deps_diff_sources() { let foo = project("foo") .file("shim-bar/Cargo.toml", r#" [package] name = "bar" version = "0.0.1" authors = [] "#) .file("shim-bar/src/lib.rs", r#" pub fn a() {} "#) .file("linux-bar/Cargo.toml", r#" [package] name = "bar" version = "0.0.1" authors = [] "#) .file("linux-bar/src/lib.rs", r#" pub fn a() {} "#) .file("Cargo.toml", r#" [package] name = "qqq" version = "0.0.1" authors = [] [target.i686-unknown-linux-gnu.dependencies] bar = { path = "shim-bar" } [target.x86_64-unknown-linux-gnu.dependencies] bar = { path = "linux-bar" } "#) .file("src/main.rs", r#"fn main () {}"#); assert_that(foo.cargo_process("build"), execs().with_status(101).with_stderr("\ [ERROR] failed to parse manifest at `[..]` Caused by: Dependency 'bar' has different source paths depending on the build target. Each dependency must \ have a single canonical source path irrespective of build target. ")); } #[test] fn unused_keys() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.1.0" authors = [] [target.foo] bar = "3" "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build"), execs().with_status(0).with_stderr("\ warning: unused manifest key: target.foo.bar [COMPILING] foo v0.1.0 (file:///[..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ")); } #[test] fn empty_dependencies() { let p = project("empty_deps") .file("Cargo.toml", r#" [package] name = "empty_deps" version = "0.0.0" authors = [] [dependencies] foo = {} "#) .file("src/main.rs", "fn main() {}"); Package::new("foo", "0.0.1").publish(); assert_that(p.cargo_process("build"), execs().with_status(0).with_stderr_contains("\ warning: dependency (foo) specified without providing a local path, Git repository, or version \ to use. This will be considered an error in future versions ")); } #[test] fn invalid_toml_historically_allowed_is_warned() { let p = project("empty_deps") .file("Cargo.toml", r#" [package] name = "empty_deps" version = "0.0.0" authors = [] "#) .file(".cargo/config", r#" [foo] bar = 2 "#) .file("src/main.rs", "fn main() {}"); assert_that(p.cargo_process("build"), execs().with_status(0).with_stderr("\ warning: TOML file found which contains invalid syntax and will soon not parse at `[..]config`. The TOML spec requires newlines after table definitions (e.g. `[a] b = 1` is invalid), but this file has a table header which does not have a newline after it. A newline needs to be added and this warning will soon become a hard error in the future. [COMPILING] empty_deps v0.0.0 ([..]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] ")); } #[test] fn ambiguous_git_reference() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies.bar] git = "https://127.0.0.1" branch = "master" tag = "some-tag" "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_stderr_contains("\ [WARNING] dependency (bar) specification is ambiguous. \ Only one of `branch`, `tag` or `rev` is allowed. \ This will be considered an error in future versions ")); } #[test] fn bad_source_config1() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.foo] "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: no source URL specified for `source.foo`, need [..] ")); } #[test] fn bad_source_config2() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.crates-io] registry = 'http://example.com' replace-with = 'bar' "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to load source for a dependency on `bar` Caused by: Unable to update registry https://[..] Caused by: could not find a configured source with the name `bar` \ when attempting to lookup `crates-io` (configuration in [..]) ")); } #[test] fn bad_source_config3() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.crates-io] registry = 'http://example.com' replace-with = 'crates-io' "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to load source for a dependency on `bar` Caused by: Unable to update registry https://[..] Caused by: detected a cycle of `replace-with` sources, [..] ")); } #[test] fn bad_source_config4() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.crates-io] registry = 'http://example.com' replace-with = 'bar' [source.bar] registry = 'http://example.com' replace-with = 'crates-io' "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to load source for a dependency on `bar` Caused by: Unable to update registry https://[..] Caused by: detected a cycle of `replace-with` sources, the source `crates-io` is \ eventually replaced with itself (configuration in [..]) ")); } #[test] fn bad_source_config5() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.crates-io] registry = 'http://example.com' replace-with = 'bar' [source.bar] registry = 'not a url' "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: configuration key `source.bar.registry` specified an invalid URL (in [..]) Caused by: invalid url `not a url`: [..] ")); } #[test] fn both_git_and_path_specified() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies.bar] git = "https://127.0.0.1" path = "bar" "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_stderr_contains("\ [WARNING] dependency (bar) specification is ambiguous. \ Only one of `git` or `path` is allowed. \ This will be considered an error in future versions ")); } #[test] fn bad_source_config6() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.crates-io] registry = 'http://example.com' replace-with = ['not', 'a', 'string'] "#); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: expected a string, but found a array for `source.crates-io.replace-with` in [..] ")); } #[test] fn ignored_git_revision() { let foo = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies.bar] path = "bar" branch = "spam" "#) .file("src/lib.rs", ""); assert_that(foo.cargo_process("build").arg("-v"), execs().with_stderr_contains("\ [WARNING] key `branch` is ignored for dependency (bar). \ This will be considered an error in future versions")); } #[test] fn bad_source_config7() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = "*" "#) .file("src/lib.rs", "") .file(".cargo/config", r#" [source.foo] registry = 'http://example.com' local-registry = 'file:///another/file' "#); Package::new("bar", "0.1.0").publish(); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: more than one source URL specified for `source.foo` ")); } #[test] fn bad_dependency() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [dependencies] bar = 3 "#) .file("src/lib.rs", ""); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to parse manifest at `[..]` Caused by: invalid type: integer `3`, expected a version string like [..] ")); } #[test] fn bad_debuginfo() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] [profile.dev] debug = 'a' "#) .file("src/lib.rs", ""); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to parse manifest at `[..]` Caused by: invalid type: string \"a\", expected a boolean or an integer for [..] ")); } #[test] fn bad_opt_level() { let p = project("foo") .file("Cargo.toml", r#" [package] name = "foo" version = "0.0.0" authors = [] build = 3 "#) .file("src/lib.rs", ""); assert_that(p.cargo_process("build"), execs().with_status(101).with_stderr("\ error: failed to parse manifest at `[..]` Caused by: invalid type: integer `3`, expected a boolean or a string for key [..] ")); }