rustlings/tests/integration_tests.rs

153 lines
3.3 KiB
Rust
Raw Normal View History

2024-07-25 15:34:43 +03:00
use std::{
env::{self, consts::EXE_SUFFIX},
process::{Command, Stdio},
str::from_utf8,
};
#[derive(Default)]
struct Cmd<'a> {
current_dir: Option<&'a str>,
args: &'a [&'a str],
stdout: Option<&'a str>,
full_stdout: bool,
}
impl<'a> Cmd<'a> {
#[inline]
fn current_dir(&mut self, current_dir: &'a str) -> &mut Self {
self.current_dir = Some(current_dir);
self
}
#[inline]
fn args(&mut self, args: &'a [&'a str]) -> &mut Self {
self.args = args;
self
}
#[inline]
fn stdout(&mut self, stdout: &'a str) -> &mut Self {
self.stdout = Some(stdout);
self
}
#[inline]
fn full_stdout(&mut self) -> &mut Self {
self.full_stdout = true;
self
}
fn assert(&self, success: bool) {
let rustlings_bin = {
let mut path = env::current_exe().unwrap();
// Pop test binary name
path.pop();
// Pop `/deps`
path.pop();
path.push("rustlings");
let mut path = path.into_os_string();
path.push(EXE_SUFFIX);
path
};
let mut cmd = Command::new(rustlings_bin);
if let Some(current_dir) = self.current_dir {
cmd.current_dir(current_dir);
}
cmd.args(self.args)
.stdin(Stdio::null())
.stderr(Stdio::null());
let status = if let Some(expected_stdout) = self.stdout {
let output = cmd.output().unwrap();
let stdout = from_utf8(&output.stdout).unwrap();
if self.full_stdout {
assert_eq!(stdout, expected_stdout);
} else {
assert!(stdout.contains(expected_stdout));
}
output.status
} else {
cmd.stdout(Stdio::null()).status().unwrap()
};
assert_eq!(status.success(), success);
}
#[inline]
fn success(&self) {
self.assert(true);
}
#[inline]
fn fail(&self) {
self.assert(false);
}
}
2019-03-20 23:05:45 +03:00
#[test]
2024-07-25 16:12:14 +03:00
fn wrong_dir() {
2024-07-25 15:34:43 +03:00
Cmd::default().current_dir("tests").fail();
2019-03-20 23:05:45 +03:00
}
#[test]
2024-07-25 16:12:14 +03:00
fn run_compilation_success() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["run", "compilation_success"])
2019-03-20 23:05:45 +03:00
.success();
}
#[test]
2024-07-25 16:12:14 +03:00
fn run_compilation_failure() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["run", "compilation_failure"])
2024-07-25 15:34:43 +03:00
.fail();
}
2019-03-20 23:05:45 +03:00
#[test]
2024-07-25 16:12:14 +03:00
fn run_test_success() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["run", "test_success"])
.stdout("\nOutput from `main` function\n")
2019-03-20 23:05:45 +03:00
.success();
}
#[test]
2024-07-25 16:12:14 +03:00
fn run_test_failure() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["run", "test_failure"])
2024-07-25 15:34:43 +03:00
.fail();
}
2019-05-09 20:16:06 +03:00
#[test]
2024-07-25 16:12:14 +03:00
fn run_exercise_not_in_info() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["run", "not_in_info"])
2024-07-25 15:34:43 +03:00
.fail();
2019-05-09 20:16:06 +03:00
}
2019-03-20 23:05:45 +03:00
#[test]
2024-07-25 16:12:14 +03:00
fn reset_without_exercise_name() {
2024-07-25 15:34:43 +03:00
Cmd::default().args(&["reset"]).fail();
2022-08-17 17:43:48 +03:00
}
2019-11-11 19:19:50 +03:00
#[test]
2024-07-25 16:12:14 +03:00
fn hint() {
2024-07-25 15:34:43 +03:00
Cmd::default()
2024-07-25 16:12:14 +03:00
.current_dir("tests/test_exercises")
.args(&["hint", "test_failure"])
.stdout("The answer to everything: 42\n")
2024-07-25 15:34:43 +03:00
.full_stdout()
.success();
2019-11-11 19:28:19 +03:00
}