use syn::punctuated::Punctuated;
use crate::light_pdas::program::parsing::{
call_has_ctx_arg, extract_context_and_params, ExtractResult,
};
fn parse_args(code: &str) -> Punctuated<syn::Expr, syn::token::Comma> {
let call: syn::ExprCall = syn::parse_str(&format!("f({})", code)).unwrap();
call.args
}
#[test]
fn test_call_has_ctx_arg_direct() {
let args = parse_args("ctx");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_reference() {
let args = parse_args("&ctx");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_mut_reference() {
let args = parse_args("&mut ctx");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_clone() {
let args = parse_args("ctx.clone()");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_into() {
let args = parse_args("ctx.into()");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_other_name() {
let args = parse_args("context");
assert!(!call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_method_on_other() {
let args = parse_args("other.clone()");
assert!(!call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_multiple_args() {
let args = parse_args("foo, ctx.clone(), bar");
assert!(call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_empty() {
let args = parse_args("");
assert!(!call_has_ctx_arg(&args, "ctx"));
}
#[test]
fn test_call_has_ctx_arg_custom_name_context() {
let args = parse_args("context");
assert!(call_has_ctx_arg(&args, "context"));
}
#[test]
fn test_call_has_ctx_arg_custom_name_anchor_ctx() {
let args = parse_args("anchor_ctx");
assert!(call_has_ctx_arg(&args, "anchor_ctx"));
}
#[test]
fn test_call_has_ctx_arg_custom_name_reference() {
let args = parse_args("&my_context");
assert!(call_has_ctx_arg(&args, "my_context"));
}
#[test]
fn test_call_has_ctx_arg_custom_name_method_call() {
let args = parse_args("c.clone()");
assert!(call_has_ctx_arg(&args, "c"));
}
#[test]
fn test_call_has_ctx_arg_wrong_custom_name() {
let args = parse_args("ctx");
assert!(!call_has_ctx_arg(&args, "context"));
}
#[test]
fn test_extract_context_and_params_standard() {
let fn_item: syn::ItemFn = syn::parse_quote! {
pub fn handler(ctx: Context<MyAccounts>, params: Params) -> Result<()> {
Ok(())
}
};
match extract_context_and_params(&fn_item) {
ExtractResult::Success {
context_type,
params_ident,
ctx_ident,
} => {
assert_eq!(context_type, "MyAccounts");
assert_eq!(params_ident.to_string(), "params");
assert_eq!(ctx_ident.to_string(), "ctx");
}
_ => panic!("Expected ExtractResult::Success"),
}
}
#[test]
fn test_extract_context_and_params_custom_context_name() {
let fn_item: syn::ItemFn = syn::parse_quote! {
pub fn handler(context: Context<MyAccounts>, params: Params) -> Result<()> {
Ok(())
}
};
match extract_context_and_params(&fn_item) {
ExtractResult::Success {
context_type,
params_ident,
ctx_ident,
} => {
assert_eq!(context_type, "MyAccounts");
assert_eq!(params_ident.to_string(), "params");
assert_eq!(ctx_ident.to_string(), "context");
}
_ => panic!("Expected ExtractResult::Success"),
}
}
#[test]
fn test_extract_context_and_params_anchor_ctx_name() {
let fn_item: syn::ItemFn = syn::parse_quote! {
pub fn handler(anchor_ctx: Context<MyAccounts>, data: Data) -> Result<()> {
Ok(())
}
};
match extract_context_and_params(&fn_item) {
ExtractResult::Success {
context_type,
params_ident,
ctx_ident,
} => {
assert_eq!(context_type, "MyAccounts");
assert_eq!(params_ident.to_string(), "data");
assert_eq!(ctx_ident.to_string(), "anchor_ctx");
}
_ => panic!("Expected ExtractResult::Success"),
}
}
#[test]
fn test_extract_context_and_params_single_letter_name() {
let fn_item: syn::ItemFn = syn::parse_quote! {
pub fn handler(c: Context<MyAccounts>, p: Params) -> Result<()> {
Ok(())
}
};
match extract_context_and_params(&fn_item) {
ExtractResult::Success {
context_type,
params_ident,
ctx_ident,
} => {
assert_eq!(context_type, "MyAccounts");
assert_eq!(params_ident.to_string(), "p");
assert_eq!(ctx_ident.to_string(), "c");
}
_ => panic!("Expected ExtractResult::Success"),
}
}
#[test]
fn test_extract_context_and_params_multiple_args_detected() {
let fn_item: syn::ItemFn = syn::parse_quote! {
pub fn handler(ctx: Context<MyAccounts>, amount: u64, owner: Pubkey) -> Result<()> {
Ok(())
}
};
match extract_context_and_params(&fn_item) {
ExtractResult::MultipleParams {
context_type,
param_names,
} => {
assert_eq!(context_type, "MyAccounts");
assert!(param_names.contains(&"amount".to_string()));
assert!(param_names.contains(&"owner".to_string()));
}
_ => panic!("Expected ExtractResult::MultipleParams"),
}
}