bop-lang 0.3.0

A small, embeddable, dynamically-typed programming language with zero dependencies
Documentation
// std.test — minimal assertion / test-runner toolkit.
//
// This isn't a xUnit clone — just the assertion primitives
// you'll reach for when writing quick sanity checks in Bop
// scripts. When a check fails the program halts with a
// runtime error carrying the failure detail; print-based
// reporting is intentionally out of scope (callers can wrap
// in `try_call` if they want to report + continue).

// Assert that `cond` is truthy. On failure, raises a runtime
// error with the caller's `message` for context.
fn assert(cond, message) {
    if !cond {
        panic(message)
    }
}

// Assert that two values are structurally equal (same as `==`).
// Message prefix `"assert_eq failed"` so failures are obvious
// in the crash log.
fn assert_eq(actual, expected) {
    if actual != expected {
        panic("assert_eq failed: " + actual.inspect() + " != " + expected.inspect())
    }
}

// Assert two floats are within `tolerance` of each other. Use
// this instead of `assert_eq` when comparing `Number` values
// subject to rounding.
fn assert_near(actual, expected, tolerance) {
    let diff = actual - expected
    if diff < 0 { diff = -diff }
    if diff > tolerance {
        panic("assert_near failed: " + actual.inspect() + " not within " + tolerance.inspect() + " of " + expected.inspect())
    }
}

// Assert that `body()` (a zero-arg closure) raises a runtime
// error. Useful for negative tests. On success (no raise),
// the assertion itself fails.
//
// `try_call` wraps successful returns in `Result::Ok(_)` and
// caught errors in `Result::Err(_)` — structurally, so the
// enum doesn't need to be declared here. We match on the
// variant name and turn the outcome into a bool for the
// subsequent `if`.
fn assert_raises(body) {
    let outcome = try_call(body)
    let raised = match outcome {
        Result::Ok(_) => false,
        Result::Err(_) => true,
    }
    if !raised {
        panic("assert_raises: body did not raise")
    }
}