mrot_test_utils/
lib.rs

1//! Library with helper functions and constructs used in the mrot test code.
2
3mod error;
4pub mod argument;
5pub mod common_steps;
6
7pub use error::Error;
8use cucumber::{parser, runner, writer, Cucumber, World as _, WriterExt};
9use futures::FutureExt as _;
10use tracing::info;
11use tracing_subscriber::{
12    filter,
13    fmt::format,
14    layer::{Layer, SubscriberExt as _},
15};
16use std::{io, path::Path};
17use libmrot::{Storage, MealRecord};
18use chrono::NaiveDate;
19
20/// Result type alias with mrot-test-util's Error.
21pub type Result<T> = std::result::Result<T, Error>;
22
23/// World for cucumber tests
24#[derive(Debug, Default, cucumber::World)]
25#[world(init = Self::default)]
26pub struct World {
27    pub storage: Option<Storage>,
28    pub two_timer_parse_result: Option<String>,
29    pub parse_result: Option<libmrot::Result<Vec<NaiveDate>>>,
30    pub result_vec_mealrecord: Option<libmrot::Result<Vec<MealRecord>>>,
31    pub result_option_mealrecord: Option<libmrot::Result<Option<MealRecord>>>,
32    pub result_mealrecord: Option<libmrot::Result<MealRecord>>,
33}
34
35/// Clean-up procedure after each scenario
36fn cleanup(world: Option<&mut World>) {
37    if let Some(_w) = world {
38        info!("Cleaning up the World");
39    }
40}
41
42/// Normal World
43pub fn normal_world<I: AsRef<Path>>() -> Cucumber<
44    World,
45    parser::Basic,
46    I,
47    runner::Basic<World>,
48    writer::Summarize<writer::Normalize<World, writer::Basic>>,
49> {
50    World::cucumber()
51        .after(|_feature, _rule, _scenario, _event, world| async { cleanup(world) }.boxed_local())
52}
53
54/// World where Scenarios are run in series
55pub fn serial_world<I: AsRef<Path>>() -> Cucumber<
56    World,
57    parser::Basic,
58    I,
59    runner::Basic<World>,
60    writer::Summarize<writer::Normalize<World, writer::Basic>>,
61> {
62    World::cucumber()
63        .max_concurrent_scenarios(1)
64        .after(|_feature, _rule, _scenario, _event, world| async { cleanup(world) }.boxed_local())
65}
66
67/// World where Scenarios are run in series and traces for debugging tests are output
68pub fn debug_world<I: AsRef<Path>>() -> Cucumber<
69    World,
70    parser::Basic,
71    I,
72    runner::Basic<World>,
73    writer::AssertNormalized<writer::Summarize<writer::Basic>>,
74> {
75    World::cucumber()
76        .max_concurrent_scenarios(1)
77        .with_writer(
78            writer::Basic::raw(io::stdout(), writer::Coloring::Never, 0)
79                .summarized()
80                .assert_normalized(),
81        )
82        .configure_and_init_tracing(
83            format::DefaultFields::new(),
84            format::Format::default(),
85            |layer| tracing_subscriber::registry().with(filter::LevelFilter::TRACE.and_then(layer)),
86        )
87        .after(|_feature, _rule, _scenario, _event, world| async { cleanup(world) }.boxed_local())
88}
89
90/// World where Scenarios are run in series and traces for debugging tests are output. Cleanup
91/// procedure is not run after the scenario.
92pub fn debug_world_no_cleanup<I: AsRef<Path>>() -> Cucumber<
93    World,
94    parser::Basic,
95    I,
96    runner::Basic<World>,
97    writer::AssertNormalized<writer::Summarize<writer::Basic>>,
98> {
99    World::cucumber()
100        .max_concurrent_scenarios(1)
101        .with_writer(
102            writer::Basic::raw(io::stdout(), writer::Coloring::Never, 0)
103                .summarized()
104                .assert_normalized(),
105        )
106        .configure_and_init_tracing(
107            format::DefaultFields::new(),
108            format::Format::default(),
109            |layer| tracing_subscriber::registry().with(filter::LevelFilter::INFO.and_then(layer)),
110        )
111}