# Testing and bench

Tests and benchmarks live in the file they are about. `vyrn run` and `vyrn build` strip them.

## test blocks

A `test` block sits beside the code it tests. `vyrn test <file>` runs the blocks and reports each one; `--name` selects a subset. `assert` and `assertEq` exist inside a test block and nowhere else.

A file can hold tests and a `main` at once. The tests are checked, then stripped, so the program is unchanged by having them.

```vyrn
// A `test` block lives beside the code it tests. `vyrn run` and `vyrn build`
// strip them; `vyrn test` runs them.
import { joinWith } from "std/strings"

fn clamp(x: Int64, lo: Int64, hi: Int64) -> Int64 {
    if x < lo {
        return lo
    }
    if x > hi {
        return hi
    }
    return x
}

test "clamp holds the bounds" {
    assertEq(clamp(5, 0, 10), 5)
    assertEq(clamp(0 - 3, 0, 10), 0)
    assertEq(clamp(99, 0, 10), 10)
}

test "clamp leaves a value inside them alone" {
    assert(clamp(7, 0, 10) == 7)
}

export fn demo() -> String {
    return joinWith(["clamp(5) is \{clamp(5, 0, 10)}", "clamp(99) is \{clamp(99, 0, 10)}"], "\n")
}

fn main() -> Int64 {
    print(demo())
    return 0
}
```

Built output:

```
clamp(5) is 5
clamp(99) is 10
```

## bench blocks

A `bench` block is a body the timer runs. `vyrn bench` reports the minimum, median and mean over many samples. It uses the native build, because that is what a shipped program is.

`blackBox` hides a value from the optimizer. Around the input it stops the compiler from precomputing the answer; around the result it keeps the work live. `vyrn bench --check` runs each body once, compiled, which is what CI does.

```vyrn
// A `bench` block is a body the timer runs. `blackBox` hides a value from the
// optimizer, so the work is done rather than folded away.
fn hashTo(n: Int64) -> Int64 {
    let mut h = 0
    let mut i = 0
    while i < n {
        h = (h * 31 + i) % 1000000007
        i = i + 1
    }
    return h
}

bench "hash to 1000" {
    blackBox(hashTo(blackBox(1000)))
}

export fn demo() -> String {
    return "hashTo(1000) is \{hashTo(1000)}"
}

fn main() -> Int64 {
    print(demo())
    return 0
}
```

Built output:

```
hashTo(1000) is 691508967
```

---

From https://vyrn-lang.github.io/tooling/testing.html — generated by `site/export.vyrn` from the Vyrn repository.
