use packr::abi::Value;
use packr::runtime::CompositionBuilder;
use std::path::Path;
fn load_doubler_package() -> Vec<u8> {
let wasm_path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("packages/doubler/target/wasm32-unknown-unknown/release/doubler_package.wasm");
std::fs::read(&wasm_path).unwrap_or_else(|e| {
panic!(
"Failed to read doubler package at {}: {}. Run: cd packages/doubler && cargo build --target wasm32-unknown-unknown --release",
wasm_path.display(),
e
)
})
}
fn load_adder_package() -> Vec<u8> {
let wasm_path = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("packages/adder/target/wasm32-unknown-unknown/release/adder_package.wasm");
std::fs::read(&wasm_path).unwrap_or_else(|e| {
panic!(
"Failed to read adder package at {}: {}. Run: cd packages/adder && cargo build --target wasm32-unknown-unknown --release",
wasm_path.display(),
e
)
})
}
#[test]
fn composition_doubler_alone() {
let doubler_wasm = load_doubler_package();
let mut composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.build()
.expect("failed to build composition");
let result = composition
.call("doubler", "double", &Value::S64(5))
.expect("failed to call double");
assert_eq!(result, Value::S64(10));
}
#[test]
fn composition_adder_with_doubler() {
let doubler_wasm = load_doubler_package();
let adder_wasm = load_adder_package();
let mut composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.add_package("adder", adder_wasm)
.wire("adder", "math", "double", "doubler", "double")
.build()
.expect("failed to build composition");
let result = composition
.call("adder", "process", &Value::S64(5))
.expect("failed to call process");
assert_eq!(result, Value::S64(11));
}
#[test]
fn composition_multiple_calls() {
let doubler_wasm = load_doubler_package();
let adder_wasm = load_adder_package();
let mut composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.add_package("adder", adder_wasm)
.wire("adder", "math", "double", "doubler", "double")
.build()
.expect("failed to build composition");
let test_cases = vec![
(0, 1), (1, 3), (5, 11), (10, 21), (100, 201), ];
for (input, expected) in test_cases {
let result = composition
.call("adder", "process", &Value::S64(input))
.unwrap_or_else(|_| panic!("failed to call process with {}", input));
assert_eq!(
result,
Value::S64(expected),
"process({}) should be {}",
input,
expected
);
}
}
#[test]
fn composition_list_packages() {
let doubler_wasm = load_doubler_package();
let adder_wasm = load_adder_package();
let composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.add_package("adder", adder_wasm)
.wire("adder", "math", "double", "doubler", "double")
.build()
.expect("failed to build composition");
let packages = composition.packages();
assert_eq!(packages.len(), 2);
assert!(packages.contains(&"doubler".to_string()));
assert!(packages.contains(&"adder".to_string()));
}
#[test]
fn composition_call_both_packages() {
let doubler_wasm = load_doubler_package();
let adder_wasm = load_adder_package();
let mut composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.add_package("adder", adder_wasm)
.wire("adder", "math", "double", "doubler", "double")
.build()
.expect("failed to build composition");
let double_result = composition
.call("doubler", "double", &Value::S64(7))
.expect("failed to call doubler");
assert_eq!(double_result, Value::S64(14));
let process_result = composition
.call("adder", "process", &Value::S64(7))
.expect("failed to call adder");
assert_eq!(process_result, Value::S64(15)); }
#[test]
fn composition_negative_numbers() {
let doubler_wasm = load_doubler_package();
let adder_wasm = load_adder_package();
let mut composition = CompositionBuilder::new()
.add_package("doubler", doubler_wasm)
.add_package("adder", adder_wasm)
.wire("adder", "math", "double", "doubler", "double")
.build()
.expect("failed to build composition");
let result = composition
.call("adder", "process", &Value::S64(-5))
.expect("failed to call process with negative");
assert_eq!(result, Value::S64(-9));
}