pub fn unit_test_rs(address: &str, program_address: &str, project_name: &str) -> String {
let template = r#"use mollusk_svm::result::{Check, ProgramResult};
use mollusk_svm::{program, Mollusk};
use solana_sdk::account::Account;
use solana_sdk::instruction::{AccountMeta, Instruction};
use solana_sdk::native_token::LAMPORTS_PER_SOL;
use solana_sdk::pubkey;
use solana_sdk::pubkey::Pubkey;
extern crate alloc;
use alloc::vec;
use {project_name}::instructions::Initialize;
use {project_name}::states::{to_bytes, MyState};
use solana_sdk::rent::Rent;
use solana_sdk::sysvar::Sysvar;
pub const PROGRAM: Pubkey = pubkey!("{program_address}");
pub const RENT: Pubkey = pubkey!("SysvarRent111111111111111111111111111111111");
pub const PAYER: Pubkey = pubkey!("{address}");
pub fn mollusk() -> Mollusk {
let mollusk = Mollusk::new(&PROGRAM, "target/deploy/{project_name}");
mollusk
}
pub fn get_rent_data() -> Vec<u8> {
let rent = Rent::default();
unsafe {
core::slice::from_raw_parts(&rent as *const Rent as *const u8, Rent::size_of()).to_vec()
}
}
#[test]
fn test_initialize_mystate() {
let mollusk = mollusk();
//system program and system account
let (system_program, system_account) = program::keyed_account_for_system_program();
// Create the PDA
let (mystate_pda, bump) =
Pubkey::find_program_address(&[MyState::SEED.as_bytes(), &PAYER.to_bytes()], &PROGRAM);
//Initialize the accounts
let payer_account = Account::new(1 * LAMPORTS_PER_SOL, 0, &system_program);
let mystate_account = Account::new(0, 0, &system_program);
let min_balance = mollusk.sysvars.rent.minimum_balance(Rent::size_of());
let mut rent_account = Account::new(min_balance, Rent::size_of(), &RENT);
rent_account.data = get_rent_data();
//Push the accounts in to the instruction_accounts vec!
let ix_accounts = vec![
AccountMeta::new(PAYER, true),
AccountMeta::new(mystate_pda, false),
AccountMeta::new_readonly(RENT, false),
AccountMeta::new_readonly(system_program, false),
];
// Create the instruction data
let ix_data = Initialize {
owner: *PAYER.as_array(),
bump,
};
// Ix discriminator = 0
let mut ser_ix_data = vec![0];
// Serialize the instruction data
ser_ix_data.extend_from_slice(unsafe { to_bytes(&ix_data) });
// Create instruction
let instruction = Instruction::new_with_bytes(PROGRAM, &ser_ix_data, ix_accounts);
// Create tx_accounts vec
let tx_accounts = &vec![
(PAYER, payer_account.clone()),
(mystate_pda, mystate_account.clone()),
(RENT, rent_account.clone()),
(system_program, system_account.clone()),
];
let init_res =
mollusk.process_and_validate_instruction(&instruction, tx_accounts, &[Check::success()]);
assert!(init_res.program_result == ProgramResult::Success);
}
"#;
template
.replace("{address}", address)
.replace("{program_address}", program_address)
.replace("{project_name}", project_name)
}