Testing
Floe supports inline test blocks that live alongside the code they test. Tests are type-checked with the rest of your code but stripped from production output.
Writing tests
Section titled “Writing tests”Use the test keyword followed by a name and a block of assert statements:
fn add(a: number, b: number) -> number { a + b }
test "addition" { assert add(1, 2) == 3 assert add(-1, 1) == 0 assert add(0, 0) == 0}Assert
Section titled “Assert”assert takes any expression that evaluates to boolean. If the expression is false, the test fails.
test "comparisons" { assert 1 < 2 assert "hello" == "hello" assert true != false}The compiler enforces that assert expressions are boolean at compile time.
Co-located tests
Section titled “Co-located tests”Tests live in the same file as the code they test. This makes it easy to keep tests in sync with the implementation:
type Validation { | Valid { string } | Empty | TooShort | TooLong}
fn validate(input: string) -> Validation { const len = input |> String.length match len { 0 -> Empty, 1 -> TooShort, _ -> match len > 100 { true -> TooLong, false -> Valid(input), }, }}
test "validation" { assert validate("") == Empty assert validate("a") == TooShort assert validate("hello") == Valid("hello")}Running tests
Section titled “Running tests”# Run all tests in a directoryfloe test src/
# Run tests in a specific filefloe test src/math.flBehavior in different commands
Section titled “Behavior in different commands”| Command | Test blocks |
|---|---|
floe test | Compiled and executed |
floe check | Type-checked, not executed |
floe build | Stripped from output |
testis a contextual keyword - it only starts a test block when followed by a string literal. You can still usetestas a function or variable name.assertis a keyword that is only valid inside test blocks.- Test blocks cannot be exported.
- Multiple test blocks per file are allowed.