Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions features/custom_vars/file.feature
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,13 @@ Feature: define a custom variable with a part of the filename
When receiving the command '{ "command": "test-file", "file": "my_file.go" }'
Then it prints
"""
TRIGGER | RUN
test-file **/*.ts | echo testing {{file_without_ext}}.test.ts
Error: cannot determine command for trigger: test-file my_file.go
Please make sure that this action is listed in contest.json
The current configuration is:
Options:
- beforeRun.clearScreen: false
"""
# ensure the server is still running and functional
When receiving the command '{ "command": "test-file", "file": "my_file.ts" }'
Expand Down
5 changes: 5 additions & 0 deletions features/test_types/test_file.feature
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,13 @@ Feature: run all tests in a file
When receiving the command '{ "command": "test-file", "file": "foo.go" }'
Then it prints
"""
TRIGGER | RUN
test-file **/*.test.ts | echo testing file {{file}}
Error: cannot determine command for trigger: test-file foo.go
Please make sure that this action is listed in contest.json
The current configuration is:
Options:
- beforeRun.clearScreen: false
"""
# ensure the server is still running and functional
When receiving the command '{ "command": "test-file", "file": "test/chars.test.ts" }'
Expand Down
5 changes: 5 additions & 0 deletions features/test_types/test_file_line.feature
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,13 @@ Feature: test only a specific function
When receiving the command '{ "command": "test-file-line", "file": "foo.go", "line": 23 }'
Then it prints
"""
TRIGGER | RUN
test-file-line **/*.ts | echo testing file {{file}}:{{line}}
Error: cannot determine command for trigger: test-file-line foo.go:23
Please make sure that this action is listed in contest.json
The current configuration is:
Options:
- beforeRun.clearScreen: false
"""
# ensure the server is still running and functional
When receiving the command '{ "command": "test-file-line", "file": "foo.ts", "line": 23 }'
Expand Down
78 changes: 45 additions & 33 deletions src/client/trigger.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! commands received from the client (through the FIFO)

use super::fifo_data::FifoTrigger;
use crate::UserError;
use crate::config::Configuration;
use crate::{Result, UserError};
use std::fmt::Display;

#[derive(Debug, Eq, PartialEq)]
Expand All @@ -14,23 +15,8 @@ pub enum Trigger {
Quit,
}

impl Display for Trigger {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Trigger::TestAll => f.write_str("test-all"),
Trigger::TestFile { file } => write!(f, "test-file {file}"),
Trigger::TestFileLine { file, line } => write!(f, "test-file-line {file}:{line}"),
Trigger::CustomCommand { run } => write!(f, "custom-command {run}"),
Trigger::RepeatLastTest => f.write_str("repeat-test"),
Trigger::Quit => f.write_str("quit"),
}
}
}

