use anyhow::Error;
use fehler::throws;
use pretty_assertions::assert_str_eq;
use std::fs;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use trident_client::___private::Commander;
use trident_idl_spec::Idl;
use trident_template::TridentTemplates;
#[throws]
#[tokio::test]
async fn test_types_generation() {
let templates = setup_templates()?;
verify_types(&templates).await?;
}
#[throws]
#[tokio::test]
async fn test_fuzz_accounts_generation() {
let templates = setup_templates()?;
verify_fuzz_accounts(&templates).await?;
}
#[throws]
#[tokio::test]
async fn test_test_fuzz_generation() {
let templates = setup_templates()?;
verify_test_fuzz(&templates).await?;
}
fn generate_templates(
templates: &TridentTemplates,
idls: Vec<Idl>,
) -> anyhow::Result<trident_template::GeneratedFiles> {
let current_package_version = env!("CARGO_PKG_VERSION");
templates
.generate(&idls, current_package_version)
.map_err(|e| anyhow::anyhow!("Template generation failed: {}", e))
}
#[throws]
async fn verify_types(templates: &TridentTemplates) {
let idls = vec![
read_idl("additional_program.json")?,
read_idl("idl_test.json")?,
];
let generated_files = generate_templates(templates, idls)?;
let generated_types = &generated_files.types;
let expected_types_path = construct_path("fuzz_template/types.rs");
let expected_types = fs::read_to_string(&expected_types_path)?;
let formatted_types = Commander::format_program_code_nightly(generated_types).await?;
assert_str_eq!(formatted_types, expected_types, "Types.rs does not match");
}
#[throws]
async fn verify_fuzz_accounts(templates: &TridentTemplates) {
let idls = vec![
read_idl("additional_program.json")?,
read_idl("idl_test.json")?,
];
let generated_files = generate_templates(templates, idls)?;
let generated_fuzz = &generated_files.fuzz_accounts;
let expected_fuzz_path = construct_path("fuzz_template/fuzz_accounts.rs");
let expected_fuzz = fs::read_to_string(&expected_fuzz_path)?;
let formatted_fuzz = Commander::format_program_code_nightly(generated_fuzz).await?;
assert_str_eq!(
formatted_fuzz,
expected_fuzz,
"Fuzz transactions does not match"
);
}
#[throws]
async fn verify_test_fuzz(templates: &TridentTemplates) {
let idls = vec![
read_idl("additional_program.json")?,
read_idl("idl_test.json")?,
];
let generated_files = generate_templates(templates, idls)?;
let generated_test_fuzz = &generated_files.test_fuzz;
let expected_test_fuzz_path = construct_path("fuzz_template/test_fuzz.rs");
let expected_test_fuzz = fs::read_to_string(&expected_test_fuzz_path)?;
let formatted_test_fuzz = Commander::format_program_code_nightly(generated_test_fuzz).await?;
assert_str_eq!(
formatted_test_fuzz,
expected_test_fuzz,
"Test fuzz does not match"
);
}
#[throws]
fn read_idl(idl_name: &str) -> Idl {
let current_dir = std::env::current_dir()?;
let anchor_idl_path: PathBuf = [
current_dir.as_ref(),
Path::new(&format!("tests/anchor_idl/{}", idl_name)),
]
.iter()
.collect();
let mut idl_file = std::fs::File::open(&anchor_idl_path)?;
let mut json_content = String::new();
idl_file.read_to_string(&mut json_content)?;
match serde_json::from_str::<Idl>(&json_content) {
Ok(parsed_idl) => parsed_idl,
Err(e) => {
panic!("Failed to parse {}: {}", anchor_idl_path.display(), e);
}
}
}
fn construct_path(relative_path: &str) -> PathBuf {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let mut path = PathBuf::from(manifest_dir);
path.push("tests");
path.push(relative_path);
path
}
#[throws]
fn setup_templates() -> TridentTemplates {
TridentTemplates::default()
}