Skip to content

Commit 679ec01

Browse files
committed
better functora-cfg tests wip
1 parent 95e4965 commit 679ec01

File tree

1 file changed

+165
-114
lines changed

1 file changed

+165
-114
lines changed
Lines changed: 165 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,132 @@
1-
use std::collections::HashMap;
2-
1+
use clap::{Args, Parser, Subcommand};
2+
use functora_cfg::*;
33
use serde::{Deserialize, Serialize};
44
use serial_test::serial;
5+
use std::collections::HashMap;
6+
use std::fmt::Debug;
57
use temp_env::with_vars;
68

7-
fn new_cfg(cli: &Cli) -> Cfg {
8-
let def = Cli {
9-
cfg: None,
10-
host: Some("127.0.0.1".into()),
11-
port: Some(8080),
12-
debug: Some(false),
13-
nest_val: Some(CfgNest {
14-
name: "foo".into(),
15-
value: 42,
16-
}),
17-
many_val: HashMap::new(),
18-
tags: None,
19-
};
20-
functora_cfg::Cfg {
21-
default: &def,
22-
file_path: |cli: &Cli| cli.cfg.as_deref(),
23-
env_prefix: "FUNCTORA",
24-
command_line: cli,
25-
}
26-
.eval()
27-
.unwrap()
28-
}
29-
30-
#[derive(Debug, Serialize, Deserialize, PartialEq)]
9+
#[derive(
10+
Eq, PartialEq, Debug, Clone, Serialize, Deserialize,
11+
)]
3112
struct Cfg {
3213
host: String,
3314
port: u16,
34-
debug: bool,
35-
nest_val: Option<CfgNest>,
36-
many_val: HashMap<usize, CfgNest>,
37-
tags: Option<Vec<String>>,
15+
logs: bool,
16+
main_account: Account,
17+
sub_accounts: HashMap<String, Account>,
18+
}
19+
20+
impl Cfg {
21+
pub fn new(
22+
cli: &Cli<IdClap<HashMap<String, Account>>>,
23+
) -> Self {
24+
functora_cfg::Cfg {
25+
default: &Cli::def(),
26+
file_path: |cli: &Cli<
27+
IdClap<HashMap<String, Account>>,
28+
>| cli.toml.as_deref(),
29+
env_prefix: "FUNCTORA",
30+
command_line: cli,
31+
}
32+
.eval()
33+
.unwrap()
34+
}
3835
}
3936

40-
#[derive(Debug, Serialize, Deserialize, PartialEq)]
41-
struct CfgNest {
42-
name: String,
43-
value: i32,
37+
#[derive(
38+
Eq,
39+
PartialEq,
40+
Ord,
41+
PartialOrd,
42+
Debug,
43+
Clone,
44+
Serialize,
45+
Deserialize,
46+
Args,
47+
)]
48+
struct Account {
49+
#[arg(long)]
50+
alias: String,
51+
#[arg(long)]
52+
balance: i32,
53+
#[arg(long)]
54+
tags: Option<Vec<String>>,
4455
}
4556

46-
#[derive(Debug, Serialize)]
47-
struct Cli {
48-
cfg: Option<String>,
57+
#[derive(
58+
Eq,
59+
PartialEq,
60+
Debug,
61+
Clone,
62+
Serialize,
63+
Deserialize,
64+
Parser,
65+
)]
66+
#[command(version, about, long_about = None)]
67+
struct Cli<T>
68+
where
69+
T: Eq
70+
+ PartialEq
71+
+ Debug
72+
+ Clone
73+
+ Serialize
74+
+ Subcommand,
75+
{
76+
#[arg(long)]
77+
toml: Option<String>,
78+
#[arg(long)]
4979
host: Option<String>,
80+
#[arg(long)]
5081
port: Option<u16>,
51-
debug: Option<bool>,
52-
nest_val: Option<CfgNest>,
53-
many_val: HashMap<usize, CfgNest>,
54-
tags: Option<Vec<String>>,
82+
#[arg(long)]
83+
logs: Option<bool>,
84+
#[command(flatten)]
85+
main_account: Option<Account>,
86+
#[command(subcommand)]
87+
sub_accounts: T,
88+
}
89+
90+
impl Cli<IdClap<HashMap<String, Account>>> {
91+
pub fn def() -> Self {
92+
Cli {
93+
toml: None,
94+
host: Some("127.0.0.1".into()),
95+
port: Some(8080),
96+
logs: Some(false),
97+
main_account: Some(Account {
98+
alias: "foo".into(),
99+
balance: 42,
100+
tags: None,
101+
}),
102+
sub_accounts: IdClap(HashMap::new()),
103+
}
104+
}
55105
}
56106

