blob: f08f4775b36c07adffbec1670d7a958b144f1d66 [file] [log] [blame]
use crate::cbor::value::Value;
use kmr_common::{cbor_type_error, AsCborValue, CborError};
use kmr_derive::AsCborValue;
#[derive(Debug, Clone, PartialEq, Eq, AsCborValue)]
struct Timestamp {
milliseconds: i64,
}
#[derive(Debug, Clone, PartialEq, Eq, AsCborValue)]
struct NamedFields {
challenge: i64,
timestamp: Timestamp,
mac: Vec<u8>,
}
#[test]
fn test_cbor_value_cddl() {
assert_eq!(<NamedFields>::cddl_typename().unwrap(), "NamedFields");
assert_eq!(
<NamedFields>::cddl_schema().unwrap(),
r#"[
challenge: int,
timestamp: Timestamp,
mac: bstr,
]"#
);
}
#[test]
fn test_cbor_value_roundtrip() {
let obj = NamedFields {
challenge: 42,
timestamp: Timestamp { milliseconds: 10_000_000 },
mac: vec![1, 2, 3, 4],
};
let obj_val = obj.clone().to_cbor_value().unwrap();
let recovered_obj = <NamedFields>::from_cbor_value(obj_val).unwrap();
assert_eq!(obj, recovered_obj);
}
#[test]
fn test_cbor_parse_fail() {
let tests = vec![
(Value::Map(vec![]), "expected arr"),
(Value::Integer(0.into()), "expected arr"),
(Value::Array(vec![]), "expected arr len 3"),
(
Value::Array(vec![
Value::Integer(0.into()),
Value::Integer(0.into()),
Value::Integer(0.into()),
Value::Integer(0.into()),
]),
"expected arr len 3",
),
(
Value::Array(vec![
Value::Integer(0.into()),
Value::Array(vec![Value::Integer(0.into())]),
Value::Integer(0.into()),
]),
"expected bstr",
),
(
Value::Array(vec![
Value::Integer(0.into()),
Value::Array(vec![Value::Integer(0.into()), Value::Integer(0.into())]),
Value::Bytes(vec![1, 2, 3]),
]),
"expected arr len 1",
),
];
for (val, wanterr) in tests {
let result = <NamedFields>::from_cbor_value(val);
expect_err(result, wanterr);
}
}
#[derive(Debug, Clone, PartialEq, Eq, AsCborValue)]
struct UnnamedFields(i64, Timestamp);
#[test]
fn test_unnamed_cbor_value_cddl() {
assert_eq!(<UnnamedFields>::cddl_typename().unwrap(), "UnnamedFields");
assert_eq!(
<UnnamedFields>::cddl_schema().unwrap(),
r#"[
int,
Timestamp,
]"#
);
}
#[test]
fn test_unnamed_cbor_value_roundtrip() {
let obj = UnnamedFields(42, Timestamp { milliseconds: 10_000_000 });
let obj_val = obj.clone().to_cbor_value().unwrap();
let recovered_obj = <UnnamedFields>::from_cbor_value(obj_val).unwrap();
assert_eq!(obj, recovered_obj);
}
#[test]
fn test_unnamed_cbor_parse_fail() {
let tests = vec![
(Value::Map(vec![]), "expected arr"),
(Value::Integer(0.into()), "expected arr"),
(Value::Array(vec![]), "expected arr len 2"),
(
Value::Array(vec![
Value::Integer(0.into()),
Value::Integer(0.into()),
Value::Integer(0.into()),
]),
"expected arr len 2",
),
(
Value::Array(vec![
Value::Bytes(vec![1, 2, 3]),
Value::Array(vec![Value::Integer(0.into())]),
]),
"expected i64",
),
(
Value::Array(vec![
Value::Integer(0.into()),
Value::Array(vec![Value::Integer(0.into()), Value::Integer(0.into())]),
]),
"expected arr len 1",
),
];
for (val, wanterr) in tests {
let result = <UnnamedFields>::from_cbor_value(val);
expect_err(result, wanterr);
}
}
/// Check for an expected error.
#[cfg(test)]
pub fn expect_err<T, E: core::fmt::Debug>(result: Result<T, E>, err_msg: &str) {
assert!(result.is_err(), "unexpected success; wanted error containing '{}'", err_msg);
let err = result.err();
assert!(
format!("{:?}", err).contains(err_msg),
"unexpected error {:?}, doesn't contain '{}'",
err,
err_msg
);
}