impl TryFrom<FifoTrigger> for Trigger {
type Error = UserError;

fn try_from(fifo: FifoTrigger) -> std::result::Result<Self, Self::Error> {
impl Trigger {
fn try_from_fifo(fifo: FifoTrigger, config: &Configuration) -> Result<Trigger> {
match fifo.data.command.to_ascii_lowercase().as_str() {
"test-all" => Ok(Trigger::TestAll),
"repeat-test" => Ok(Trigger::RepeatLastTest),
Expand All @@ -49,16 +35,29 @@ impl TryFrom<FifoTrigger> for Trigger {
(None, None) => Err(UserError::MissingFileAndLineInTrigger { original: fifo.original_line }),
},
"quit" => Ok(Trigger::Quit),
_ => Err(UserError::UnknownTrigger { source: fifo.data.command }),
_ => Err(UserError::UnknownTrigger {
source: fifo.data.command,
config: config.clone(),
}),
}
}
}

impl TryFrom<String> for Trigger {
type Error = UserError;
pub fn try_from_string(value: String, config: &Configuration) -> Result<Trigger> {
let fifo = FifoTrigger::parse(value)?;
Trigger::try_from_fifo(fifo, config)
}
}

fn try_from(value: String) -> std::result::Result<Self, Self::Error> {
Trigger::try_from(FifoTrigger::parse(value)?)
impl Display for Trigger {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Trigger::TestAll => f.write_str("test-all"),
Trigger::TestFile { file } => write!(f, "test-file {file}"),
Trigger::TestFileLine { file, line } => write!(f, "test-file-line {file}:{line}"),
Trigger::CustomCommand { run } => write!(f, "custom-command {run}"),
Trigger::RepeatLastTest => f.write_str("repeat-test"),
Trigger::Quit => f.write_str("quit"),
}
}
}

Expand All @@ -68,6 +67,7 @@ mod tests {
mod into_trigger {
use crate::client::fifo_data::FifoTriggerData;
use crate::client::{FifoTrigger, Trigger};
use crate::config::Configuration;
use big_s::S;

#[test]
Expand All @@ -79,7 +79,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_trigger).unwrap();
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_trigger, &config).unwrap();
let want = Trigger::TestAll;
assert_eq!(have, want);
}
Expand All @@ -93,14 +94,16 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data).unwrap();
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config).unwrap();
let want = Trigger::RepeatLastTest;
assert_eq!(have, want);
}

mod custom_command {
use crate::client::fifo_data::FifoTriggerData;
use crate::client::{FifoTrigger, Trigger};
use crate::config::Configuration;
use big_s::S;

#[test]
Expand All @@ -113,7 +116,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data).unwrap();
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config).unwrap();
let want = Trigger::CustomCommand { run: S("echo hello") };
assert_eq!(have, want);
}
Expand All @@ -128,14 +132,16 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data);
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config);
assert!(have.is_err());
}
}

mod test_file {
use crate::client::fifo_data::FifoTriggerData;
use crate::client::{FifoTrigger, Trigger};
use crate::config::Configuration;
use big_s::S;

#[test]
Expand All @@ -148,7 +154,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data).unwrap();
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config).unwrap();
let want = Trigger::TestFile { file: S("file.rs") };
assert_eq!(have, want);
}
Expand All @@ -163,14 +170,16 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data);
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config);
assert!(have.is_err());
}
}

mod test_function {
use crate::client::fifo_data::FifoTriggerData;
use crate::client::{FifoTrigger, Trigger};
use crate::config::Configuration;
use big_s::S;

#[test]
Expand All @@ -184,7 +193,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data).unwrap();
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config).unwrap();
let want = Trigger::TestFileLine { file: S("file.rs"), line: 2 };
assert_eq!(have, want);
}
Expand All @@ -200,7 +210,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data);
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config);
assert!(have.is_err());
}

Expand All @@ -215,7 +226,8 @@ mod tests {
},
..FifoTrigger::default()
};
let have = Trigger::try_from(fifo_data);
let config = Configuration::default();
let have = Trigger::try_from_fifo(fifo_data, &config);
assert!(have.is_err());
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::UserError;
use crate::config::file::{ActionType, FileAction};

/// Actions are executed when receiving a command.
#[derive(Debug, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Action {
pub pattern: Pattern,
pub run: String,
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/after_run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::config::file::FileAfterRun;

#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AfterRun {
pub newlines: usize,
pub indicator_lines: usize,
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/before_run.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::config::file::FileBeforeRun;

#[derive(Debug, Default, Eq, PartialEq)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct BeforeRun {
pub clear_screen: bool,
pub newlines: usize,
Expand Down
7 changes: 5 additions & 2 deletions src/config/data/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::{fs, io};
/// filename of the Contest config file
pub const JSON_PATH: &str = "contest.json";

#[derive(Debug, Default, PartialEq)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Configuration {
pub actions: Vec<Action>,
pub options: Options,
Expand Down Expand Up @@ -71,7 +71,10 @@ impl Configuration {
return format_run(action, trigger);
}
}
Err(UserError::UnknownTrigger { source: trigger.to_string() })
Err(UserError::UnknownTrigger {
source: trigger.to_string(),
config: self.clone(),
})
}

