xll-utils 0.1.0

PE/COFF parsing and export verification utilities for Excel XLL development
Documentation
use xll_utils::pe::parse_pe_file;
use xll_utils::types::Architecture;
use xll_utils::xll::{is_valid_xll, verify_xll_entry_points, xll_info};

fn fixture_path() -> std::path::PathBuf {
    std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
        .join("tests")
        .join("fixtures")
        .join("test_xll.xll")
}

// --- xll_info ---

#[test]
fn xll_info_basic() {
    let info = xll_info(fixture_path()).unwrap();
    assert_eq!(info.name, "test_xll");
    assert_eq!(info.architecture, Architecture::X64);
    assert!(info.export_count >= 9);
}

#[test]
fn xll_info_entry_points() {
    let info = xll_info(fixture_path()).unwrap();
    assert!(info.has_auto_open);
    assert!(info.has_auto_close);
    assert!(info.has_auto_free);
    assert!(info.has_addin_manager_info);
}

#[test]
fn xll_info_exports_sorted() {
    let info = xll_info(fixture_path()).unwrap();
    let mut sorted = info.exports.clone();
    sorted.sort();
    assert_eq!(info.exports, sorted);
}

#[test]
fn xll_info_path_set() {
    let path = fixture_path();
    let info = xll_info(&path).unwrap();
    assert_eq!(info.path, path);
}

#[test]
fn xll_info_nonexistent() {
    let err = xll_info("no_such.xll").unwrap_err();
    assert!(matches!(err, xll_utils::Error::FileOpen { .. }));
}

// --- verify_xll_entry_points ---

#[test]
fn verify_entry_points_valid() {
    let pe = parse_pe_file(fixture_path()).unwrap();
    assert!(verify_xll_entry_points(&pe));
}

// --- is_valid_xll ---

#[test]
fn is_valid_xll_true() {
    assert!(is_valid_xll(fixture_path()).unwrap());
}

#[test]
fn is_valid_xll_nonexistent() {
    let err = is_valid_xll("no_such.xll").unwrap_err();
    assert!(matches!(err, xll_utils::Error::FileOpen { .. }));
}