Skip to content

Commit a6c059d

Browse files
committed
test: Write unit tests for the env-based Config
1 parent c030b7d commit a6c059d

File tree

1 file changed

+93
-26
lines changed

1 file changed

+93
-26
lines changed

crates/core/src/config.rs

+93-26
Original file line numberDiff line numberDiff line change
@@ -85,35 +85,34 @@ impl Default for Config {
8585

8686
impl Config {
8787
pub fn from_env() -> Result<Self> {
88-
fn require_env_var(var_key: &'static str) -> Result<String> {
89-
std::env::var(var_key).map_err(|_| eyre!("The \"{}\" env var must be set or a configuration file must be specified", var_key))
90-
}
88+
Self::from_vars(|key| std::env::var(key).ok())
89+
}
90+
91+
fn from_vars<F>(get: F) -> Result<Self>
92+
where
93+
F: Fn(&'static str) -> Option<String> + 'static,
94+
{
95+
let require = |var_key: &'static str| {
96+
get(var_key).ok_or_else(|| eyre!("The \"{}\" env var must be set or a configuration file must be specified", var_key))
97+
};
9198

9299
Ok(Self {
93-
network: Network::from_str(
94-
&std::env::var("NETWORK").unwrap_or_default(),
95-
)
96-
.unwrap_or(Network::MAINNET),
97-
eth_execution_rpc: require_env_var("ETH_EXECUTION_RPC")?,
98-
starknet_rpc: require_env_var("STARKNET_RPC")?,
99-
data_dir: PathBuf::from(
100-
std::env::var("DATA_DIR").unwrap_or_default(),
101-
),
102-
poll_secs: u64::from_str(
103-
&std::env::var("POLL_SECS").unwrap_or_default(),
104-
)
105-
.unwrap_or(DEFAULT_POLL_SECS),
106-
rpc_addr: if let Ok(addr) = std::env::var("RPC_ADDR") {
107-
SocketAddr::from_str(&addr)
108-
.context("Invalid value for `RPC_ADDR`")?
109-
} else {
110-
rpc_addr()
100+
network: Network::from_str(&get("NETWORK").unwrap_or_default())
101+
.unwrap_or(Network::MAINNET),
102+
eth_execution_rpc: require("ETH_EXECUTION_RPC")?,
103+
starknet_rpc: require("STARKNET_RPC")?,
104+
data_dir: PathBuf::from(get("DATA_DIR").unwrap_or_default()),
105+
poll_secs: u64::from_str(&get("POLL_SECS").unwrap_or_default())
106+
.unwrap_or(DEFAULT_POLL_SECS),
107+
rpc_addr: match get("RPC_ADDR") {
108+
Some(addr) => SocketAddr::from_str(&addr)
109+
.context("Invalid value for `RPC_ADDR`")?,
110+
None => rpc_addr(),
111111
},
112-
fee_token_addr: if let Ok(addr) = std::env::var("FEE_TOKEN_ADDR") {
113-
FieldElement::from_hex_be(&addr)
114-
.context("Invalid value for `FEE_TOKEN_ADDR`")?
115-
} else {
116-
fee_token_addr()
112+
fee_token_addr: match get("FEE_TOKEN_ADDR") {
113+
Some(addr) => FieldElement::from_hex_be(&addr)
114+
.context("Invalid value for `FEE_TOKEN_ADDR`")?,
115+
None => fee_token_addr(),
117116
},
118117
})
119118
}
@@ -214,3 +213,71 @@ impl Config {
214213
.expect("incorrect helios client config")
215214
}
216215
}
216+
217+
#[cfg(test)]
218+
mod tests {
219+
use std::collections::HashMap;
220+
221+
use super::*;
222+
223+
fn case(vars: &[(&'static str, &'static str)]) -> Result<Config> {
224+
let vars: HashMap<&str, &str> = HashMap::from_iter(vars.to_vec());
225+
Config::from_vars(move |s| vars.get(s).map(|s| s.to_string()))
226+
}
227+
228+
static MIN_CONFIG_VARS: &[(&'static str, &'static str)] =
229+
&[("ETH_EXECUTION_RPC", "url"), ("STARKNET_RPC", "url")];
230+
231+
#[test]
232+
fn test_min_config_requirements() {
233+
assert!(case(&[("ETH_EXECUTION_RPC", "url"),]).is_err());
234+
assert!(case(&[("STARKNET_RPC", "url"),]).is_err());
235+
236+
assert!(case(&MIN_CONFIG_VARS).is_ok());
237+
}
238+
239+
#[test]
240+
fn test_unspecified_network_is_mainnet() {
241+
let config = case(&MIN_CONFIG_VARS).unwrap();
242+
assert_eq!(config.network, Network::MAINNET);
243+
}
244+
245+
#[test]
246+
fn test_rpc_address_is_validated() {
247+
let result = case(&[
248+
("ETH_EXECUTION_RPC", "url"),
249+
("STARKNET_RPC", "url"),
250+
("RPC_ADDR", "invalid_value"),
251+
]);
252+
assert!(result.is_err());
253+
254+
let result = case(&[
255+
("ETH_EXECUTION_RPC", "url"),
256+
("STARKNET_RPC", "url"),
257+
("RPC_ADDR", "127.0.0.1:3333"),
258+
]);
259+
assert!(result.is_ok());
260+
assert_eq!(
261+
SocketAddr::from_str("127.0.0.1:3333").unwrap(),
262+
result.unwrap().rpc_addr
263+
);
264+
}
265+
266+
#[test]
267+
fn test_fee_token_addr_is_validated() {
268+
let result = case(&[
269+
("ETH_EXECUTION_RPC", "url"),
270+
("STARKNET_RPC", "url"),
271+
("FEE_TOKEN_ADDR", "invalid_value"),
272+
]);
273+
assert!(result.is_err());
274+
275+
let result = case(&[
276+
("ETH_EXECUTION_RPC", "url"),
277+
("STARKNET_RPC", "url"),
278+
("FEE_TOKEN_ADDR", "1"),
279+
]);
280+
assert!(result.is_ok());
281+
assert_eq!(FieldElement::ONE, result.unwrap().fee_token_addr);
282+
}
283+
}

0 commit comments

Comments
 (0)