use pina::ProgramError;
use pina::parse_instruction;
#[pina::discriminator(crate = ::pina)]
#[derive(Debug, PartialEq)]
pub enum TestInstruction {
Initialize = 0,
Update = 1,
Close = 2,
}
const PROGRAM_ID: pina::Address = pina::address!("11111111111111111111111111111111");
#[test]
fn parse_instruction_valid_discriminator() {
let data = [0u8]; let result: TestInstruction = parse_instruction(&PROGRAM_ID, &PROGRAM_ID, &data)
.unwrap_or_else(|e| panic!("expected valid parse: {e:?}"));
assert_eq!(result, TestInstruction::Initialize);
}
#[test]
fn parse_instruction_all_variants() {
for (byte, expected) in [
(0u8, TestInstruction::Initialize),
(1u8, TestInstruction::Update),
(2u8, TestInstruction::Close),
] {
let data = [byte];
let result: TestInstruction = parse_instruction(&PROGRAM_ID, &PROGRAM_ID, &data)
.unwrap_or_else(|e| panic!("expected valid parse for variant {byte}: {e:?}"));
assert_eq!(result, expected);
}
}
#[test]
fn parse_instruction_wrong_program_id() {
let data = [0u8];
let wrong_id = pina::address!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
let err = parse_instruction::<TestInstruction>(&PROGRAM_ID, &wrong_id, &data).unwrap_err();
assert_eq!(err, ProgramError::IncorrectProgramId);
}
#[test]
fn parse_instruction_empty_data() {
let data: &[u8] = &[];
let err = parse_instruction::<TestInstruction>(&PROGRAM_ID, &PROGRAM_ID, data).unwrap_err();
assert_eq!(err, ProgramError::InvalidInstructionData);
}
#[test]
fn parse_instruction_invalid_discriminator_remapped() {
let data = [99u8];
let err = parse_instruction::<TestInstruction>(&PROGRAM_ID, &PROGRAM_ID, &data).unwrap_err();
assert_eq!(err, ProgramError::InvalidInstructionData);
}
#[test]
fn parse_instruction_extra_data_is_ok() {
let data = [1u8, 0xFF, 0xFF, 0xFF];
let result: TestInstruction = parse_instruction(&PROGRAM_ID, &PROGRAM_ID, &data)
.unwrap_or_else(|e| panic!("expected valid parse: {e:?}"));
assert_eq!(result, TestInstruction::Update);
}
#[test]
fn assert_true_returns_ok() {
let result = pina::assert(true, ProgramError::InvalidArgument, "should not fail");
assert!(result.is_ok());
}
#[test]
fn assert_false_returns_err() {
let result = pina::assert(false, ProgramError::InvalidArgument, "expected failure");
assert_eq!(result.unwrap_err(), ProgramError::InvalidArgument);
}
#[test]
fn assert_custom_error_type() {
let result = pina::assert(
false,
pina::PinaProgramError::DataTooShort,
"data too short",
);
let err = result.unwrap_err();
match err {
ProgramError::Custom(code) => assert_eq!(code, 0xFFFF_FFFA),
other => panic!("expected Custom error, got: {other:?}"),
}
}