Skip to main content

lexicon_spec/
behavior.rs

1use serde::{Deserialize, Serialize};
2
3use crate::version::SchemaVersion;
4
5/// A BDD-style behavior scenario for readable intent documentation.
6///
7/// Behavior scenarios complement contracts by providing narrative
8/// descriptions of expected behavior, useful for acceptance testing
9/// and communicating intent to stakeholders.
10///
11/// Stored at `specs/behavior/<id>.toml`.
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct BehaviorScenario {
14    pub schema_version: SchemaVersion,
15    /// Unique identifier for this scenario.
16    pub id: String,
17    pub title: String,
18    /// Optional contract this scenario relates to.
19    #[serde(default)]
20    pub contract_id: Option<String>,
21    /// Preconditions (Given).
22    #[serde(default)]
23    pub given: Vec<String>,
24    /// Actions (When).
25    #[serde(default)]
26    pub when: Vec<String>,
27    /// Expected outcomes (Then).
28    #[serde(default)]
29    pub then: Vec<String>,
30    /// Tags for categorization.
31    #[serde(default)]
32    pub tags: Vec<String>,
33}
34
35#[cfg(test)]
36mod tests {
37    use super::*;
38
39    #[test]
40    fn test_behavior_scenario_roundtrip() {
41        let scenario = BehaviorScenario {
42            schema_version: SchemaVersion::CURRENT,
43            id: "store-retrieval".to_string(),
44            title: "Stored values can be retrieved".to_string(),
45            contract_id: Some("key-value-store".to_string()),
46            given: vec!["an empty store".to_string()],
47            when: vec!["a value is stored with key \"foo\"".to_string()],
48            then: vec!["getting key \"foo\" returns the stored value".to_string()],
49            tags: vec!["basic".to_string(), "happy-path".to_string()],
50        };
51        let toml_str = toml::to_string_pretty(&scenario).unwrap();
52        let parsed: BehaviorScenario = toml::from_str(&toml_str).unwrap();
53        assert_eq!(parsed.id, "store-retrieval");
54        assert_eq!(parsed.given.len(), 1);
55    }
56}