pub fn read() -> Result<Configuration> {
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/options.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{AfterRun, BeforeRun};
use crate::config::file::FileOptions;

#[derive(Debug, Default, Eq, PartialEq)]
#[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct Options {
pub before_run: BeforeRun,
pub after_run: AfterRun,
Expand Down
2 changes: 1 addition & 1 deletion src/config/data/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::client::Trigger;
use std::fmt::Display;

/// a pattern defined in the config file, describes conditions that match actions
#[derive(Debug, Eq, PartialEq)]
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Pattern {
TestAll,
TestFile { files: glob::Pattern },
Expand Down
17 changes: 16 additions & 1 deletion src/config/data/var.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,22 @@ impl Var {

impl PartialEq for Var {
fn eq(&self, other: &Self) -> bool {
self.name == other.name && self.source == other.source && self.filter.to_string() == other.filter.to_string()
self.name == other.name && self.source == other.source && self.filter.as_str() == other.filter.as_str()
}
}

impl Eq for Var {}

impl Clone for Var {
fn clone(&self) -> Self {
// SAFETY: We know the regex is valid because it was validated during construction
#[allow(clippy::unwrap_used)]
let filter = Regex::new(self.filter.as_str()).unwrap();
Var {
name: self.name.clone(),
source: self.source.clone(),
filter,
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/config/data/var_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use schemars::JsonSchema;
use serde::Deserialize;
use std::fmt::{self, Display};

#[derive(Debug, Deserialize, Eq, JsonSchema, PartialEq)]
#[derive(Clone, Debug, Deserialize, Eq, JsonSchema, PartialEq)]
#[serde(rename_all = "camelCase")]
pub enum VarSource {
File,
Expand Down
11 changes: 7 additions & 4 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! error types used in this app

use crate::config;
use crate::config::Configuration;
use crate::config::file::ActionType;
use big_s::S;

Expand Down Expand Up @@ -37,7 +37,7 @@ pub enum UserError {
TriggerTooManyCaptures { count: usize, regex: String, line: String },
TriggerRegexNotFound { regex: String, filename: String, line: usize },
UnknownActionType { action_type: ActionType },
UnknownTrigger { source: String },
UnknownTrigger { source: String, config: Configuration },
}

impl UserError {
Expand Down Expand Up @@ -102,9 +102,12 @@ impl UserError {
format!("unknown action type: {action_type}"),
Some(S(r#"Valid types are "test-all", "test-file", and "test-file-line"."#)),
),
UserError::UnknownTrigger { source } => (
UserError::UnknownTrigger { source, config } => (
format!("cannot determine command for trigger: {source}"),
Some(format!("Please make sure that this action is listed in {}", config::JSON_PATH)),
Some(format!(
"Please make sure that this action is listed in {}.\n\nThe current configuration is:\n\n{config}",
crate::config::JSON_PATH
)),
),
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ pub fn run_with_decoration(text: String, config: &config::Configuration, debug:
if config.options.before_run.clear_screen {
print!("{esc}[2J{esc}[1;1H{esc}c", esc = 27 as char);
}
let trigger = Trigger::try_from(text)?;
let trigger = Trigger::try_from_string(text, config)?;
if trigger == Trigger::Quit {
return Ok(RunOutcome::Quit);
}
Expand Down Expand Up @@ -88,7 +88,7 @@ fn run_command(trigger: &Trigger, configuration: &config::Configuration, last_co
cli::print_error(err);
return Ok(subshell::Outcome::TestFail);
}
UserError::UnknownTrigger { source: _ } => {
UserError::UnknownTrigger { source: _, config: _ } => {
// user sent a trigger from the wrong file --> let them know and send one from the correct file
cli::print_error(err);
return Ok(subshell::Outcome::TestFail);
Expand Down
Loading