nushell/crates/nu-derive-value/src/tests.rs
Piepmatz ebe42241fe
Add #[nu_value(rename = "...")] as helper attribute on members for derive macros (#13761)
# Description

This PR allows the helper attribute `nu_value(rename = "...")` to be
used on struct fields and enum variants. This allows renaming keys and
variants just like [`#[serde(rename =
"name")]`](https://serde.rs/field-attrs.html#rename). This has no
singular variants for `IntoValue` or `FromValue`, both need to use the
same (but I think this shouldn't be an issue for now).

# User-Facing Changes

Users of the derive macros `IntoValue` and `FromValue` may now use
`#[nu_value(rename = "...")]` to rename single fields, but no already
existing code will break.
2024-09-04 11:27:21 +02:00

243 lines
6.1 KiB
Rust

// These tests only check that the derive macros throw the relevant errors.
// Functionality of the derived types is tested in nu_protocol::value::test_derive.
use crate::error::DeriveError;
use crate::from::derive_from_value;
use crate::into::derive_into_value;
use quote::quote;
#[test]
fn unsupported_unions() {
let input = quote! {
#[nu_value]
union SomeUnion {
f1: u32,
f2: f32,
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::UnsupportedUnions)),
"expected `DeriveError::UnsupportedUnions`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::UnsupportedUnions)),
"expected `DeriveError::UnsupportedUnions`, got {:?}",
into_res
);
}
#[test]
fn unsupported_enums() {
let input = quote! {
#[nu_value(rename_all = "SCREAMING_SNAKE_CASE")]
enum ComplexEnum {
Unit,
Unnamed(u32, f32),
Named {
u: u32,
f: f32,
}
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::UnsupportedEnums { .. })),
"expected `DeriveError::UnsupportedEnums`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::UnsupportedEnums { .. })),
"expected `DeriveError::UnsupportedEnums`, got {:?}",
into_res
);
}
#[test]
fn unexpected_attribute() {
let input = quote! {
#[nu_value(what)]
enum SimpleEnum {
A,
B,
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
into_res
);
}
#[test]
fn unexpected_attribute_on_struct_field() {
let input = quote! {
struct SimpleStruct {
#[nu_value(what)]
field_a: i32,
field_b: String,
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
into_res
);
}
#[test]
fn unexpected_attribute_on_enum_variant() {
let input = quote! {
enum SimpleEnum {
#[nu_value(what)]
A,
B,
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::UnexpectedAttribute { .. })),
"expected `DeriveError::UnexpectedAttribute`, got {:?}",
into_res
);
}
#[test]
fn invalid_attribute_position_in_tuple_struct() {
let input = quote! {
struct SimpleTupleStruct(
#[nu_value(what)]
i32,
String,
);
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(
from_res,
Err(DeriveError::InvalidAttributePosition { attribute_span: _ })
),
"expected `DeriveError::InvalidAttributePosition`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(
into_res,
Err(DeriveError::InvalidAttributePosition { attribute_span: _ })
),
"expected `DeriveError::InvalidAttributePosition`, got {:?}",
into_res
);
}
#[test]
fn invalid_attribute_value() {
let input = quote! {
#[nu_value(rename_all = "CrazY-CasE")]
enum SimpleEnum {
A,
B
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::InvalidAttributeValue { .. })),
"expected `DeriveError::InvalidAttributeValue`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::InvalidAttributeValue { .. })),
"expected `DeriveError::InvalidAttributeValue`, got {:?}",
into_res
);
}
#[test]
fn non_unique_struct_keys() {
let input = quote! {
struct DuplicateStruct {
#[nu_value(rename = "field")]
some_field: (),
field: (),
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::NonUniqueName { .. })),
"expected `DeriveError::NonUniqueName`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::NonUniqueName { .. })),
"expected `DeriveError::NonUniqueName`, got {:?}",
into_res
);
}
#[test]
fn non_unique_enum_variants() {
let input = quote! {
enum DuplicateEnum {
#[nu_value(rename = "variant")]
SomeVariant,
Variant
}
};
let from_res = derive_from_value(input.clone());
assert!(
matches!(from_res, Err(DeriveError::NonUniqueName { .. })),
"expected `DeriveError::NonUniqueName`, got {:?}",
from_res
);
let into_res = derive_into_value(input);
assert!(
matches!(into_res, Err(DeriveError::NonUniqueName { .. })),
"expected `DeriveError::NonUniqueName`, got {:?}",
into_res
);
}