mirror of
https://github.com/rust-lang/cargo
synced 2024-10-14 03:32:39 +00:00
9115b2c326
Extract out all our test support code to its own standalone crate so it can be shared between multiple test suites if necessary.
383 lines
11 KiB
Rust
383 lines
11 KiB
Rust
use cargo_test_support::{clippy_is_available, is_nightly, process, project, registry::Package};
|
|
use std::path::Path;
|
|
|
|
fn as_str(bytes: &[u8]) -> &str {
|
|
std::str::from_utf8(bytes).expect("valid utf-8")
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn simple() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// A simple example that generates two warnings (unused functions).
|
|
let p = project()
|
|
.file(
|
|
"src/lib.rs",
|
|
"
|
|
fn a() {}
|
|
fn b() {}
|
|
",
|
|
)
|
|
.build();
|
|
|
|
let agnostic_path = Path::new("src").join("lib.rs");
|
|
let agnostic_path_s = agnostic_path.to_str().unwrap();
|
|
|
|
// Capture what rustc actually emits. This is done to avoid relying on the
|
|
// exact message formatting in rustc.
|
|
let rustc_output = process("rustc")
|
|
.cwd(p.root())
|
|
.args(&["--crate-type=lib", agnostic_path_s])
|
|
.exec_with_output()
|
|
.expect("rustc to run");
|
|
|
|
assert!(rustc_output.stdout.is_empty());
|
|
assert!(rustc_output.status.success());
|
|
|
|
// -q so the output is the same as rustc (no "Compiling" or "Finished").
|
|
let cargo_output1 = p
|
|
.cargo("check -Zcache-messages -q --color=never")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output1.stderr));
|
|
assert!(cargo_output1.stdout.is_empty());
|
|
// Check that the cached version is exactly the same.
|
|
let cargo_output2 = p
|
|
.cargo("check -Zcache-messages -q")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output2.stderr));
|
|
assert!(cargo_output2.stdout.is_empty());
|
|
}
|
|
|
|
// same as `simple`, except everything is using the short format
|
|
#[cargo_test]
|
|
fn simple_short() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
let p = project()
|
|
.file(
|
|
"src/lib.rs",
|
|
"
|
|
fn a() {}
|
|
fn b() {}
|
|
",
|
|
)
|
|
.build();
|
|
|
|
let agnostic_path = Path::new("src").join("lib.rs");
|
|
let agnostic_path_s = agnostic_path.to_str().unwrap();
|
|
|
|
let rustc_output = process("rustc")
|
|
.cwd(p.root())
|
|
.args(&["--crate-type=lib", agnostic_path_s, "--error-format=short"])
|
|
.exec_with_output()
|
|
.expect("rustc to run");
|
|
|
|
assert!(rustc_output.stdout.is_empty());
|
|
assert!(rustc_output.status.success());
|
|
|
|
let cargo_output1 = p
|
|
.cargo("check -Zcache-messages -q --color=never --message-format=short")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output1.stderr));
|
|
// assert!(cargo_output1.stdout.is_empty());
|
|
let cargo_output2 = p
|
|
.cargo("check -Zcache-messages -q --message-format=short")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
println!("{}", String::from_utf8_lossy(&cargo_output2.stdout));
|
|
assert_eq!(as_str(&rustc_output.stderr), as_str(&cargo_output2.stderr));
|
|
assert!(cargo_output2.stdout.is_empty());
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn color() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Check enabling/disabling color.
|
|
let p = project().file("src/lib.rs", "fn a() {}").build();
|
|
|
|
let agnostic_path = Path::new("src").join("lib.rs");
|
|
let agnostic_path_s = agnostic_path.to_str().unwrap();
|
|
// Capture the original color output.
|
|
let rustc_output = process("rustc")
|
|
.cwd(p.root())
|
|
.args(&["--crate-type=lib", agnostic_path_s, "--color=always"])
|
|
.exec_with_output()
|
|
.expect("rustc to run");
|
|
assert!(rustc_output.status.success());
|
|
let rustc_color = as_str(&rustc_output.stderr);
|
|
assert!(rustc_color.contains("\x1b["));
|
|
|
|
// Capture the original non-color output.
|
|
let rustc_output = process("rustc")
|
|
.cwd(p.root())
|
|
.args(&["--crate-type=lib", agnostic_path_s])
|
|
.exec_with_output()
|
|
.expect("rustc to run");
|
|
let rustc_nocolor = as_str(&rustc_output.stderr);
|
|
assert!(!rustc_nocolor.contains("\x1b["));
|
|
|
|
// First pass, non-cached, with color, should be the same.
|
|
let cargo_output1 = p
|
|
.cargo("check -Zcache-messages -q --color=always")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(rustc_color, as_str(&cargo_output1.stderr));
|
|
|
|
// Replay cached, with color.
|
|
let cargo_output2 = p
|
|
.cargo("check -Zcache-messages -q --color=always")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(rustc_color, as_str(&cargo_output2.stderr));
|
|
|
|
// Replay cached, no color.
|
|
let cargo_output_nocolor = p
|
|
.cargo("check -Zcache-messages -q --color=never")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(rustc_nocolor, as_str(&cargo_output_nocolor.stderr));
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn cached_as_json() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Check that cached JSON output is the same.
|
|
let p = project().file("src/lib.rs", "fn a() {}").build();
|
|
|
|
// Grab the non-cached output, feature disabled.
|
|
// NOTE: When stabilizing, this will need to be redone.
|
|
let cargo_output = p
|
|
.cargo("check --message-format=json")
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert!(cargo_output.status.success());
|
|
let orig_cargo_out = as_str(&cargo_output.stdout);
|
|
assert!(orig_cargo_out.contains("compiler-message"));
|
|
p.cargo("clean").run();
|
|
|
|
// Check JSON output, not fresh.
|
|
let cargo_output1 = p
|
|
.cargo("check -Zcache-messages --message-format=json")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
assert_eq!(as_str(&cargo_output1.stdout), orig_cargo_out);
|
|
|
|
// Check JSON output, fresh.
|
|
let cargo_output2 = p
|
|
.cargo("check -Zcache-messages --message-format=json")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("cargo to run");
|
|
// The only difference should be this field.
|
|
let fix_fresh = as_str(&cargo_output2.stdout).replace("\"fresh\":true", "\"fresh\":false");
|
|
assert_eq!(fix_fresh, orig_cargo_out);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn clears_cache_after_fix() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Make sure the cache is invalidated when there is no output.
|
|
let p = project().file("src/lib.rs", "fn asdf() {}").build();
|
|
// Fill the cache.
|
|
p.cargo("check -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]asdf[..]")
|
|
.run();
|
|
let cpath = p
|
|
.glob("target/debug/.fingerprint/foo-*/output")
|
|
.next()
|
|
.unwrap()
|
|
.unwrap();
|
|
assert!(std::fs::read_to_string(cpath).unwrap().contains("asdf"));
|
|
|
|
// Fix it.
|
|
p.change_file("src/lib.rs", "");
|
|
|
|
p.cargo("check -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stdout("")
|
|
.with_stderr(
|
|
"\
|
|
[CHECKING] foo [..]
|
|
[FINISHED] [..]
|
|
",
|
|
)
|
|
.run();
|
|
assert_eq!(p.glob("target/debug/.fingerprint/foo-*/output").count(), 0);
|
|
|
|
// And again, check the cache is correct.
|
|
p.cargo("check -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stdout("")
|
|
.with_stderr(
|
|
"\
|
|
[FINISHED] [..]
|
|
",
|
|
)
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn rustdoc() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Create a warning in rustdoc.
|
|
let p = project()
|
|
.file(
|
|
"src/lib.rs",
|
|
"
|
|
#![warn(private_doc_tests)]
|
|
/// asdf
|
|
/// ```
|
|
/// let x = 1;
|
|
/// ```
|
|
fn f() {}
|
|
",
|
|
)
|
|
.build();
|
|
|
|
// At this time, rustdoc does not support --json-rendered=termcolor. So it
|
|
// will always be uncolored with -Zcache-messages.
|
|
let rustdoc_output = p
|
|
.cargo("doc -Zcache-messages -q")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("rustdoc to run");
|
|
assert!(rustdoc_output.status.success());
|
|
let rustdoc_stderr = as_str(&rustdoc_output.stderr);
|
|
assert!(rustdoc_stderr.contains("private"));
|
|
// Invert this when --json-rendered is added.
|
|
assert!(!rustdoc_stderr.contains("\x1b["));
|
|
assert_eq!(p.glob("target/debug/.fingerprint/foo-*/output").count(), 1);
|
|
|
|
// Check the cached output.
|
|
let rustdoc_output = p
|
|
.cargo("doc -Zcache-messages -q")
|
|
.masquerade_as_nightly_cargo()
|
|
.exec_with_output()
|
|
.expect("rustdoc to run");
|
|
assert_eq!(as_str(&rustdoc_output.stderr), rustdoc_stderr);
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn fix() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Make sure `fix` is not broken by caching.
|
|
let p = project().file("src/lib.rs", "pub fn try() {}").build();
|
|
|
|
p.cargo("fix --edition --allow-no-vcs -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.run();
|
|
|
|
assert_eq!(p.read_file("src/lib.rs"), "pub fn r#try() {}");
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn clippy() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
eprintln!("skipping test: requires nightly");
|
|
return;
|
|
}
|
|
|
|
if !clippy_is_available() {
|
|
return;
|
|
}
|
|
|
|
// Caching clippy output.
|
|
// This is just a random clippy lint (assertions_on_constants) that
|
|
// hopefully won't change much in the future.
|
|
let p = project()
|
|
.file("src/lib.rs", "pub fn f() { assert!(true); }")
|
|
.build();
|
|
|
|
p.cargo("clippy-preview -Zunstable-options -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]assert!(true)[..]")
|
|
.run();
|
|
|
|
// Again, reading from the cache.
|
|
p.cargo("clippy-preview -Zunstable-options -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]assert!(true)[..]")
|
|
.run();
|
|
|
|
// FIXME: Unfortunately clippy is sharing the same hash with check. This
|
|
// causes the cache to be reused when it shouldn't.
|
|
p.cargo("check -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]assert!(true)[..]") // This should not be here.
|
|
.run();
|
|
}
|
|
|
|
#[cargo_test]
|
|
fn very_verbose() {
|
|
if !is_nightly() {
|
|
// --json-rendered is unstable
|
|
return;
|
|
}
|
|
// Handle cap-lints in dependencies.
|
|
Package::new("bar", "1.0.0")
|
|
.file("src/lib.rs", "fn not_used() {}")
|
|
.publish();
|
|
|
|
let p = project()
|
|
.file(
|
|
"Cargo.toml",
|
|
r#"
|
|
[package]
|
|
name = "foo"
|
|
version = "0.1.0"
|
|
|
|
[dependencies]
|
|
bar = "1.0"
|
|
"#,
|
|
)
|
|
.file("src/lib.rs", "")
|
|
.build();
|
|
|
|
p.cargo("check -Zcache-messages -vv")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]not_used[..]")
|
|
.run();
|
|
|
|
p.cargo("check -Zcache-messages")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr("[FINISHED] [..]")
|
|
.run();
|
|
|
|
p.cargo("check -Zcache-messages -vv")
|
|
.masquerade_as_nightly_cargo()
|
|
.with_stderr_contains("[..]not_used[..]")
|
|
.run();
|
|
}
|