enterprise/syn-serde/tests/test_item.rs
2020-02-17 06:09:45 -06:00

740 lines
16 KiB
Rust

use syn::*;
#[test]
fn test_unit() {
let raw = "struct Unit;";
let json = r#"
{
"struct": {
"ident": "Unit",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let ser: syn_serde::Item = serde_json::from_str(json).unwrap();
let ser = Item::from(&ser);
assert_eq!(ser, actual);
}
#[test]
fn test_struct() {
let raw = "
#[derive(Debug, Clone)]
pub struct Item {
pub ident: Ident,
pub attrs: Vec<Attribute>
}
";
let json = r#"
{
"struct": {
"attrs": [
{
"style": "outer",
"path": {
"segments": [
{
"ident": "derive"
}
]
},
"tokens": [
{
"group": {
"delimiter": "parenthesis",
"stream": [
{
"ident": "Debug"
},
{
"punct": {
"op": ",",
"spacing": "alone"
}
},
{
"ident": "Clone"
}
]
}
}
]
}
],
"vis": "pub",
"ident": "Item",
"fields": {
"named": [
{
"vis": "pub",
"ident": "ident",
"colon_token": true,
"ty": {
"path": {
"segments": [
{
"ident": "Ident"
}
]
}
}
},
{
"vis": "pub",
"ident": "attrs",
"colon_token": true,
"ty": {
"path": {
"segments": [
{
"ident": "Vec",
"arguments": {
"angle_bracketed": {
"args": [
{
"type": {
"path": {
"segments": [
{
"ident": "Attribute"
}
]
}
}
}
]
}
}
}
]
}
}
}
]
}
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_union() {
let raw = "
union MaybeUninit<T> {
uninit: (),
value: T
}
";
let json = r#"
{
"union": {
"ident": "MaybeUninit",
"generics": {
"params": [
{
"type": {
"ident": "T"
}
}
]
},
"fields": [
{
"ident": "uninit",
"colon_token": true,
"ty": {
"tuple": {
"elems": []
}
}
},
{
"ident": "value",
"colon_token": true,
"ty": {
"path": {
"segments": [
{
"ident": "T"
}
]
}
}
}
]
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_enum() {
let raw = r#"
/// See the std::result module documentation for details.
#[must_use]
pub enum Result<T, E> {
Ok(T),
Err(E),
Surprise = 0isize,
// Smuggling data into a proc_macro_derive,
// in the style of https://github.com/dtolnay/proc-macro-hack
ProcMacroHack = (0, "data").0
}
"#;
let json = r#"
{
"enum": {
"attrs": [
{
"style": "outer",
"path": {
"segments": [
{
"ident": "doc"
}
]
},
"tokens": [
{
"punct": {
"op": "=",
"spacing": "alone"
}
},
{
"lit": "\" See the std::result module documentation for details.\""
}
]
},
{
"style": "outer",
"path": {
"segments": [
{
"ident": "must_use"
}
]
}
}
],
"vis": "pub",
"ident": "Result",
"generics": {
"params": [
{
"type": {
"ident": "T"
}
},
{
"type": {
"ident": "E"
}
}
]
},
"variants": [
{
"ident": "Ok",
"fields": {
"unnamed": [
{
"ty": {
"path": {
"segments": [
{
"ident": "T"
}
]
}
}
}
]
}
},
{
"ident": "Err",
"fields": {
"unnamed": [
{
"ty": {
"path": {
"segments": [
{
"ident": "E"
}
]
}
}
}
]
}
},
{
"ident": "Surprise",
"fields": "unit",
"discriminant": {
"lit": {
"int": "0isize"
}
}
},
{
"ident": "ProcMacroHack",
"fields": "unit",
"discriminant": {
"field": {
"base": {
"tuple": {
"elems": [
{
"lit": {
"int": "0"
}
},
{
"lit": {
"str": "\"data\""
}
}
]
}
},
"index": 0
}
}
}
]
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_attr_with_path() {
let raw = r#"
#[::attr_args::identity
fn main() { assert_eq!(foo(), "Hello, world!"); }]
struct Dummy;
"#;
let json = r#"
{
"struct": {
"attrs": [
{
"style": "outer",
"path": {
"leading_colon": true,
"segments": [
{
"ident": "attr_args"
},
{
"ident": "identity"
}
]
},
"tokens": [
{
"ident": "fn"
},
{
"ident": "main"
},
{
"group": {
"delimiter": "parenthesis",
"stream": []
}
},
{
"group": {
"delimiter": "brace",
"stream": [
{
"ident": "assert_eq"
},
{
"punct": {
"op": "!",
"spacing": "alone"
}
},
{
"group": {
"delimiter": "parenthesis",
"stream": [
{
"ident": "foo"
},
{
"group": {
"delimiter": "parenthesis",
"stream": []
}
},
{
"punct": {
"op": ",",
"spacing": "alone"
}
},
{
"lit": "\"Hello, world!\""
}
]
}
},
{
"punct": {
"op": ";",
"spacing": "alone"
}
}
]
}
}
]
}
],
"ident": "Dummy",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_attr_with_non_mod_style_path() {
let raw = r#"
#[inert <T>]
struct S;
"#;
let json = r#"
{
"struct": {
"attrs": [
{
"style": "outer",
"path": {
"segments": [
{
"ident": "inert"
}
]
},
"tokens": [
{
"punct": {
"op": "<",
"spacing": "alone"
}
},
{
"ident": "T"
},
{
"punct": {
"op": ">",
"spacing": "alone"
}
}
]
}
],
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_attr_with_mod_style_path_with_self() {
let raw = r#"
#[foo::self]
struct S;
"#;
let json = r#"
{
"struct": {
"attrs": [
{
"style": "outer",
"path": {
"segments": [
{
"ident": "foo"
},
{
"ident": "self"
}
]
}
}
],
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_pub_restricted() {
// Taken from tests/rust/src/test/ui/resolve/auxiliary/privacy-struct-ctor.rs
let raw = r#"
pub(in m) struct Z(pub(in m::n) u8);
"#;
let json = r#"
{
"struct": {
"vis": {
"restricted": {
"in_token": true,
"path": {
"segments": [
{
"ident": "m"
}
]
}
}
},
"ident": "Z",
"fields": {
"unnamed": [
{
"vis": {
"restricted": {
"in_token": true,
"path": {
"segments": [
{
"ident": "m"
},
{
"ident": "n"
}
]
}
}
},
"ty": {
"path": {
"segments": [
{
"ident": "u8"
}
]
}
}
}
]
}
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_vis_crate() {
let raw = r#"
crate struct S;
"#;
let json = r#"
{
"struct": {
"vis": "crate",
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_pub_restricted_crate() {
let raw = r#"
pub(crate) struct S;
"#;
let json = r#"
{
"struct": {
"vis": {
"restricted": {
"path": {
"segments": [
{
"ident": "crate"
}
]
}
}
},
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_pub_restricted_super() {
let raw = r#"
pub(super) struct S;
"#;
let json = r#"
{
"struct": {
"vis": {
"restricted": {
"path": {
"segments": [
{
"ident": "super"
}
]
}
}
},
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_pub_restricted_in_super() {
let raw = r#"
pub(in super) struct S;
"#;
let json = r#"
{
"struct": {
"vis": {
"restricted": {
"in_token": true,
"path": {
"segments": [
{
"ident": "super"
}
]
}
}
},
"ident": "S",
"fields": "unit"
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}
#[test]
fn test_ambiguous_crate() {
// The field type is `(crate::X)` not `crate (::X)`.
let raw = "struct S(crate::X);";
let json = r#"
{
"struct": {
"ident": "S",
"fields": {
"unnamed": [
{
"ty": {
"path": {
"segments": [
{
"ident": "crate"
},
{
"ident": "X"
}
]
}
}
}
]
}
}
}
"#;
let actual = syn::parse_str(raw).unwrap();
let json: syn_serde::Item = serde_json::from_str(json).unwrap();
let json = Item::from(&json);
assert_eq!(json, actual);
}