120 lines
3.0 KiB
Rust
120 lines
3.0 KiB
Rust
use kaptan_config::{
|
|
ConfigAggregate, ConfigSection, ConfigValue, ConfigViolation, FieldId, FieldWriteError,
|
|
ValidateFields, ValidationRule,
|
|
};
|
|
use kaptan_config_derive::ConfigValidate;
|
|
|
|
#[derive(ConfigValidate)]
|
|
struct LocalSection {
|
|
#[config(
|
|
id = 1,
|
|
key = "local.first",
|
|
unit = "count",
|
|
default = 2,
|
|
range(min = 1, max = 9)
|
|
)]
|
|
first: u32,
|
|
#[config(
|
|
id = 2,
|
|
key = "local.second",
|
|
unit = "count",
|
|
default = 4,
|
|
range(min = 1, max = 9)
|
|
)]
|
|
second: u32,
|
|
}
|
|
|
|
#[derive(ConfigValidate)]
|
|
#[config(post = Self::validate_order)]
|
|
struct OrderedSection {
|
|
#[config(
|
|
id = 3,
|
|
key = "ordered.minimum",
|
|
unit = "count",
|
|
default = 1,
|
|
range(min = 0, max = 9)
|
|
)]
|
|
minimum: u32,
|
|
#[config(
|
|
id = 4,
|
|
key = "ordered.maximum",
|
|
unit = "count",
|
|
default = 2,
|
|
range(min = 0, max = 9)
|
|
)]
|
|
maximum: u32,
|
|
}
|
|
|
|
impl OrderedSection {
|
|
fn validate_order(&self) -> Result<(), ConfigViolation> {
|
|
if self.minimum > self.maximum {
|
|
return Err(ConfigViolation::related(
|
|
FieldId::new(3),
|
|
FieldId::new(4),
|
|
ValidationRule::Inconsistent,
|
|
));
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[derive(ConfigValidate)]
|
|
struct Aggregate {
|
|
#[config(section)]
|
|
local: LocalSection,
|
|
#[config(section)]
|
|
ordered: OrderedSection,
|
|
}
|
|
|
|
#[test]
|
|
fn generated_section_owns_every_declared_scalar_path() {
|
|
let mut section = LocalSection::default_section().unwrap();
|
|
assert_eq!(LocalSection::FIELD_COUNT, 2);
|
|
assert_eq!(
|
|
section.field_value(FieldId::new(2)),
|
|
Some(ConfigValue::U32(4))
|
|
);
|
|
section
|
|
.set_field(FieldId::new(2), ConfigValue::U32(8))
|
|
.unwrap();
|
|
assert_eq!(
|
|
section.field_value(FieldId::new(2)),
|
|
Some(ConfigValue::U32(8))
|
|
);
|
|
assert_eq!(
|
|
section.set_field(FieldId::new(2), ConfigValue::U32(0)),
|
|
Err(FieldWriteError::Violation(ConfigViolation::field(
|
|
FieldId::new(2),
|
|
ValidationRule::BelowMinimum,
|
|
)))
|
|
);
|
|
assert_eq!(
|
|
section.field_value(FieldId::new(2)),
|
|
Some(ConfigValue::U32(8))
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn aggregate_routes_writes_and_defers_declared_post_validation() {
|
|
let mut aggregate = Aggregate::default_aggregate().unwrap();
|
|
assert_eq!(Aggregate::FIELD_COUNT, 4);
|
|
assert_eq!(
|
|
aggregate.field_value(FieldId::new(2)),
|
|
Some(ConfigValue::U32(4))
|
|
);
|
|
aggregate
|
|
.set_field(FieldId::new(3), ConfigValue::U32(3))
|
|
.unwrap();
|
|
assert!(matches!(
|
|
aggregate.validate_fields(),
|
|
Err(issue)
|
|
if issue.primary() == Some(FieldId::new(3))
|
|
&& issue.related_field() == Some(FieldId::new(4))
|
|
&& issue.rule() == ValidationRule::Inconsistent
|
|
));
|
|
aggregate
|
|
.set_field(FieldId::new(4), ConfigValue::U32(3))
|
|
.unwrap();
|
|
aggregate.validate_fields().unwrap();
|
|
}
|