virtual_io/
vio_fake_builder.rs1use crate::{
2 helpers::{append_stdout, VioFakeMessage},
3 vio_fake::VioFake,
4};
5
6#[derive(PartialEq, Eq, Debug, Default)]
45pub struct VioFakeBuilder {
46 messages: Vec<VioFakeMessage>,
47 environment_variables: Vec<(String, String)>,
48}
49
50impl VioFakeBuilder {
51 #[must_use]
52 pub const fn new() -> Self {
53 Self {
54 messages: Vec::new(),
55 environment_variables: Vec::new(),
56 }
57 }
58
59 pub fn expect_stdout<S: Into<String>>(&mut self, message: S) -> &mut Self {
60 append_stdout(&mut self.messages, message.into());
61 self
62 }
63
64 pub fn provide_stdin<S: Into<String>>(&mut self, message: S) -> &mut Self {
65 self.messages.push(VioFakeMessage::StdIn(message.into()));
66 self
67 }
68
69 pub fn set_environment_var<S: Into<String>>(&mut self, name: S, value: S) -> &mut Self {
70 let name = name.into();
71 let value = value.into();
72 for var in &mut self.environment_variables {
73 if var.0 == name {
74 var.1 = value;
75 return self;
76 }
77 }
78 self.environment_variables.push((name, value));
79 self
80 }
81
82 #[must_use]
83 pub fn build(&self) -> VioFake {
84 VioFake::new(self.messages.clone(), self.environment_variables.clone())
85 }
86}
87
88#[cfg(test)]
89mod test {
90 use super::*;
91
92 #[test]
93 fn vio_fake_builder_accepts_input() {
94 assert_eq!(
95 VioFakeBuilder::new()
96 .provide_stdin("John")
97 .build()
98 .expected_messages,
99 vec![VioFakeMessage::StdIn("John".to_string())]
100 );
101 }
102
103 #[test]
104 fn vio_fake_builder_inputs_do_not_collapse() {
105 assert_eq!(
106 VioFakeBuilder::new()
107 .provide_stdin("John")
108 .provide_stdin("Smith")
109 .build()
110 .expected_messages,
111 vec![
112 VioFakeMessage::StdIn("John".to_string()),
113 VioFakeMessage::StdIn("Smith".to_string())
114 ]
115 );
116 }
117
118 #[test]
119 fn vio_fake_builder_prints() {
120 assert_eq!(
121 VioFakeBuilder::new()
122 .expect_stdout("John")
123 .build()
124 .expected_messages,
125 vec![VioFakeMessage::StdOut("John".to_string())]
126 );
127 }
128
129 #[test]
130 fn vio_fake_builder_consecutive_print_statements_collapse_into_single_message() {
131 assert_eq!(
132 VioFakeBuilder::new()
133 .expect_stdout("I'm")
134 .expect_stdout(" ")
135 .expect_stdout("John")
136 .expect_stdout(' ')
137 .expect_stdout("Smith\n")
138 .expect_stdout("> What's your name? ")
139 .provide_stdin("Jane Doe")
140 .expect_stdout("Your name is Jane Doe.\n")
141 .expect_stdout("Nice to meet you Jane Doe.\n")
142 .build()
143 .expected_messages,
144 vec![
145 VioFakeMessage::StdOut("I'm John Smith\n> What's your name? ".to_string()),
146 VioFakeMessage::StdIn("Jane Doe".to_string()),
147 VioFakeMessage::StdOut(
148 "Your name is Jane Doe.\nNice to meet you Jane Doe.\n".to_string()
149 )
150 ]
151 );
152 }
153
154 #[test]
155 fn vio_fake_builder_environment_variables() {
156 assert_eq!(
157 VioFakeBuilder::new()
158 .set_environment_var("HELLO", "WORLD")
159 .set_environment_var("MY_MOOD", "GOOD")
160 .set_environment_var("MY_MOOD", "SO_SO")
162 .build()
163 .environment_variables,
164 vec![
165 ("HELLO".to_string(), "WORLD".to_string()),
166 ("MY_MOOD".to_string(), "SO_SO".to_string()),
167 ]
168 );
169 }
170}