Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: update assert function to include reason argument #4

Merged
merged 7 commits into from
May 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ jobs:
- name: Install XTP CLI
run: curl https://static.dylibso.com/cli/install.sh | sudo sh

- name: Check XTP CLI Version
run: xtp -v

- name: Build
run: cargo build --release --examples

Expand Down
8 changes: 8 additions & 0 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ pub fn test() -> FnResult<()> {
// assert the count of the vowels is correct, giving the test case a name (which will be shown in the CLI output)
xtp_test::assert_eq("count_vowels of 'some input'", res.count, 4);

let time_ns = xtp_test::time_ns("count_vowels", "o".repeat(1024 * 10))?;
const TARGET_NS: u64 = 5e7 as u64;
xtp_test::assert(
"timing count_vowels nanos (10KB input)",
time_ns < TARGET_NS,
format!("{} > {}", time_ns, TARGET_NS),
);

// create a group of tests, which will be run together and reset after the group is complete
xtp_test::group("count_vowels maintains state", || {
let mut accum_total = 0;
Expand Down
76 changes: 66 additions & 10 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mod harness {
extern "C" {
pub fn call(name: u64, input: u64) -> u64;
pub fn time(name: u64, input: u64) -> u64;
pub fn assert(name: u64, value: u64);
pub fn assert(name: u64, value: u64, message: u64);
pub fn reset();
pub fn group(name: u64);
}
Expand Down Expand Up @@ -56,23 +56,34 @@ pub fn time_sec(func_name: impl AsRef<str>, input: impl ToMemory) -> Result<f64>
time_ns(func_name, input).map(|x| x as f64 / 1e9)
}

/// Assert that the `outcome` is true, naming the assertion with `msg`, which will be used as a label in the CLI runner.
pub fn assert(msg: impl AsRef<str>, outcome: bool) {
let msg_mem = Memory::from_bytes(msg.as_ref()).expect("assert message Extism memory");
/// Assert that the `outcome` is true, naming the assertion with `name`, which will be used as a label in the CLI runner. The `reason` argument
/// will be used to print a message when the assertion fails, this should contain some additional information about values being compared.
pub fn assert(name: impl AsRef<str>, outcome: bool, reason: impl AsRef<str>) {
let name_mem = Memory::from_bytes(name.as_ref()).expect("assert name Extism memory");
let reason_mem = Memory::from_bytes(reason.as_ref()).expect("assert reason Extism memory");
unsafe {
harness::assert(msg_mem.offset(), outcome as u64);
harness::assert(name_mem.offset(), outcome as u64, reason_mem.offset());
}
msg_mem.free();
reason_mem.free();
name_mem.free();
}

/// Assert that `x` and `y` are equal, naming the assertion with `msg`, which will be used as a label in the CLI runner.
pub fn assert_eq<U, T: PartialEq<U>>(msg: impl AsRef<str>, x: T, y: U) {
assert(msg, x == y);
pub fn assert_eq<U: std::fmt::Debug, T: std::fmt::Debug + PartialEq<U>>(
msg: impl AsRef<str>,
x: T,
y: U,
) {
assert(msg, x == y, format!("Expected {:?} == {:?}", x, y));
}

/// Assert that `x` and `y` are not equal, naming the assertion with `msg`, which will be used as a label in the CLI runner.
pub fn assert_ne<U, T: PartialEq<U>>(msg: impl AsRef<str>, x: T, y: U) {
assert(msg, x != y);
pub fn assert_ne<U: std::fmt::Debug, T: std::fmt::Debug + PartialEq<U>>(
msg: impl AsRef<str>,
x: T,
y: U,
) {
assert(msg, x != y, format!("Expected {:?} != {:?}", x, y));
}

// Create a new test group. NOTE: these cannot be nested and starting a new group will end the last one.
Expand Down Expand Up @@ -110,3 +121,48 @@ pub fn group(name: impl AsRef<str>, f: impl FnOnce() -> Result<()>) -> Result<()
reset();
res
}

#[macro_export]
macro_rules! assert {
($name:expr, $b:expr) => {
$crate::assert(
$name,
$b,
format!("Assertion failed ({}, line {})", file!(), line!()),
);
};
}

#[macro_export]
macro_rules! assert_eq {
($name:expr, $a:expr, $b:expr) => {
$crate::assert(
$name,
$a == $b,
format!(
"Expected {:?} == {:?} ({}, line {})",
$a,
$b,
file!(),
line!()
),
);
};
}

#[macro_export]
macro_rules! assert_ne {
($name:expr, $a:expr, $b:expr) => {
$crate::assert(
$name,
$a != $b,
format!(
"Expected {:?} != {:?} ({}, line {})",
$a,
$b,
file!(),
line!()
),
);
};
}
Loading