use {
crate::process,
ferrotype::Ferrotype,
quote::quote,
};
#[test_log::test]
fn test_simple_cst_struct() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct SimpleCST {
span: Span,
token: NodeId<crate::Token>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
let output_str = output.to_string();
assert!(output_str.contains("impl SimpleCST"));
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_with_field_types() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct ComplexCST {
span: Span,
start_token: NodeId<crate::Token>,
children: Vec<NodeId>,
end_token: Option<NodeId<crate::Token>>,
trivia: Vec<crate::Trivia>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_with_multiple_node_types() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct MultiNodeCST {
span: Span,
expr: NodeId<crate::Expression, crate::Statement>,
mixed: NodeId<crate::Token, crate::Trivia, crate::Comment>,
optional_multi: Option<NodeId<crate::Type1, crate::Type2>>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_with_doc_comments() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct DocumentedCST {
span: Span,
open: NodeId<crate::Token>,
content: Vec<NodeId>,
close: NodeId<crate::Token>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_error_node() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST, error)]
pub struct CSTErrorNode {
message: String,
span: Span,
tokens: Vec<NodeId<crate::Token>>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST, error), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_with_semantic_tokens() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST, allow_semantic)]
pub struct SemanticCST {
span: Span,
token: NodeId<crate::SemanticToken>,
kind: Field<TokenKind>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST, allow_semantic), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_error_not_struct() {
let mut snapshot = Ferrotype::new();
snapshot.set_expect_errors(true);
let input = quote! {
#[laburnum_syntax(CST)]
pub enum NotAStruct {
Token(NodeId),
Trivia(NodeId),
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(_) => {
panic!("Expected error for non-struct item");
},
| Err(e) => {
snapshot.add_debug("Error", &e);
let error_message = e.to_string();
assert!(
error_message.contains("struct"),
"Error message should mention 'struct', got: {error_message}",
);
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_empty_struct() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct EmptyCST {
span: Span,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
snapshot.add_debug("Error", &e);
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_with_generics() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct GenericCST<T> {
span: Span,
data: NodeId<T>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
snapshot.add_debug("Error", &e);
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_complex_real_world_example() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
pub struct FunctionCST {
span: Span,
visibility_token: Option<NodeId<crate::Token>>,
fn_keyword: NodeId<crate::Token>,
name: NodeId<crate::Identifier>,
generic_params: Option<NodeId<crate::GenericParams>>,
lparen: NodeId<crate::Token>,
params: Vec<crate::Param>,
rparen: NodeId<crate::Token>,
return_type: Option<NodeId<crate::ReturnType>>,
body: NodeId<crate::Block>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
let output_str = output.to_string();
assert!(output_str.contains("impl FunctionCST"));
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_multiple_attributes() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[derive(Debug, Clone)]
#[laburnum_syntax(CST)]
pub struct MultiAttrCST {
span: Span,
token: NodeId<crate::Token>,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
let output_str = output.to_string();
assert!(output_str.contains("derive"));
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}
#[test_log::test]
fn test_cst_private_struct() {
let mut snapshot = Ferrotype::new();
let input = quote! {
#[laburnum_syntax(CST)]
struct PrivateCST {
span: Span,
field: NodeId,
}
};
snapshot.add_token_stream("Input", &input);
match process(quote!(CST), input) {
| Ok(output) => {
snapshot.add_token_stream("Output", &output);
},
| Err(e) => {
panic!("Unexpected error: {e:?}");
},
}
ferrotype::assert!(snapshot);
}