Files
Decodal/crates/decodal-derive/tests/derive.rs
T

151 lines
3.7 KiB
Rust

use decodal::{Data, DecodalDecode, DecodalSchema, EmptyLoader, Engine};
use decodal_derive::Decodal;
#[derive(Debug, PartialEq, Decodal)]
struct Service {
name: String,
#[decodal(gt = 443, default = 8443)]
port: i64,
#[decodal(default = true, rename = "feature.enable")]
feature_enabled: bool,
#[decodal(default)]
tags: Vec<String>,
}
#[derive(Debug, PartialEq, Decodal)]
struct Worker {
name: String,
#[decodal(default = true)]
enabled: bool,
}
#[derive(Debug, PartialEq, Decodal)]
struct Fleet {
workers: Vec<Worker>,
}
#[test]
fn derives_schema_and_decode() {
let mut engine = Engine::new(EmptyLoader);
engine
.bind_global("Service", Service::decodal_schema())
.unwrap();
let module = engine
.add_root_source(
"test",
"test",
r#"
Service & {
name = "api";
port = 9443;
feature.enable = false;
tags = ["web", "prod"];
}
"#,
)
.unwrap();
let value = engine.eval_module(module).unwrap();
let data = engine.materialize(&value).unwrap();
let service = Service::decodal_decode(&data).unwrap();
assert_eq!(
service,
Service {
name: "api".into(),
port: 9443,
feature_enabled: false,
tags: vec!["web".into(), "prod".into()],
}
);
}
#[test]
fn defaults_are_available_in_schema() {
let mut engine = Engine::new(EmptyLoader);
engine
.bind_global("Service", Service::decodal_schema())
.unwrap();
let module = engine
.add_root_source(
"test",
"test",
r#"
Service & {
name = "api";
}
"#,
)
.unwrap();
let value = engine.eval_module(module).unwrap();
let data = engine.materialize(&value).unwrap();
let service = Service::decodal_decode(&data).unwrap();
assert_eq!(service.port, 8443);
assert!(service.feature_enabled);
assert!(service.tags.is_empty());
}
#[test]
fn decode_reports_field_path() {
let data = Data::Object(vec![]);
let error = Service::decodal_decode(&data).unwrap_err();
assert_eq!(error.path, "name");
}
#[test]
fn vec_schema_rejects_invalid_element_before_decode() {
let mut engine = Engine::new(EmptyLoader);
engine
.bind_global("Service", Service::decodal_schema())
.unwrap();
let module = engine
.add_root_source(
"test",
"test",
r#"
Service & {
name = "api";
port = 9443;
tags = ["web", 1];
}
"#,
)
.unwrap();
let error = engine.eval_module(module).unwrap_err();
assert!(
error
.labels
.iter()
.any(|label| label.message.contains("array element [1]"))
);
}
#[test]
fn vec_schema_applies_nested_struct_defaults() {
let mut engine = Engine::new(EmptyLoader);
engine
.bind_global("Fleet", Fleet::decodal_schema())
.unwrap();
let module = engine
.add_root_source(
"test",
"test",
r#"
Fleet & {
workers = [{ name = "api"; }];
}
"#,
)
.unwrap();
let value = engine.eval_module(module).unwrap();
let data = engine.materialize(&value).unwrap();
let fleet = Fleet::decodal_decode(&data).unwrap();
assert_eq!(
fleet,
Fleet {
workers: vec![Worker {
name: "api".into(),
enabled: true,
}],
}
);
}