cli-test: Log line of assertion being executed
This commit is contained in:
parent
9055a2043c
commit
ed2b36cf9c
|
|
@ -70,6 +70,8 @@ pub struct Assertion {
|
||||||
expected: String,
|
expected: String,
|
||||||
/// Expected exit status.
|
/// Expected exit status.
|
||||||
exit: ExitStatus,
|
exit: ExitStatus,
|
||||||
|
/// Line number in the test file where this assertion is defined.
|
||||||
|
line: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
||||||
|
|
@ -275,7 +277,7 @@ impl TestFormula {
|
||||||
let mut fenced = false; // Whether we're inside a fenced code block.
|
let mut fenced = false; // Whether we're inside a fenced code block.
|
||||||
let mut file: Option<(PathBuf, String)> = None; // Path and content of file created by this test block.
|
let mut file: Option<(PathBuf, String)> = None; // Path and content of file created by this test block.
|
||||||
|
|
||||||
for line in r.lines() {
|
for (row, line) in r.lines().enumerate() {
|
||||||
let line = line?;
|
let line = line?;
|
||||||
|
|
||||||
if line.starts_with("```") {
|
if line.starts_with("```") {
|
||||||
|
|
@ -343,6 +345,7 @@ impl TestFormula {
|
||||||
} else {
|
} else {
|
||||||
ExitStatus::Success
|
ExitStatus::Success
|
||||||
},
|
},
|
||||||
|
line: row + 1,
|
||||||
});
|
});
|
||||||
} else if let Some(a) = test.assertions.last_mut() {
|
} else if let Some(a) = test.assertions.last_mut() {
|
||||||
a.expected.push_str(line.as_str());
|
a.expected.push_str(line.as_str());
|
||||||
|
|
@ -411,13 +414,16 @@ impl TestFormula {
|
||||||
*arg = arg.replace(format!("${k}").as_str(), &v);
|
*arg = arg.replace(format!("${k}").as_str(), &v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let path = assertion
|
let location = assertion
|
||||||
.path
|
.path
|
||||||
.file_name()
|
.file_name()
|
||||||
.map(|f| f.to_string_lossy().to_string())
|
.map(|f| f.to_string_lossy().to_string())
|
||||||
|
.map(|f| f.strip_suffix(".md").unwrap_or(&f).to_owned())
|
||||||
|
.map(|f| f + ":" + assertion.line.to_string().as_str())
|
||||||
.unwrap_or(String::from("<none>"));
|
.unwrap_or(String::from("<none>"));
|
||||||
let cmd = if assertion.command == "rad" {
|
|
||||||
snapbox::cmd::cargo_bin("rad")
|
let (cmd, cmd_display) = if assertion.command == "rad" {
|
||||||
|
(snapbox::cmd::cargo_bin("rad"), "rad".to_string())
|
||||||
} else if assertion.command == "cd" {
|
} else if assertion.command == "cd" {
|
||||||
let arg = assertion.args.first().unwrap();
|
let arg = assertion.args.first().unwrap();
|
||||||
let dir: PathBuf = arg.into();
|
let dir: PathBuf = arg.into();
|
||||||
|
|
@ -426,7 +432,7 @@ impl TestFormula {
|
||||||
// TODO: Add support for `..` and `/`
|
// TODO: Add support for `..` and `/`
|
||||||
// TODO: Error if more than one args are given.
|
// TODO: Error if more than one args are given.
|
||||||
|
|
||||||
log::debug!(target: "test", "{path}: Running `cd {}`..", dir.display());
|
log::debug!(target: "test", "{location}: `cd {}`..", dir.display());
|
||||||
|
|
||||||
if !dir.exists() {
|
if !dir.exists() {
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
|
|
@ -438,12 +444,11 @@ impl TestFormula {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
PathBuf::from(&assertion.command)
|
(PathBuf::from(&assertion.command), assertion.command.clone())
|
||||||
};
|
};
|
||||||
log::debug!(target: "test", "{path}: Running `{}` with {:?} in `{}`..", cmd.display(), assertion.args, run.path().display());
|
|
||||||
|
|
||||||
if !run.path().exists() {
|
if !run.path().exists() {
|
||||||
log::warn!(target: "test", "{path}: Directory {} does not exist. Creating..", run.path().display());
|
log::warn!(target: "test", "{location}: Directory {} does not exist. Creating..", run.path().display());
|
||||||
fs::create_dir_all(run.path())?;
|
fs::create_dir_all(run.path())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,20 +468,24 @@ impl TestFormula {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(ffi::OsStr::new(&PATH_SEPARATOR.to_string()));
|
.join(ffi::OsStr::new(&PATH_SEPARATOR.to_string()));
|
||||||
|
|
||||||
log::debug!(target: "test", "Using PATH={:?}", bins);
|
let command = Command::new(cmd.clone())
|
||||||
|
|
||||||
let result = Command::new(cmd.clone())
|
|
||||||
.env_clear()
|
.env_clear()
|
||||||
.env("PATH", &bins)
|
.env("PATH", &bins)
|
||||||
.env("RUST_BACKTRACE", "1")
|
.env("RUST_BACKTRACE", "1")
|
||||||
.envs(jj_envs)
|
.envs(jj_envs)
|
||||||
.envs(run.envs())
|
.envs(run.envs())
|
||||||
.current_dir(run.path())
|
.current_dir(run.path())
|
||||||
.args(args)
|
.args(args.clone())
|
||||||
.with_assert(assert.clone())
|
.with_assert(assert.clone());
|
||||||
.output();
|
|
||||||
|
|
||||||
match result {
|
log::debug!(target: "test", "{location}: `{} {}` @ {}", cmd_display, args.join(" "), run.path().display());
|
||||||
|
log::trace!(target: "test", "{location}: {}", run.envs().map(|(k, v)| format!("{}={}", k, v)).collect::<Vec<_>>().join(", "));
|
||||||
|
log::logger().flush();
|
||||||
|
|
||||||
|
// Even though it would be possible to use `Command::assert` to directly obtain
|
||||||
|
// `OutputAssert`, we use `Command::output` to be able to handle `io::ErrorKind::NotFound`
|
||||||
|
// separately and provide a more helpful error message in that case.
|
||||||
|
match command.output() {
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
let assert = OutputAssert::new(output).with_assert(assert.clone());
|
let assert = OutputAssert::new(output).with_assert(assert.clone());
|
||||||
let expected = Self::map_spaced_brackets(&assertion.expected);
|
let expected = Self::map_spaced_brackets(&assertion.expected);
|
||||||
|
|
@ -507,11 +516,11 @@ impl TestFormula {
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
if err.kind() == io::ErrorKind::NotFound {
|
if err.kind() == io::ErrorKind::NotFound {
|
||||||
log::error!(target: "test", "{path}: Command `{}` does not exist..", cmd.display());
|
log::error!(target: "test", "{location}: Command `{}` does not exist..", cmd.display());
|
||||||
}
|
}
|
||||||
return Err(io::Error::new(
|
return Err(io::Error::new(
|
||||||
err.kind(),
|
err.kind(),
|
||||||
format!("{path}: {err}: `{}`", cmd.display()),
|
format!("{location}: {err}: `{}`", cmd.display()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -606,6 +615,7 @@ $ rad sync
|
||||||
home: None,
|
home: None,
|
||||||
assertions: vec![
|
assertions: vec![
|
||||||
Assertion {
|
Assertion {
|
||||||
|
line: 3,
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
command: String::from("rad"),
|
command: String::from("rad"),
|
||||||
args: vec![String::from("track"), String::from("@dave")],
|
args: vec![String::from("track"), String::from("@dave")],
|
||||||
|
|
@ -615,6 +625,7 @@ $ rad sync
|
||||||
exit: ExitStatus::Success,
|
exit: ExitStatus::Success,
|
||||||
},
|
},
|
||||||
Assertion {
|
Assertion {
|
||||||
|
line: 7,
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
command: String::from("rad"),
|
command: String::from("rad"),
|
||||||
args: vec![String::from("track"), String::from("@sean")],
|
args: vec![String::from("track"), String::from("@sean")],
|
||||||
|
|
@ -634,6 +645,7 @@ $ rad sync
|
||||||
context: vec![String::from("Super, now let's move on to the next step.")],
|
context: vec![String::from("Super, now let's move on to the next step.")],
|
||||||
home: Some("alice".to_owned()),
|
home: Some("alice".to_owned()),
|
||||||
assertions: vec![Assertion {
|
assertions: vec![Assertion {
|
||||||
|
line: 13,
|
||||||
path: path.clone(),
|
path: path.clone(),
|
||||||
command: String::from("rad"),
|
command: String::from("rad"),
|
||||||
args: vec![String::from("sync")],
|
args: vec![String::from("sync")],
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue