use rstest

This commit is contained in:
Max Känner 2024-08-16 20:59:05 +02:00
parent 0e63dc3c22
commit ea6c3a34b8
2 changed files with 81 additions and 68 deletions

View File

@ -33,3 +33,5 @@ darling = "0.20"
[dev-dependencies] [dev-dependencies]
miniconf = { version = "0.13", features = ["json-core"] } miniconf = { version = "0.13", features = ["json-core"] }
serde = "1.0" serde = "1.0"
rstest = "0.22"
serde-json-core = "0.5.1"

View File

@ -7,6 +7,7 @@ use miniconf::{
Traversal::{Access, TooLong}, Traversal::{Access, TooLong},
Tree, TreeKey, Tree, TreeKey,
}; };
use rstest::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[config] #[config]
@ -30,27 +31,39 @@ struct Config {
sub_config: SubConfig, sub_config: SubConfig,
} }
#[test] #[rstest]
fn keys() { #[case(0, ["skipped"])]
for (id, field) in ["skipped", "min", "max", "default", "description"] #[case(1, ["min"])]
.into_iter() #[case(2, ["max"])]
.enumerate() #[case(3, ["default"])]
{ #[case(4, ["description"])]
assert_eq!( fn key<const N: usize>(#[case] id: usize, #[case] field: [&str; N]) {
SubConfig::traverse_by_key([field].into_keys(), |index, name, _len| { assert_eq!(
assert_eq!((id, Some(field)), (index, name)); SubConfig::traverse_by_key(field.into_keys(), |index, name, _len| {
Ok::<_, ()>(()) assert_eq!((id, Some(field[field.len() - 1])), (index, name));
}), Ok::<_, ()>(())
Ok(1) }),
); Ok(1)
} );
} }
#[test] #[rstest]
fn sub_keys() { #[case(["skipped", "value"], Err(Traversal(TooLong(1))))]
#[case(["min", "value"], Ok(2))]
#[case(["max", "value"], Ok(2))]
#[case(["default", "value"], Ok(2))]
#[case(["description", "value"], Ok(2))]
#[case(["min", "min"], Ok(2))]
#[case(["max", "max"], Ok(2))]
#[case(["default", "default"], Ok(2))]
#[case(["description", "description"], Ok(2))]
fn sub_keys<const N: usize>(
#[case] fields: [&str; N],
#[case] expected: Result<usize, miniconf::Error<()>>,
) {
assert_eq!( assert_eq!(
SubConfig::traverse_by_key(["skipped", "value"].into_keys(), |_, _, _| Ok::<_, ()>(())), SubConfig::traverse_by_key(fields.into_keys(), |_, _, _| Ok::<_, ()>(())),
Err(Traversal(TooLong(1))) expected
); );
assert_eq!( assert_eq!(
SubConfig::traverse_by_key(["skipped"].into_keys(), |_, _, _| Ok::<_, ()>(())), SubConfig::traverse_by_key(["skipped"].into_keys(), |_, _, _| Ok::<_, ()>(())),
@ -68,39 +81,59 @@ fn sub_keys() {
} }
} }
#[test] #[fixture]
fn serialize() { #[once]
let mut buffer = [0u8; 32]; fn sub_config() -> SubConfig {
let config = SubConfig { SubConfig {
skipped: 1, skipped: 1,
min: __SubConfigMin::new(2), min: __SubConfigMin::new(2),
max: __SubConfigMax::new(3), max: __SubConfigMax::new(3),
default: __SubConfigDefault::new(4), default: __SubConfigDefault::new(4),
description: __SubConfigDescription::new(5), description: __SubConfigDescription::new(5),
};
for (input, output) in [
("/skipped", "1"),
("/min", "2"),
("/min/value", "2"),
("/min/min", "-2147483648"),
("/max", "3"),
("/max/value", "3"),
("/max/max", "2147483647"),
("/default", "4"),
("/default/value", "4"),
("/default/default", "0"),
("/description", "5"),
("/description/value", "5"),
("/description/description", "\"This is a description\""),
] {
let len = config.get_json(input, &mut buffer).unwrap();
assert_eq!(from_utf8(&buffer[..len]), Ok(output));
} }
} }
#[test] #[rstest]
fn deserialize() { #[case("/skipped", "1")]
#[case("/min", "2")]
#[case("/min/value", "2")]
#[case("/min/min", "-2147483648")]
#[case("/max", "3")]
#[case("/max/value", "3")]
#[case("/max/max", "2147483647")]
#[case("/default", "4")]
#[case("/default/value", "4")]
#[case("/default/default", "0")]
#[case("/description", "5")]
#[case("/description/value", "5")]
#[case("/description/description", "\"This is a description\"")]
fn serialize(sub_config: &SubConfig, #[case] path: &str, #[case] expected: &str) {
let mut buffer = [0u8; 32];
let len = sub_config.get_json(path, &mut buffer).unwrap();
assert_eq!(from_utf8(&buffer[..len]), Ok(expected));
}
#[rstest]
#[case("/skipped", Ok(2))]
#[case("/min", Ok(2))]
#[case("/min/value", Ok(2))]
#[case("/max", Ok(2))]
#[case("/max/value", Ok(2))]
#[case("/default", Ok(2))]
#[case("/default/value", Ok(2))]
#[case("/description", Ok(2))]
#[case("/description/value", Ok(2))]
#[case("/min/min", Err(Traversal(Access(1, "Cannot write limits"))))]
#[case("/max/max", Err(Traversal(Access(1, "Cannot write limits"))))]
#[case("/default/default", Err(Traversal(Access(1, "Cannot write limits"))))]
#[case(
"/description/description",
Err(Traversal(Access(1, "Cannot write limits")))
)]
fn deserialize(
#[case] path: &str,
#[case] expected: Result<usize, miniconf::Error<serde_json_core::de::Error>>,
) {
let mut config = SubConfig { let mut config = SubConfig {
skipped: 0, skipped: 0,
min: __SubConfigMin::new(0), min: __SubConfigMin::new(0),
@ -109,34 +142,12 @@ fn deserialize() {
description: __SubConfigDescription::new(0), description: __SubConfigDescription::new(0),
}; };
for input in [ let res = config.set_json(path, b"10");
"/skipped", assert_eq!(res, expected);
"/min",
"/min/value",
"/max",
"/max/value",
"/default",
"/default/value",
"/description",
"/description/value",
] {
let res = config.set_json(input, b"10");
assert_eq!(res, Ok(2));
}
for input in [
"/min/min",
"/max/max",
"/default/default",
"/description/description",
] {
let res = config.set_json(input, b"10");
assert_eq!(res, Err(Traversal(Access(1, "Cannot write limits"))));
}
} }
#[test] #[test]
fn subconfig() { fn config_paths() {
let control = vec![ let control = vec![
"/sub_config/skipped".to_owned(), "/sub_config/skipped".to_owned(),
"/sub_config/min/value".to_owned(), "/sub_config/min/value".to_owned(),