Fix test error hint in a workspace.
authorEric Huss <eric@huss.org>
Mon, 26 Feb 2018 00:51:48 +0000 (16:51 -0800)
committerEric Huss <eric@huss.org>
Mon, 26 Feb 2018 00:51:48 +0000 (16:51 -0800)
This adds "-p NAME" to the hint on how to re-run a test when it fails if it is
inside a workspace.

Fixes #5053

src/bin/test.rs
src/cargo/ops/cargo_test.rs
src/cargo/util/errors.rs
tests/testsuite/test.rs

index 242f1ebb25cc147eb232be03929325d2bc710fe6..d13e9edbc624388d4e39c38c80fd682ec25923aa 100644 (file)
@@ -186,7 +186,7 @@ pub fn execute(mut options: Options, config: &mut Config) -> CliResult {
         None => Ok(()),
         Some(err) => {
             Err(match err.exit.as_ref().and_then(|e| e.code()) {
-                Some(i) => CliError::new(format_err!("{}", err.hint()), i),
+                Some(i) => CliError::new(format_err!("{}", err.hint(&ws)), i),
                 None => CliError::new(err.into(), 101),
             })
         }
index deb547b62376fe4a5e39d62ae0c907cb620df39a..6e0ae53dbeeb2bb385145221eb0a1bb79090689d 100644 (file)
@@ -107,7 +107,7 @@ fn run_unit_tests(options: &TestOptions,
         match result {
             Err(e) => {
                 let e = e.downcast::<ProcessError>()?;
-                errors.push((kind.clone(), test.clone(), e));
+                errors.push((kind.clone(), test.clone(), pkg.name().to_string(), e));
                 if !options.no_fail_fast {
                     break;
                 }
@@ -117,10 +117,10 @@ fn run_unit_tests(options: &TestOptions,
     }
 
     if errors.len() == 1 {
-        let (kind, test, e) = errors.pop().unwrap();
-        Ok((Test::UnitTest(kind, test), vec![e]))
+        let (kind, name, pkg_name, e) = errors.pop().unwrap();
+        Ok((Test::UnitTest{kind, name, pkg_name}, vec![e]))
     } else {
-        Ok((Test::Multiple, errors.into_iter().map(|(_, _, e)| e).collect()))
+        Ok((Test::Multiple, errors.into_iter().map(|(_, _, _, e)| e).collect()))
     }
 }
 
index de2047ce89cf66d83ec86bf5cecc544f5e27ab50..565b41bb4c736a300db79edf9c2e64f2bdbf620e 100644 (file)
@@ -4,7 +4,7 @@ use std::fmt;
 use std::process::{Output, ExitStatus};
 use std::str;
 
-use core::TargetKind;
+use core::{TargetKind, Workspace};
 use failure::{Context, Error, Fail};
 
 pub use failure::Error as CargoError;
@@ -92,7 +92,7 @@ pub struct CargoTestError {
 pub enum Test {
     Multiple,
     Doc,
-    UnitTest(TargetKind, String)
+    UnitTest{kind: TargetKind, name: String, pkg_name: String}
 }
 
 impl CargoTestError {
@@ -111,16 +111,26 @@ impl CargoTestError {
         }
     }
 
-    pub fn hint(&self) -> String {
+    pub fn hint(&self, ws: &Workspace) -> String {
         match self.test {
-            Test::UnitTest(ref kind, ref name) => {
+            Test::UnitTest{ref kind, ref name, ref pkg_name} => {
+                let pkg_info = if ws.members().count() > 1 && ws.is_virtual() {
+                    format!("-p {} ", pkg_name)
+                } else {
+                    String::new()
+                };
+
                 match *kind {
-                    TargetKind::Bench => format!("test failed, to rerun pass '--bench {}'", name),
-                    TargetKind::Bin => format!("test failed, to rerun pass '--bin {}'", name),
-                    TargetKind::Lib(_) => "test failed, to rerun pass '--lib'".into(),
-                    TargetKind::Test => format!("test failed, to rerun pass '--test {}'", name),
+                    TargetKind::Bench =>
+                        format!("test failed, to rerun pass '{}--bench {}'", pkg_info, name),
+                    TargetKind::Bin =>
+                        format!("test failed, to rerun pass '{}--bin {}'", pkg_info, name),
+                    TargetKind::Lib(_) =>
+                        format!("test failed, to rerun pass '{}--lib'", pkg_info),
+                    TargetKind::Test =>
+                        format!("test failed, to rerun pass '{}--test {}'", pkg_info, name),
                     TargetKind::ExampleBin | TargetKind::ExampleLib(_) =>
-                        format!("test failed, to rerun pass '--example {}", name),
+                        format!("test failed, to rerun pass '{}--example {}", pkg_info, name),
                     _ => "test failed.".into()
                 }
             },
index 914a06d310a61deecce55bdc718a1c32b572a2a2..5b6d1d9c53b1db3381ffb0a61bbec158b51a0d5f 100644 (file)
@@ -2936,3 +2936,36 @@ fn test_hint_not_masked_by_doctest() {
                 .with_stderr_contains("[ERROR] test failed, to rerun pass \
                                       '--test integ'"));
 }
+
+#[test]
+fn test_hint_workspace() {
+   let workspace = project("workspace")
+        .file("Cargo.toml", r#"
+            [workspace]
+            members = ["a", "b"]
+        "#)
+        .file("a/Cargo.toml", r#"
+            [project]
+            name = "a"
+            version = "0.1.0"
+        "#)
+        .file("a/src/lib.rs", r#"
+            #[test]
+            fn t1() {}
+        "#)
+        .file("b/Cargo.toml", r#"
+            [project]
+            name = "b"
+            version = "0.1.0"
+        "#)
+        .file("b/src/lib.rs", r#"
+            #[test]
+            fn t1() {assert!(false)}
+        "#)
+        .build();
+
+    assert_that(workspace.cargo("test"),
+                execs().with_stderr_contains(
+                    "[ERROR] test failed, to rerun pass '-p b --lib'")
+                       .with_status(101));
+}