use litesvm::LiteSVM;
use solana_program::pubkey::Pubkey;
pub struct LiteSVMBuilder {
svm: LiteSVM,
programs: Vec<(Pubkey, Vec<u8>)>,
}
impl LiteSVMBuilder {
pub fn new() -> Self {
Self {
svm: LiteSVM::new(),
programs: Vec::new(),
}
}
pub fn deploy_program(mut self, program_id: Pubkey, program_bytes: &[u8]) -> Self {
self.programs.push((program_id, program_bytes.to_vec()));
self
}
pub fn build(mut self) -> LiteSVM {
for (program_id, program_bytes) in self.programs {
self.svm
.add_program(program_id, &program_bytes)
.expect("Failed to add program");
}
self.svm
}
pub fn build_with_program(program_id: Pubkey, program_bytes: &[u8]) -> LiteSVM {
Self::new()
.deploy_program(program_id, program_bytes)
.build()
}
pub fn build_with_programs(programs: &[(Pubkey, &[u8])]) -> LiteSVM {
let mut builder = Self::new();
for (program_id, program_bytes) in programs {
builder = builder.deploy_program(*program_id, program_bytes);
}
builder.build()
}
}
impl Default for LiteSVMBuilder {
fn default() -> Self {
Self::new()
}
}
pub trait ProgramTestExt {
fn deploy_program(&mut self, program_id: Pubkey, program_bytes: &[u8]);
}
impl ProgramTestExt for LiteSVM {
fn deploy_program(&mut self, program_id: Pubkey, program_bytes: &[u8]) {
self.add_program(program_id, program_bytes)
.expect("Failed to deploy program");
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_builder_new() {
let builder = LiteSVMBuilder::new();
let _svm = builder.build();
}
#[test]
fn test_builder_default() {
let builder = LiteSVMBuilder::default();
let _svm = builder.build();
}
#[test]
fn test_builder_deploy_single_program() {
let program_id = Pubkey::new_unique();
let program_bytes = vec![1, 2, 3, 4];
let mut builder = LiteSVMBuilder::new();
builder = builder.deploy_program(program_id, &program_bytes);
assert_eq!(builder.programs.len(), 1);
assert_eq!(builder.programs[0].0, program_id);
}
#[test]
fn test_builder_deploy_multiple_programs() {
let program_id1 = Pubkey::new_unique();
let program_id2 = Pubkey::new_unique();
let program_bytes = vec![1, 2, 3, 4];
let builder = LiteSVMBuilder::new()
.deploy_program(program_id1, &program_bytes)
.deploy_program(program_id2, &program_bytes);
assert_eq!(builder.programs.len(), 2);
}
#[test]
fn test_build_with_programs_empty_list() {
let programs: Vec<(Pubkey, &[u8])> = vec![];
let _svm = LiteSVMBuilder::build_with_programs(&programs);
}
#[test]
fn test_builder_chaining() {
let program_id1 = Pubkey::new_unique();
let program_id2 = Pubkey::new_unique();
let program_id3 = Pubkey::new_unique();
let program_bytes = vec![1, 2, 3, 4];
let builder = LiteSVMBuilder::new()
.deploy_program(program_id1, &program_bytes)
.deploy_program(program_id2, &program_bytes)
.deploy_program(program_id3, &program_bytes);
assert_eq!(builder.programs.len(), 3);
}
}