diff --git a/Cargo.toml b/Cargo.toml index 65845c2..5e81ef7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,3 +33,5 @@ darling = "0.20" [dev-dependencies] miniconf = { version = "0.13", features = ["json-core"] } serde = "1.0" +rstest = "0.22" +serde-json-core = "0.5.1" diff --git a/tests/simple.rs b/tests/simple.rs index c20a264..4ca1d94 100644 --- a/tests/simple.rs +++ b/tests/simple.rs @@ -7,6 +7,7 @@ use miniconf::{ Traversal::{Access, TooLong}, Tree, TreeKey, }; +use rstest::*; use serde::{Deserialize, Serialize}; #[config] @@ -30,27 +31,39 @@ struct Config { sub_config: SubConfig, } -#[test] -fn keys() { - for (id, field) in ["skipped", "min", "max", "default", "description"] - .into_iter() - .enumerate() - { - assert_eq!( - SubConfig::traverse_by_key([field].into_keys(), |index, name, _len| { - assert_eq!((id, Some(field)), (index, name)); - Ok::<_, ()>(()) - }), - Ok(1) - ); - } +#[rstest] +#[case(0, ["skipped"])] +#[case(1, ["min"])] +#[case(2, ["max"])] +#[case(3, ["default"])] +#[case(4, ["description"])] +fn key(#[case] id: usize, #[case] field: [&str; N]) { + assert_eq!( + SubConfig::traverse_by_key(field.into_keys(), |index, name, _len| { + assert_eq!((id, Some(field[field.len() - 1])), (index, name)); + Ok::<_, ()>(()) + }), + Ok(1) + ); } -#[test] -fn sub_keys() { +#[rstest] +#[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( + #[case] fields: [&str; N], + #[case] expected: Result>, +) { assert_eq!( - SubConfig::traverse_by_key(["skipped", "value"].into_keys(), |_, _, _| Ok::<_, ()>(())), - Err(Traversal(TooLong(1))) + SubConfig::traverse_by_key(fields.into_keys(), |_, _, _| Ok::<_, ()>(())), + expected ); assert_eq!( SubConfig::traverse_by_key(["skipped"].into_keys(), |_, _, _| Ok::<_, ()>(())), @@ -68,39 +81,59 @@ fn sub_keys() { } } -#[test] -fn serialize() { - let mut buffer = [0u8; 32]; - let config = SubConfig { +#[fixture] +#[once] +fn sub_config() -> SubConfig { + SubConfig { skipped: 1, min: __SubConfigMin::new(2), max: __SubConfigMax::new(3), default: __SubConfigDefault::new(4), 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] -fn deserialize() { +#[rstest] +#[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>, +) { let mut config = SubConfig { skipped: 0, min: __SubConfigMin::new(0), @@ -109,34 +142,12 @@ fn deserialize() { description: __SubConfigDescription::new(0), }; - for input in [ - "/skipped", - "/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")))); - } + let res = config.set_json(path, b"10"); + assert_eq!(res, expected); } #[test] -fn subconfig() { +fn config_paths() { let control = vec![ "/sub_config/skipped".to_owned(), "/sub_config/min/value".to_owned(),