summaryrefslogtreecommitdiff
path: root/subplotlib
diff options
context:
space:
mode:
authorDaniel Silverstone <dsilvers@digital-scurf.org>2023-08-12 11:35:22 +0100
committerDaniel Silverstone <dsilvers@digital-scurf.org>2023-08-12 11:35:22 +0100
commit6741b6a4479c27ab428bf2c3dd5d0af0963dd899 (patch)
tree5141d1d4a9d37453902e9aa65e9c90cc76642246 /subplotlib
parentdb8aef62e629b1bac2c72bb2590ba4caa90aa8d9 (diff)
downloadsubplot-6741b6a4479c27ab428bf2c3dd5d0af0963dd899.tar.gz
subplotlib: Add storage of location into scenario/scenariostep
Signed-off-by: Daniel Silverstone <dsilvers@digital-scurf.org>
Diffstat (limited to 'subplotlib')
-rw-r--r--subplotlib/src/scenario.rs20
-rw-r--r--subplotlib/src/step.rs20
2 files changed, 26 insertions, 14 deletions
diff --git a/subplotlib/src/scenario.rs b/subplotlib/src/scenario.rs
index a83e215..9bcc43d 100644
--- a/subplotlib/src/scenario.rs
+++ b/subplotlib/src/scenario.rs
@@ -159,6 +159,7 @@ where
/// This container allows the running of code within a given scenario context.
pub struct ScenarioContext {
title: String,
+ location: &'static str,
inner: Container![],
hooks: RefCell<Vec<Box<dyn ScenarioContextHookKind>>>,
}
@@ -212,9 +213,10 @@ impl Debug for ScenarioContext {
}
impl ScenarioContext {
- fn new(title: &str) -> Self {
+ fn new(title: &str, location: &'static str) -> Self {
Self {
title: title.to_string(),
+ location,
inner: <Container![]>::new(),
hooks: RefCell::new(Vec::new()),
}
@@ -303,12 +305,12 @@ impl ScenarioContext {
/// ```
/// # use subplotlib::prelude::*;
///
-/// let mut scenario = Scenario::new("example scenario");
+/// let mut scenario = Scenario::new("example scenario", "unknown");
///
/// let run_step = subplotlib::steplibrary::runcmd::run::Builder::default()
/// .argv0("true")
/// .args("")
-/// .build("when I run true".to_string());
+/// .build("when I run true".to_string(), "unknown");
/// scenario.add_step(run_step, None);
///
/// ```
@@ -319,9 +321,9 @@ pub struct Scenario {
impl Scenario {
/// Create a new scenario with the given title
- pub fn new(title: &str) -> Self {
+ pub fn new(title: &str, location: &'static str) -> Self {
Self {
- contexts: ScenarioContext::new(title),
+ contexts: ScenarioContext::new(title, location),
steps: Vec::new(),
}
}
@@ -372,7 +374,11 @@ impl Scenario {
// Firstly, we start all the contexts
let mut ret = Ok(());
let mut highest_start = None;
- println!("scenario: {}", self.contexts.title());
+ println!(
+ "{}: scenario: {}",
+ self.contexts.location,
+ self.contexts.title()
+ );
for (i, hook) in self.contexts.hooks.borrow().iter().enumerate() {
let res = hook.scenario_starts(&self.contexts);
if res.is_err() {
@@ -387,7 +393,7 @@ impl Scenario {
if ret.is_ok() {
let mut highest = None;
for (i, step) in self.steps.iter().map(|(step, _)| step).enumerate() {
- println!(" step: {}", step.step_text());
+ println!("{}: step: {}", step.location(), step.step_text());
let mut highest_prep = None;
for (i, prep) in self.contexts.hooks.borrow().iter().enumerate() {
let res = prep.step_starts(&self.contexts, step.step_text());
diff --git a/subplotlib/src/step.rs b/subplotlib/src/step.rs
index 12b4ddf..76b9193 100644
--- a/subplotlib/src/step.rs
+++ b/subplotlib/src/step.rs
@@ -25,11 +25,12 @@ type StepFunc = dyn Fn(&ScenarioContext, bool) -> StepResult;
/// # use subplotlib::prelude::*;
///
/// let step = ScenarioStep::new(
-/// "when everything works".to_string(), |ctx, ok| Ok(()), |scen| ()
+/// "when everything works".to_string(), |ctx, ok| Ok(()), |scen| (), "unknown"
/// );
/// ```
pub struct ScenarioStep {
step_text: String,
+ location: &'static str,
func: Box<StepFunc>,
reg: Box<dyn Fn(&Scenario)>,
}
@@ -40,13 +41,14 @@ impl ScenarioStep {
/// This is used to construct a scenario step from a function which
/// takes the scenario context container. This will generally be
/// called from the generated build method for the step.
- pub fn new<F, R>(step_text: String, func: F, reg: R) -> Self
+ pub fn new<F, R>(step_text: String, func: F, reg: R, location: &'static str) -> Self
where
F: Fn(&ScenarioContext, bool) -> StepResult + 'static,
R: Fn(&Scenario) + 'static,
{
Self {
step_text,
+ location,
func: Box::new(func),
reg: Box::new(reg),
}
@@ -55,13 +57,13 @@ impl ScenarioStep {
/// Attempt to render a message.
/// If something panics with a type other than a static string or
/// a formatted string then we won't be able to render it sadly.
- fn render_panic(name: &str, err: Box<dyn Any + Send>) -> String {
+ fn render_panic(location: &str, name: &str, err: Box<dyn Any + Send>) -> String {
if let Some(msg) = err.downcast_ref::<&str>() {
- format!("step {name} panic'd: {msg}")
+ format!("{location}: step {name} panic'd: {msg}")
} else if let Some(msg) = err.downcast_ref::<String>() {
- format!("step {name} panic'd: {msg}")
+ format!("{location}: step {name} panic'd: {msg}")
} else {
- format!("step {name} panic'd")
+ format!("{location}: step {name} panic'd")
}
}
@@ -73,7 +75,7 @@ impl ScenarioStep {
// subsequent step calls may not be sound. There's not a lot we can
// do to ensure things are good except try.
let func = AssertUnwindSafe(|| (*self.func)(context, defuse_poison));
- catch_unwind(func).map_err(|e| Self::render_panic(self.step_text(), e))?
+ catch_unwind(func).map_err(|e| Self::render_panic(self.location(), self.step_text(), e))?
}
/// Return the full text of this step
@@ -85,4 +87,8 @@ impl ScenarioStep {
pub(crate) fn register_contexts(&self, scenario: &Scenario) {
(*self.reg)(scenario);
}
+
+ pub(crate) fn location(&self) -> &'static str {
+ self.location
+ }
}