use std::sync::mpsc;
use piecrust::{ContractData, Error, SessionData, VM, contract_bytecode};
const OWNER: [u8; 32] = [0u8; 32];
const LIMIT: u64 = 1_000_000;
#[test]
fn feed() -> Result<(), Error> {
let vm = VM::ephemeral()?;
let mut session = vm.session(SessionData::builder())?;
let id = session.deploy(
contract_bytecode!("feeder"),
ContractData::builder().owner(OWNER),
LIMIT,
)?;
const FEED_NUM: u32 = 10;
const GAS_LIMIT: u64 = 1_000_000;
let (first_sender, receiver) = mpsc::channel();
session.feeder_call::<_, ()>(
id,
"feed_num",
&FEED_NUM,
GAS_LIMIT,
first_sender,
)?;
let numbers = receiver
.into_iter()
.map(|data| {
rkyv::from_bytes(&data).expect("Fed data should be a number")
})
.collect::<Vec<u32>>();
assert_eq!(
numbers.len(),
FEED_NUM as usize,
"The correct number of numbers should be fed"
);
for (i, n) in numbers.into_iter().enumerate() {
assert_eq!(i as u32, n, "Numbers should be fed in order");
}
let (second_sender, receiver) = mpsc::channel();
session.feeder_call::<_, ()>(
id,
"feed_num_raw",
&FEED_NUM,
GAS_LIMIT,
second_sender,
)?;
let numbers = receiver
.into_iter()
.map(|data| {
rkyv::from_bytes(&data).expect("Fed data should be a number")
})
.collect::<Vec<u32>>();
assert_eq!(
numbers.len(),
FEED_NUM as usize,
"The correct number of numbers should be fed"
);
for (i, n) in numbers.into_iter().enumerate() {
assert_eq!(i as u32, n, "Numbers should be fed in order");
}
Ok(())
}
#[test]
fn feed_errors_when_normal_call() -> Result<(), Error> {
let vm = VM::ephemeral()?;
let mut session = vm.session(SessionData::builder())?;
let id = session.deploy(
contract_bytecode!("feeder"),
ContractData::builder().owner(OWNER),
LIMIT,
)?;
const FEED_NUM: u32 = 10;
session
.call::<_, ()>(id, "feed_num", &FEED_NUM, LIMIT)
.expect_err("Call should error when not called with `feeder_call` or `feeder_call_raw`");
Ok(())
}
#[test]
fn feed_out_of_gas() -> Result<(), Error> {
let vm = VM::ephemeral()?;
let mut session = vm.session(SessionData::builder())?;
let id = session.deploy(
contract_bytecode!("feeder"),
ContractData::builder().owner(OWNER),
LIMIT,
)?;
const FEED_NUM: u32 = 100;
const GAS_LIMIT: u64 = 1_000;
let (sender, _receiver) = mpsc::channel();
let err = session
.feeder_call::<_, ()>(id, "feed_num", &FEED_NUM, GAS_LIMIT, sender)
.expect_err("Call should error when out of gas");
assert!(matches!(err, Error::OutOfGas));
Ok(())
}