|
|
|
@ -302,18 +302,32 @@ mod tests {
|
|
|
|
|
const TRUE_BYTE: u8 = 0xc3;
|
|
|
|
|
const NEVER_USED_BYTE: u8 = 0xc1;
|
|
|
|
|
|
|
|
|
|
// fixstr of 6 bytes with str "header"
|
|
|
|
|
const HEADER_FIELD_BYTES: &[u8] = &[0xa6, b'h', b'e', b'a', b'd', b'e', b'r'];
|
|
|
|
|
|
|
|
|
|
// fixmap of 2 objects with
|
|
|
|
|
// 1. key fixstr "key" and value fixstr "value"
|
|
|
|
|
// 1. key fixstr "num" and value fixint 123
|
|
|
|
|
const HEADER_BYTES: &[u8] = &[
|
|
|
|
|
0x82, // valid map with 2 pair
|
|
|
|
|
0xa3, b'k', b'e', b'y', // key: "key"
|
|
|
|
|
0xa5, b'v', b'a', b'l', b'u', b'e', // value: "value"
|
|
|
|
|
0xa3, b'n', b'u', b'm', // key: "num"
|
|
|
|
|
0x7b, // value: 123
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// fixstr of 2 bytes with str "id"
|
|
|
|
|
const ID_FIELD_BYTES: &[u8] = &[0xa2, 0x69, 0x64];
|
|
|
|
|
const ID_FIELD_BYTES: &[u8] = &[0xa2, b'i', b'd'];
|
|
|
|
|
|
|
|
|
|
// fixstr of 9 bytes with str "origin_id"
|
|
|
|
|
const ORIGIN_ID_FIELD_BYTES: &[u8] =
|
|
|
|
|
&[0xa9, 0x6f, 0x72, 0x69, 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x64];
|
|
|
|
|
|
|
|
|
|
// fixstr of 7 bytes with str "payload"
|
|
|
|
|
const PAYLOAD_FIELD_BYTES: &[u8] = &[0xa7, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64];
|
|
|
|
|
const PAYLOAD_FIELD_BYTES: &[u8] = &[0xa7, b'p', b'a', b'y', b'l', b'o', b'a', b'd'];
|
|
|
|
|
|
|
|
|
|
/// fixstr of 4 bytes with str "test"
|
|
|
|
|
const TEST_STR_BYTES: &[u8] = &[0xa4, 0x74, 0x65, 0x73, 0x74];
|
|
|
|
|
const TEST_STR_BYTES: &[u8] = &[0xa4, b't', b'e', b's', b't'];
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn untyped_response_should_support_converting_to_bytes() {
|
|
|
|
@ -416,6 +430,31 @@ mod tests {
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn untyped_response_should_support_parsing_full_request() {
|
|
|
|
|
let input = [
|
|
|
|
|
&[0x84],
|
|
|
|
|
HEADER_FIELD_BYTES,
|
|
|
|
|
HEADER_BYTES,
|
|
|
|
|
ID_FIELD_BYTES,
|
|
|
|
|
TEST_STR_BYTES,
|
|
|
|
|
ORIGIN_ID_FIELD_BYTES,
|
|
|
|
|
&[0xa2, b'o', b'g'],
|
|
|
|
|
PAYLOAD_FIELD_BYTES,
|
|
|
|
|
&[TRUE_BYTE],
|
|
|
|
|
]
|
|
|
|
|
.concat();
|
|
|
|
|
|
|
|
|
|
// Convert into typed so we can test
|
|
|
|
|
let untyped_response = UntypedResponse::from_slice(&input).unwrap();
|
|
|
|
|
let response: Response<bool> = untyped_response.to_typed_response().unwrap();
|
|
|
|
|
|
|
|
|
|
assert_eq!(response.header, header!("key" -> "value", "num" -> 123));
|
|
|
|
|
assert_eq!(response.id, "test");
|
|
|
|
|
assert_eq!(response.origin_id, "og");
|
|
|
|
|
assert!(response.payload);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn untyped_response_should_fail_to_parse_if_given_bytes_not_representing_a_response() {
|
|
|
|
|
// Empty byte slice
|
|
|
|
@ -436,6 +475,46 @@ mod tests {
|
|
|
|
|
Err(UntypedResponseParseError::WrongType)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Invalid header key
|
|
|
|
|
assert_eq!(
|
|
|
|
|
UntypedResponse::from_slice(
|
|
|
|
|
[
|
|
|
|
|
&[0x84],
|
|
|
|
|
&[0xa0], // header key would be defined here, set to empty str
|
|
|
|
|
HEADER_BYTES,
|
|
|
|
|
ID_FIELD_BYTES,
|
|
|
|
|
TEST_STR_BYTES,
|
|
|
|
|
ORIGIN_ID_FIELD_BYTES,
|
|
|
|
|
TEST_STR_BYTES,
|
|
|
|
|
PAYLOAD_FIELD_BYTES,
|
|
|
|
|
&[TRUE_BYTE],
|
|
|
|
|
]
|
|
|
|
|
.concat()
|
|
|
|
|
.as_slice()
|
|
|
|
|
),
|
|
|
|
|
Err(UntypedResponseParseError::InvalidHeaderKey)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Invalid header bytes
|
|
|
|
|
assert_eq!(
|
|
|
|
|
UntypedResponse::from_slice(
|
|
|
|
|
[
|
|
|
|
|
&[0x84],
|
|
|
|
|
HEADER_FIELD_BYTES,
|
|
|
|
|
&[0xa0], // header would be defined here, set to empty str
|
|
|
|
|
ID_FIELD_BYTES,
|
|
|
|
|
TEST_STR_BYTES,
|
|
|
|
|
ORIGIN_ID_FIELD_BYTES,
|
|
|
|
|
TEST_STR_BYTES,
|
|
|
|
|
PAYLOAD_FIELD_BYTES,
|
|
|
|
|
&[TRUE_BYTE],
|
|
|
|
|
]
|
|
|
|
|
.concat()
|
|
|
|
|
.as_slice()
|
|
|
|
|
),
|
|
|
|
|
Err(UntypedResponseParseError::InvalidHeader)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Missing fields (corrupt data)
|
|
|
|
|
assert_eq!(
|
|
|
|
|
UntypedResponse::from_slice(&[0x83]),
|
|
|
|
|