Skip to content

Commit

Permalink
fix(run): makes run never prompt
Browse files Browse the repository at this point in the history
`watch` and `verify` do prompt the user to actively move to the
next exercise. This change fixes `run` to never prompt. Previously
it was inconsistent between "test" and "compile" exercises.

BREAKING CHANGE: we again change the behavior of the `run` command
  • Loading branch information
jrvidal committed Nov 12, 2019
1 parent bc56788 commit 4b26546
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 20 deletions.
28 changes: 28 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ path = "src/main.rs"

[dev-dependencies]
assert_cmd = "0.11.0"
predicates = "1.0.1"
glob = "0.3.0"
4 changes: 1 addition & 3 deletions src/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use indicatif::ProgressBar;

pub fn run(exercise: &Exercise) -> Result<(), ()> {
match exercise.mode {
Mode::Test => {
test(exercise)?;
}
Mode::Test => test(exercise)?,
Mode::Compile => compile_and_run(exercise)?,
}
Ok(())
Expand Down
40 changes: 23 additions & 17 deletions src/verify.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use crate::exercise::{ContextLine, Exercise, Mode, State};
use crate::exercise::{Exercise, Mode, State};
use console::{style, Emoji};
use indicatif::ProgressBar;

pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<(), ()> {
for exercise in start_at {
let is_done = match exercise.mode {
Mode::Test => test(&exercise)?,
Mode::Test => compile_and_test_interactively(&exercise)?,
Mode::Compile => compile_only(&exercise)?,
};
if !is_done {
Expand All @@ -15,6 +15,11 @@ pub fn verify<'a>(start_at: impl IntoIterator<Item = &'a Exercise>) -> Result<()
Ok(())
}

pub fn test(exercise: &Exercise) -> Result<(), ()> {
compile_and_test(exercise, true)?;
Ok(())
}

fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message(format!("Compiling {}...", exercise).as_str());
Expand All @@ -25,12 +30,7 @@ fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
let formatstr = format!("{} Successfully compiled {}!", Emoji("✅", "✓"), exercise);
println!("{}", style(formatstr).green());
exercise.clean();
if let State::Pending(context) = exercise.state() {
print_everything_looks_good(exercise.mode, context);
Ok(false)
} else {
Ok(true)
}
Ok(prompt_for_completion(&exercise))
} else {
let formatstr = format!(
"{} Compilation of {} failed! Compiler error message:\n",
Expand All @@ -44,7 +44,11 @@ fn compile_only(exercise: &Exercise) -> Result<bool, ()> {
}
}

pub fn test(exercise: &Exercise) -> Result<bool, ()> {
fn compile_and_test_interactively(exercise: &Exercise) -> Result<bool, ()> {
compile_and_test(exercise, false)
}

fn compile_and_test(exercise: &Exercise, skip_prompt: bool) -> Result<bool, ()> {
let progress_bar = ProgressBar::new_spinner();
progress_bar.set_message(format!("Testing {}...", exercise).as_str());
progress_bar.enable_steady_tick(100);
Expand All @@ -60,12 +64,7 @@ pub fn test(exercise: &Exercise) -> Result<bool, ()> {
let formatstr = format!("{} Successfully tested {}!", Emoji("✅", "✓"), exercise);
println!("{}", style(formatstr).green());
exercise.clean();
if let State::Pending(context) = exercise.state() {
print_everything_looks_good(exercise.mode, context);
Ok(false)
} else {
Ok(true)
}
Ok(skip_prompt || prompt_for_completion(exercise))
} else {
let formatstr = format!(
"{} Testing of {} failed! Please try again. Here's the output:",
Expand All @@ -91,8 +90,13 @@ pub fn test(exercise: &Exercise) -> Result<bool, ()> {
}
}

fn print_everything_looks_good(mode: Mode, context: Vec<ContextLine>) {
let success_msg = match mode {
fn prompt_for_completion(exercise: &Exercise) -> bool {
let context = match exercise.state() {
State::Done => return true,
State::Pending(context) => context,
};

let success_msg = match exercise.mode {
Mode::Compile => "The code is compiling!",
Mode::Test => "The code is compiling, and the tests pass!",
};
Expand Down Expand Up @@ -120,4 +124,6 @@ fn print_everything_looks_good(mode: Mode, context: Vec<ContextLine>) {
formatted_line
);
}

false
}
5 changes: 5 additions & 0 deletions tests/fixture/state/finished_exercise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// fake_exercise

fn main() {

}
11 changes: 11 additions & 0 deletions tests/fixture/state/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[[exercises]]
name = "pending_exercise"
path = "pending_exercise.rs"
mode = "compile"
hint = """"""

[[exercises]]
name = "pending_test_exercise"
path = "pending_test_exercise.rs"
mode = "test"
hint = """"""
4 changes: 4 additions & 0 deletions tests/fixture/state/pending_test_exercise.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// I AM NOT DONE

#[test]
fn it_works() {}
23 changes: 23 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use assert_cmd::prelude::*;
use glob::glob;
use predicates::boolean::PredicateBooleanExt;
use std::fs::File;
use std::io::Read;
use std::process::Command;
Expand Down Expand Up @@ -136,3 +137,25 @@ fn all_exercises_require_confirmation() {
));
}
}

#[test]
fn run_compile_exercise_does_not_prompt() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
.stdout(predicates::str::contains("I AM NOT DONE").not());
}

#[test]
fn run_test_exercise_does_not_prompt() {
Command::cargo_bin("rustlings")
.unwrap()
.args(&["r", "pending_test_exercise"])
.current_dir("tests/fixture/state")
.assert()
.code(0)
.stdout(predicates::str::contains("I AM NOT DONE").not());
}

0 comments on commit 4b26546

Please sign in to comment.