fixture
import std::test::fixture; · source
Types
Fixture
type trait Fixture {
static setup() -> Result<This, TestError>;
}
A fixture is a value a test needs set up beforehand and torn down after — a temp directory, a seeded RNG, a probe allocator, a socket. The trait standardizes only the setup half.
Teardown is the value's own Drop impl. Because Cryo runs drop glue on every scope exit — including the early-return paths ? and return Result::Err(...) take — a fixture bound as a local is torn down on success and on assertion failure, with no per-test cleanup code.
![test]
function writes_a_file() -> Result<(), TestError> {
mut tmp: TmpDir = TmpDir::setup()?;
// ... the directory is removed however this function exits ...
return Result::Ok(());
}
Define setup() once, in the Fixture impl. A second inherent setup() that called TmpDir::setup() would recurse into itself.
The one path Drop cannot cover is a hard process abort; there the OS reclaims everything.
Constructors
static setup() -> Result<This, TestError>;
static setup() -> Result<This, TestError>;Construct the fixture, or return a TestError (use bail_other for environment/setup failures) if the resource could not be acquired.
type struct Name { ... }
type enum Name { ... }
type trait Name { ... }
type union Name { ... }Begins a type declaration; the keyword that follows says which kind. On its own, type Name = Existing; declares an alias.
type trait Name : Base {
method(&this, other: &This) -> Ret;
}Names a set of methods a type may implement. Inside the body This is the implementing type; methods may carry default bodies, and a trait may require a base trait (type trait Ord : Eq). Generic code asks for a trait with where T: Name.
type trait Fixture {
static setup() -> Result<This, TestError>;
}A per-test resource. setup() builds it; the value's Drop impl is the teardown. Bind the result as a local in the test function and let scope exit run the teardown on every path.
static name(param: Type) -> Ret { ... }A method that belongs to the type rather than an instance, called as Type::name(..). For structs, static new(..) returning a struct literal is the idiomatic constructor.
static Fixture::setup() -> Result<This, TestError>Construct the fixture, or return a TestError (use bail_other for environment/setup failures) if the resource could not be acquired.
ThisThe implementing type, inside a trait or implement body. other: &This in a trait method is a reference to whichever type implements it; This::Item names an associated type.
type enum TestError {
Failed(String);
Other(String);
}Why a test failed. The runner prints the variant's message verbatim to stderr from the child process before exiting non-zero, so the parent can show the failing message in the test summary.
std::test::errorfunction name<T>(param: Type) -> Ret { ... }Declares a function. Parameters are written name: Type and are never inferred; the return type follows -> and defaults to void. Declaration order does not matter: every signature is collected before any body is checked, so functions may call each other freely and recurse.
function writes_a_file() -> Result<(), TestError>primitive ()The unit type: a value that carries no information, and the empty tuple. Distinct from void, which is the absence of a value - Result<(), E> succeeds with nothing to return. 0 bytes.
mut name: Type = value;A mutable binding, reassignable after declaration - mutability is opt-in, const is the default. At module level it declares mutable global state. Before & it marks an exclusive reference or receiver instead.
mut tmp: TmpDirvalue?Error propagation. On a Result<T, E> it yields the T of an Ok and otherwise returns the Err(e) from the enclosing function unchanged; on an Option<T> it yields the T of a Some or returns None. The enclosing function must return a matching Result / Option.
return value;Leaves the current function with the given value. A function whose return type is not void must return one; a bare return; is for void. In an async function it completes the future with the value.
Result::Ok(T)import a::b;
import a::b::{ X, Y };
import a::b as c;
import a::b::*;Brings a module, or selected items from it, into scope. One path per declaration: use the brace form for several items, as to alias, and * for everything public (prefer the brace form; wildcards invite name collisions).
namespace std::test::fixture;Fixture: a per-test resource with deterministic setup and teardown.
module pageResult::Err(E)function name(count: i32, args...)A variadic parameter: the trailing bucket receives any number of further arguments with C's calling convention, so the function stays ABI-compatible with the printf family. Wrap the bucket in VaArgs to read typed values from it.
static Fixture::setup() -> Result<This, TestError>Construct the fixture, or return a TestError (use bail_other for environment/setup failures) if the resource could not be acquired.
type trait Fixture {
static setup() -> Result<This, TestError>;
}A per-test resource. setup() builds it; the value's Drop impl is the teardown. Bind the result as a local in the test function and let scope exit run the teardown on every path.