diff options
| author | Abdou Seck <djily02016@gmail.com> | 2020-06-04 10:31:17 -0400 |
|---|---|---|
| committer | Abdou Seck <djily02016@gmail.com> | 2020-06-04 11:18:26 -0400 |
| commit | 8ad5f9bf531a4848b1104b7b389a20171624c82f (patch) | |
| tree | 331c5d3725140b07d836ed8be6df30c8ddfd63fb /src/exercise.rs | |
| parent | 02a2fe48714a4546b28d38fb611e6bfce9f43cf6 (diff) | |
feat: Add a --nocapture option to display test harnesses' outputs
This new feature can be accessed by invoking rustlings with --nocapture.
Both unit and integration tests added.
closes #262
BREAKING CHANGES:
The following function take a new boolean argument:
* `run`
* `verify`
* `test`
* `compile_and_test`
Diffstat (limited to 'src/exercise.rs')
| -rw-r--r-- | src/exercise.rs | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/exercise.rs b/src/exercise.rs index d1eaa1a..177b7f3 100644 --- a/src/exercise.rs +++ b/src/exercise.rs @@ -11,15 +11,21 @@ const I_AM_DONE_REGEX: &str = r"(?m)^\s*///?\s*I\s+AM\s+NOT\s+DONE"; const CONTEXT: usize = 2; const CLIPPY_CARGO_TOML_PATH: &str = "./exercises/clippy/Cargo.toml"; +// Get a temporary file name that is hopefully unique to this process +#[inline] fn temp_file() -> String { format!("./temp_{}", process::id()) } +// The mode of the exercise. #[derive(Deserialize, Copy, Clone)] #[serde(rename_all = "lowercase")] pub enum Mode { + // Indicates that the exercise should be compiled as a binary Compile, + // Indicates that the exercise should be compiled as a test harness Test, + // Indicates that the exercise should be linted with clippy Clippy, } @@ -28,41 +34,60 @@ pub struct ExerciseList { pub exercises: Vec<Exercise>, } +// A representation of a rustlings exercise. +// This is deserialized from the accompanying info.toml file #[derive(Deserialize)] pub struct Exercise { + // Name of the exercise pub name: String, + // The path to the file containing the exercise's source code pub path: PathBuf, + // The mode of the exercise (Test, Compile, or Clippy) pub mode: Mode, + // The hint text associated with the exercise pub hint: String, } +// An enum to track of the state of an Exercise. +// An Exercise can be either Done or Pending #[derive(PartialEq, Debug)] pub enum State { + // The state of the exercise once it's been completed Done, + // The state of the exercise while it's not completed yet Pending(Vec<ContextLine>), } +// The context information of a pending exercise #[derive(PartialEq, Debug)] pub struct ContextLine { + // The source code that is still pending completion pub line: String, + // The line number of the source code still pending completion pub number: usize, + // Whether or not this is important pub important: bool, } +// The result of compiling an exercise pub struct CompiledExercise<'a> { exercise: &'a Exercise, _handle: FileHandle, } impl<'a> CompiledExercise<'a> { + // Run the compiled exercise pub fn run(&self) -> Result<ExerciseOutput, ExerciseOutput> { self.exercise.run() } } +// A representation of an already executed binary #[derive(Debug)] pub struct ExerciseOutput { + // The textual contents of the standard output of the binary pub stdout: String, + // The textual contents of the standard error of the binary pub stderr: String, } @@ -140,7 +165,11 @@ path = "{}.rs""#, } fn run(&self) -> Result<ExerciseOutput, ExerciseOutput> { - let cmd = Command::new(&temp_file()) + let arg = match self.mode { + Mode::Test => "--show-output", + _ => "" + }; + let cmd = Command::new(&temp_file()).arg(arg) .output() .expect("Failed to run 'run' command"); @@ -205,6 +234,7 @@ impl Display for Exercise { } } +#[inline] fn clean() { let _ignored = remove_file(&temp_file()); } @@ -280,4 +310,16 @@ mod test { assert_eq!(exercise.state(), State::Done); } + + #[test] + fn test_exercise_with_output() { + let exercise = Exercise { + name: "finished_exercise".into(), + path: PathBuf::from("tests/fixture/success/testSuccess.rs"), + mode: Mode::Test, + hint: String::new(), + }; + let out = exercise.compile().unwrap().run().unwrap(); + assert!(out.stdout.contains("THIS TEST TOO SHALL PASS")); + } } |
