summaryrefslogtreecommitdiff
path: root/src/tests/mod.rs
blob: 58cd2b001b394145d5bf3fb88ae28f4ec3a73b55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
use crate::Configuration;
use std::collections::HashSet;

mod parsing;

fn check_configs_equal(
	cfg1: &Configuration,
	cfg2: &Configuration,
) -> Result<(), Box<dyn std::error::Error>> {
	fn check_configs_equal_at(
		cfg1: &Configuration,
		cfg2: &Configuration,
		prefix: &str,
	) -> Result<(), Box<dyn std::error::Error>> {
		let (keys1, keys2): (HashSet<&str>, HashSet<&str>) =
			if let Some(k) = prefix.strip_suffix('.') {
				(cfg1.subkeys(k).collect(), cfg2.subkeys(k).collect())
			} else {
				(cfg1.keys().collect(), cfg2.keys().collect())
			};
		for key in keys1.difference(&keys2) {
			return Err(format!(
				"Key {prefix}{key} appears at {}, but not in other configuration",
				cfg1.location(&format!("{prefix}{key}")).unwrap()
			)
			.into());
		}
		for key in keys2.difference(&keys1) {
			return Err(format!(
				"Key {prefix}{key} appears at {}, but not in other configuration",
				cfg2.location(&format!("{prefix}{key}")).unwrap()
			)
			.into());
		}
		for key in &keys1 {
			let full_key = format!("{prefix}{key}");
			let val1 = cfg1.get(&full_key);
			let val2 = cfg2.get(&full_key);
			if val1 != val2 {
				return Err(format!(
					"Mismatch between values for key {full_key}
    defined as {val1:?} at {},
but defined as {val2:?} at {}",
					cfg1.location(&full_key)
						.map_or("<nowhere>".into(), |x| format!("{x}")),
					cfg2.location(&full_key)
						.map_or("<nowhere>".into(), |x| format!("{x}")),
				)
				.into());
			}
			check_configs_equal_at(cfg1, cfg2, &format!("{full_key}."))?;
		}
		Ok(())
	}
	check_configs_equal_at(cfg1, cfg2, "")
}