diff options
author | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-04-19 10:11:34 +0100 |
---|---|---|
committer | Daniel Silverstone <dsilvers@digital-scurf.org> | 2020-04-19 10:11:34 +0100 |
commit | e9c9133555ce5c8f1eecdbf1155a104f0170d865 (patch) | |
tree | 3fa0ba53f2a343c9a662565fbde6b9b4070268c4 /src/steps.rs | |
parent | e64d261ee8695e3403657d6f35adae07f766cf42 (diff) | |
download | subplot-e9c9133555ce5c8f1eecdbf1155a104f0170d865.tar.gz |
parse: Ensure continuation keywords cannot be used too early
We switch from assuming a continuation of `Given` by default
to passing Option<StepKind> around and ensuring that we do not
succeed in parsing a step if that is None.
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'src/steps.rs')
-rw-r--r-- | src/steps.rs | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/src/steps.rs b/src/steps.rs index b5d1d33..2c6f34f 100644 --- a/src/steps.rs +++ b/src/steps.rs @@ -40,15 +40,15 @@ impl ScenarioStep { /// /// If the step uses the "and" or "but" keyword, use the default /// step kind instead. - pub fn new_from_str(text: &str, default: StepKind) -> Result<ScenarioStep> { + pub fn new_from_str(text: &str, default: Option<StepKind>) -> Result<ScenarioStep> { let mut words = text.split_whitespace(); let kind = match words.next() { Some("given") => StepKind::Given, Some("when") => StepKind::When, Some("then") => StepKind::Then, - Some("and") => default, - Some("but") => default, + Some("and") => default.ok_or(SubplotError::ContinuationTooEarly)?, + Some("but") => default.ok_or(SubplotError::ContinuationTooEarly)?, _ => return Err(SubplotError::UnknownStepKind), }; @@ -100,42 +100,52 @@ impl fmt::Display for StepKind { #[cfg(test)] mod test { - use super::{ScenarioStep, StepKind}; + use super::{ScenarioStep, StepKind, SubplotError}; #[test] fn parses_given() { - let step = ScenarioStep::new_from_str("given I am Tomjon", StepKind::Then).unwrap(); + let step = ScenarioStep::new_from_str("given I am Tomjon", None).unwrap(); assert_eq!(step.kind(), StepKind::Given); assert_eq!(step.text(), "I am Tomjon"); } #[test] fn parses_given_with_extra_spaces() { - let step = - ScenarioStep::new_from_str(" given I am Tomjon ", StepKind::When).unwrap(); + let step = ScenarioStep::new_from_str(" given I am Tomjon ", None).unwrap(); assert_eq!(step.kind(), StepKind::Given); assert_eq!(step.text(), "I am Tomjon"); } #[test] fn parses_when() { - let step = - ScenarioStep::new_from_str("when I declare myself king", StepKind::Given).unwrap(); + let step = ScenarioStep::new_from_str("when I declare myself king", None).unwrap(); assert_eq!(step.kind(), StepKind::When); assert_eq!(step.text(), "I declare myself king"); } #[test] fn parses_then() { - let step = ScenarioStep::new_from_str("then everyone accepts it", StepKind::Given).unwrap(); + let step = ScenarioStep::new_from_str("then everyone accepts it", None).unwrap(); assert_eq!(step.kind(), StepKind::Then); assert_eq!(step.text(), "everyone accepts it"); } #[test] fn parses_and() { - let step = ScenarioStep::new_from_str("and everyone accepts it", StepKind::Then).unwrap(); + let step = + ScenarioStep::new_from_str("and everyone accepts it", Some(StepKind::Then)).unwrap(); assert_eq!(step.kind(), StepKind::Then); assert_eq!(step.text(), "everyone accepts it"); } + + #[test] + fn fails_to_parse_and() { + let step = ScenarioStep::new_from_str("and everyone accepts it", None); + assert!(step.is_err()); + match step.err() { + None => unreachable!(), + Some(SubplotError::ContinuationTooEarly) => (), + Some(e) => panic!("Incorrect error: {}", e), + } + } } |