Skip to content

Commit 9c7c742

Browse files
committed
improved test: making it maintainable
Signed-off-by: Aminu Oluwaseun Joshua <[email protected]>
1 parent 25b263a commit 9c7c742

File tree

1 file changed

+62
-51
lines changed

1 file changed

+62
-51
lines changed

crates/expressions/tests/validation_test.rs

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,39 @@ use spin_locked_app::Variable;
66
#[derive(Default)]
77
struct ResolverTester {
88
providers: Vec<Box<dyn Provider>>,
9+
variables: HashMap<String, Variable>,
910
}
1011

1112
impl ResolverTester {
1213
fn new() -> Self {
1314
Self::default()
1415
}
1516

16-
fn with_provider(mut self, provider: Box<dyn Provider>) -> Self {
17-
self.providers.push(provider);
17+
fn with_dynamic_provider(mut self) -> Self {
18+
self.providers.push(Box::new(DynamicProvider));
1819
self
1920
}
2021

21-
fn make_resolver(
22-
self,
23-
key: Option<&str>,
24-
default: Option<&str>,
25-
) -> anyhow::Result<ProviderResolver> {
26-
let mut provider_resolver = ProviderResolver::new(
27-
key.map(|k| {
28-
vec![(
29-
k.to_string(),
30-
Variable {
31-
description: None,
32-
default: default.map(ToString::to_string),
33-
secret: false,
34-
},
35-
)]
36-
})
37-
.unwrap_or_default(),
38-
)?;
22+
fn with_static_provider(mut self, key: &str, value: Option<&str>) -> Self {
23+
self.providers
24+
.push(Box::new(StaticProvider::with_variable(key, value)));
25+
self
26+
}
27+
28+
fn with_variable(mut self, (key, default): (&str, Option<&str>)) -> Self {
29+
self.variables.insert(
30+
key.to_string(),
31+
Variable {
32+
description: None,
33+
default: default.map(ToString::to_string),
34+
secret: false,
35+
},
36+
);
37+
self
38+
}
39+
40+
fn make_resolver(self) -> anyhow::Result<ProviderResolver> {
41+
let mut provider_resolver = ProviderResolver::new(self.variables)?;
3942

4043
for provider in self.providers {
4144
provider_resolver.add_provider(provider as _);
@@ -48,8 +51,8 @@ impl ResolverTester {
4851
#[tokio::test(flavor = "multi_thread")]
4952
async fn single_static_provider_with_no_variable_provided_is_valid() -> anyhow::Result<()> {
5053
let resolver = ResolverTester::new()
51-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
52-
.make_resolver(None, None)?;
54+
.with_static_provider("foo", Some("bar"))
55+
.make_resolver()?;
5356

5457
resolver.validate_variables().await?;
5558

@@ -59,8 +62,9 @@ async fn single_static_provider_with_no_variable_provided_is_valid() -> anyhow::
5962
#[tokio::test(flavor = "multi_thread")]
6063
async fn if_single_static_provider_has_variable_value_validation_succeeds() -> anyhow::Result<()> {
6164
let resolver = ResolverTester::new()
62-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
63-
.make_resolver(Some("foo"), None)?;
65+
.with_static_provider("foo", Some("bar"))
66+
.with_variable(("foo", None))
67+
.make_resolver()?;
6468

6569
resolver.validate_variables().await?;
6670

@@ -71,8 +75,9 @@ async fn if_single_static_provider_has_variable_value_validation_succeeds() -> a
7175
async fn if_there_is_a_single_static_provider_and_it_does_not_contain_a_required_variable_then_validation_fails(
7276
) -> anyhow::Result<()> {
7377
let resolver = ResolverTester::new()
74-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
75-
.make_resolver(Some("baz"), None)?;
78+
.with_static_provider("foo", Some("bar"))
79+
.with_variable(("bar", None))
80+
.make_resolver()?;
7681

7782
assert!(resolver.validate_variables().await.is_err());
7883

@@ -83,8 +88,9 @@ async fn if_there_is_a_single_static_provider_and_it_does_not_contain_a_required
8388
async fn if_there_is_a_dynamic_provider_then_validation_succeeds_even_if_a_static_provider_without_the_variable_is_in_play(
8489
) -> anyhow::Result<()> {
8590
let resolver = ResolverTester::new()
86-
.with_provider(Box::new(DynamicMockProvider))
87-
.make_resolver(Some("baz"), None)?;
91+
.with_dynamic_provider()
92+
.with_variable(("bar", None))
93+
.make_resolver()?;
8894

8995
resolver.validate_variables().await?;
9096

@@ -95,9 +101,10 @@ async fn if_there_is_a_dynamic_provider_then_validation_succeeds_even_if_a_stati
95101
async fn if_there_is_a_dynamic_provider_and_a_static_provider_then_validation_succeeds_even_if_a_static_provider_without_the_variable_is_in_play(
96102
) -> anyhow::Result<()> {
97103
let resolver = ResolverTester::new()
98-
.with_provider(Box::new(DynamicMockProvider))
99-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
100-
.make_resolver(Some("baz"), None)?;
104+
.with_dynamic_provider()
105+
.with_static_provider("foo", Some("bar"))
106+
.with_variable(("baz", None))
107+
.make_resolver()?;
101108

102109
resolver.validate_variables().await?;
103110

@@ -108,9 +115,10 @@ async fn if_there_is_a_dynamic_provider_and_a_static_provider_then_validation_su
108115
async fn if_there_is_a_dynamic_provider_and_a_static_provider_then_validation_succeeds_even_if_a_static_provider_with_the_variable_is_in_play(
109116
) -> anyhow::Result<()> {
110117
let resolver = ResolverTester::new()
111-
.with_provider(Box::new(DynamicMockProvider))
112-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
113-
.make_resolver(Some("baz"), Some("coo"))?;
118+
.with_dynamic_provider()
119+
.with_static_provider("foo", Some("bar"))
120+
.with_variable(("baz", Some("coo")))
121+
.make_resolver()?;
114122

115123
resolver.validate_variables().await?;
116124

@@ -120,9 +128,10 @@ async fn if_there_is_a_dynamic_provider_and_a_static_provider_then_validation_su
120128
#[tokio::test(flavor = "multi_thread")]
121129
async fn if_there_is_two_static_providers_where_one_has_data_is_valid() -> anyhow::Result<()> {
122130
let resolver = ResolverTester::new()
123-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
124-
.with_provider(Box::new(StaticMockProvider::with_variables("baz", "hay")))
125-
.make_resolver(Some("foo"), None)?;
131+
.with_static_provider("foo", Some("bar"))
132+
.with_static_provider("baz", Some("hay"))
133+
.with_variable(("foo", None))
134+
.make_resolver()?;
126135

127136
resolver.validate_variables().await?;
128137

@@ -133,9 +142,10 @@ async fn if_there_is_two_static_providers_where_one_has_data_is_valid() -> anyho
133142
async fn if_there_is_two_static_providers_where_first_provider_does_not_have_data_while_second_provider_does(
134143
) -> anyhow::Result<()> {
135144
let resolver = ResolverTester::new()
136-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
137-
.with_provider(Box::new(StaticMockProvider::with_variables("baz", "hay")))
138-
.make_resolver(Some("baz"), None)?;
145+
.with_static_provider("foo", Some("bar"))
146+
.with_static_provider("baz", Some("hay"))
147+
.with_variable(("baz", None))
148+
.make_resolver()?;
139149

140150
resolver.validate_variables().await?;
141151

@@ -145,30 +155,31 @@ async fn if_there_is_two_static_providers_where_first_provider_does_not_have_dat
145155
#[tokio::test(flavor = "multi_thread")]
146156
async fn if_there_is_two_static_providers_neither_having_data_is_invalid() -> anyhow::Result<()> {
147157
let resolver = ResolverTester::new()
148-
.with_provider(Box::new(StaticMockProvider::with_variables("foo", "bar")))
149-
.with_provider(Box::new(StaticMockProvider::with_variables("baz", "hay")))
150-
.make_resolver(Some("hello"), None)?;
158+
.with_static_provider("foo", Some("bar"))
159+
.with_static_provider("baz", Some("hay"))
160+
.with_variable(("hello", None))
161+
.make_resolver()?;
151162

152163
assert!(resolver.validate_variables().await.is_err());
153164

154165
Ok(())
155166
}
156167

157168
#[derive(Debug)]
158-
struct StaticMockProvider {
169+
struct StaticProvider {
159170
variables: HashMap<String, Option<String>>,
160171
}
161172

162-
impl StaticMockProvider {
163-
fn with_variables(key: &str, value: &str) -> Self {
173+
impl StaticProvider {
174+
fn with_variable(key: &str, value: Option<&str>) -> Self {
164175
Self {
165-
variables: HashMap::from([(key.into(), Some(value.into()))]),
176+
variables: HashMap::from([(key.into(), value.map(|v| v.into()))]),
166177
}
167178
}
168179
}
169180

170181
#[spin_world::async_trait]
171-
impl Provider for StaticMockProvider {
182+
impl Provider for StaticProvider {
172183
async fn get(&self, key: &Key) -> anyhow::Result<Option<String>> {
173184
Ok(self.variables.get(key.as_str()).cloned().flatten())
174185
}
@@ -179,12 +190,12 @@ impl Provider for StaticMockProvider {
179190
}
180191

181192
#[derive(Debug)]
182-
struct DynamicMockProvider;
193+
struct DynamicProvider;
183194

184195
#[spin_world::async_trait]
185-
impl Provider for DynamicMockProvider {
196+
impl Provider for DynamicProvider {
186197
async fn get(&self, _key: &Key) -> anyhow::Result<Option<String>> {
187-
Ok(None)
198+
panic!("validation should never call get for a dynamic provider")
188199
}
189200

190201
fn kind(&self) -> ProviderVariableKind {

0 commit comments

Comments
 (0)