57107
#[test]
58108
#[serial]
59109
fn defaults_only() {
60-
let def = Cfg {
61-
host: "127.0.0.1".into(),
62-
port: 8080,
63-
debug: false,
64-
nest_val: Some(CfgNest {
65-
name: "foo".into(),
66-
value: 42,
67-
}),
68-
many_val: HashMap::new(),
69-
tags: None,
70-
};
71-
let cli = Cli {
72-
cfg: None,
110+
let lhs = Cfg::new(&Cli {
111+
toml: None,
73112
host: None,
74113
port: None,
75-
debug: None,
76-
nest_val: None,
77-
many_val: HashMap::new(),
78-
tags: None,
114+
logs: None,
115+
main_account: None,
116+
sub_accounts: IdClap(HashMap::new()),
117+
});
118+
let rhs = Cfg {
119+
host: "127.0.0.1".into(),
120+
port: 8080,
121+
logs: false,
122+
main_account: Account {
123+
alias: "foo".into(),
124+
balance: 42,
125+
tags: None,
126+
},
127+
sub_accounts: HashMap::new(),
79128
};
80-
let cfg: Cfg = new_cfg(&cli);
81-
assert_eq!(cfg, def);
129+
assert_eq!(lhs, rhs);
82130
}
83131

84132
#[test]
@@ -88,35 +136,34 @@ fn with_file_override() {
88136
let file = r#"
89137
host = "192.168.1.100"
90138
port = 9090
91-
debug = true
139+
logs = true
92140
tags = ["a", "b"]
93141
94-
[many_val.1]
95-
name = "hello"
96-
value = 123
142+
[sub_accounts.alice]
143+
alias = "hello"
144+
balance = 123
97145
"#;
98146
std::fs::write(&path, file).unwrap();
99147
let cli = Cli {
100-
cfg: Some(path.to_string_lossy().into_owned()),
148+
toml: Some(path.to_string_lossy().into_owned()),
101149
host: None,
102150
port: None,
103-
debug: None,
104-
nest_val: None,
105-
many_val: HashMap::new(),
106-
tags: None,
151+
logs: None,
152+
main_account: None,
153+
sub_accounts: IdClap(HashMap::new()),
107154
};
108-
let cfg: Cfg = new_cfg(&cli);
155+
let cfg: Cfg = Cfg::new(&cli);
109156
assert_eq!(cfg.host, "192.168.1.100");
110157
assert_eq!(cfg.port, 9090);
111-
assert_eq!(cfg.debug, true);
112-
assert_eq!(cfg.tags.unwrap(), vec!["a", "b"]);
158+
assert_eq!(cfg.logs, true);
113159
assert_eq!(
114-
cfg.many_val,
160+
cfg.sub_accounts,
115161
HashMap::from([(
116-
1,
117-
CfgNest {
118-
name: "hello".into(),
119-
value: 123
162+
"alice".into(),
163+
Account {
164+
alias: "hello".into(),
165+
balance: 123,
166+
tags: None,
120167
}
121168
)])
122169
);
@@ -126,42 +173,49 @@ fn with_file_override() {
126173
#[serial]
127174
fn env_override() {
128175
let cli = Cli {
129-
cfg: None,
176+
toml: None,
130177
host: None,
131178
port: None,
132-
debug: None,
133-
nest_val: None,
134-
many_val: HashMap::new(),
135-
tags: None,
179+
logs: None,
180+
main_account: None,
181+
sub_accounts: IdClap(HashMap::new()),
136182
};
137183
with_vars(
138184
vec![
139185
("FUNCTORA__HOST", Some("10.0.0.1")),
140186
("FUNCTORA__PORT", Some("7070")),
141-
("FUNCTORA__DEBUG", Some("true")),
142-
("FUNCTORA__NEST_VAL__NAME", Some("bar")),
143-
("FUNCTORA__MANY_VAL__0__NAME", Some("buz")),
144-
("FUNCTORA__MANY_VAL__0__VALUE", Some("1")),
187+
("FUNCTORA__LOGS", Some("true")),
188+
("FUNCTORA__MAIN_ACCOUNT__ALIAS", Some("bar")),
189+
(
190+
"FUNCTORA__SUB_ACCOUNTS__BOB__ALIAS",
191+
Some("buz"),
192+
),
193+
(
194+
"FUNCTORA__SUB_ACCOUNTS__BOB__BALANCE",
195+
Some("1"),
196+
),
145197
],
146198
|| {
147-
let cfg: Cfg = new_cfg(&cli);
199+
let cfg: Cfg = Cfg::new(&cli);
148200
assert_eq!(cfg.host, "10.0.0.1");
149201
assert_eq!(cfg.port, 7070);
150-
assert_eq!(cfg.debug, true);
202+
assert_eq!(cfg.logs, true);
151203
assert_eq!(
152-
cfg.nest_val,
153-
Some(CfgNest {
154-
name: "bar".into(),
155-
value: 42
156-
})
204+
cfg.main_account,
205+
Account {
206+
alias: "bar".into(),
207+
balance: 42,
208+
tags: None,
209+
}
157210
);
158211
assert_eq!(
159-
cfg.many_val,
212+
cfg.sub_accounts,
160213
HashMap::from([(
161-
0,
162-
CfgNest {
163-
name: "buz".into(),
164-
value: 1
214+
"bob".into(),
215+
Account {
216+
alias: "buz".into(),
217+
balance: 1,
218+
tags: None,
165219
}
166220
)])
167221
);
@@ -173,34 +227,31 @@ fn env_override() {
173227
#[serial]
174228
fn cli_override() {
175229
let cli = Cli {
176-
cfg: None,
230+
toml: None,
177231
host: Some("cli.host".into()),
178232
port: Some(6060),
179-
debug: Some(true),
180-
nest_val: None,
181-
many_val: HashMap::new(),
182-
tags: Some(vec!["cli1".into(), "cli2".into()]),
233+
logs: Some(true),
234+
main_account: None,
235+
sub_accounts: IdClap(HashMap::new()),
183236
};
184-
let cfg: Cfg = new_cfg(&cli);
237+
let cfg: Cfg = Cfg::new(&cli);
185238
assert_eq!(cfg.host, "cli.host");
186239
assert_eq!(cfg.port, 6060);
187-
assert_eq!(cfg.debug, true);
188-
assert_eq!(cfg.tags.unwrap(), vec!["cli1", "cli2"]);
240+
assert_eq!(cfg.logs, true);
189241
}
190242

191243
#[test]
192244
#[serial]
193245
fn nested_struct() {
194246
let cli = Cli {
195-
cfg: None,
247+
toml: None,
196248
host: None,
197249
port: None,
198-
debug: None,
199-
nest_val: None,
200-
many_val: HashMap::new(),
201-
tags: None,
250+
logs: None,
251+
main_account: None,
252+
sub_accounts: IdClap(HashMap::new()),
202253
};
203-
let cfg: Cfg = new_cfg(&cli);
204-
assert_eq!(cfg.nest_val.as_ref().unwrap().name, "foo");
205-
assert_eq!(cfg.nest_val.as_ref().unwrap().value, 42);
254+
let cfg: Cfg = Cfg::new(&cli);
255+
assert_eq!(cfg.main_account.alias, "foo");
256+
assert_eq!(cfg.main_account.balance, 42);
206257
}

0 commit comments

Comments
 (0)