From 9e6ff713300295150a02c6ab12852d325d92559a Mon Sep 17 00:00:00 2001
From: Andrew Kelley
- When the zig test tool is building a test runner, only resolved {#syntax#}test{#endsyntax#} - declarations are included in the build. Initially, only the given Zig source file's top-level - declarations are resolved. Unless nested {#link|containers|Containers#} are referenced from a top-level test declaration, - nested container tests will not be resolved. -
-- The code sample below uses the {#syntax#}std.testing.refAllDecls(@This()){#endsyntax#} function call to - reference all of the containers that are in the file including the imported Zig source file. The code - sample also shows an alternative way to reference containers using the {#syntax#}_ = C;{#endsyntax#} - syntax. This syntax tells the compiler to ignore the result of the expression on the right side of the - assignment operator. -
- {#code_begin|test|testing_nested_container_tests#} -const std = @import("std"); -const expect = std.testing.expect; - -// Imported source file tests will run when referenced from a top-level test declaration. -// The next line alone does not cause "testing_introduction.zig" tests to run. -const imported_file = @import("testing_introduction.zig"); - -test { - // To run nested container tests, either, call `refAllDecls` which will - // reference all declarations located in the given argument. - // `@This()` is a builtin function that returns the innermost container it is called from. - // In this example, the innermost container is this file (implicitly a struct). - std.testing.refAllDecls(@This()); - - // or, reference each container individually from a top-level test declaration. - // The `_ = C;` syntax is a no-op reference to the identifier `C`. - _ = S; - _ = U; - _ = @import("testing_introduction.zig"); -} - -const S = struct { - test "S demo test" { - try expect(true); - } - - const SE = enum { - V, - - // This test won't run because its container (SE) is not referenced. - test "This Test Won't Run" { - try expect(false); - } - }; -}; - -const U = union { // U is referenced by the file's top-level test declaration - s: US, // and US is referenced here; therefore, "U.Us demo test" will run - - const US = struct { - test "U.US demo test" { - // This test is a top-level test declaration for the struct. - // The struct is nested (declared) inside of a union. - try expect(true); - } - }; - - test "U demo test" { - try expect(true); - } -}; - {#code_end#} - {#header_close#} {#header_open|Test Failure#}
The default test runner checks for an {#link|error|Errors#} returned from a test.
From 8662c0ff43aad7191b063047c71384e868086d6f Mon Sep 17 00:00:00 2001
From: Andrew Kelley
- To convert one pointer type to another, use {#link|@ptrCast#}. This is an unsafe - operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other - conversions are not possible. + {#link|@ptrCast#} converts a pointer's element type to another. This + creates a new pointer that can cause undetectable illegal behavior + depending on the loads and stores that pass through it. Generally, other + kinds of type conversions are preferable to + {#syntax#}@ptrCast{#endsyntax#} if possible.
{#code_begin|test|test_pointer_casting#} const std = @import("std"); @@ -8592,7 +8594,8 @@ test "decl access by string" {{#syntax#}@floatFromInt(int: anytype) anytype{#endsyntax#}
Converts an integer to the closest floating point representation. The return type is the inferred result type. - To convert the other way, use {#link|@intFromFloat#}. This cast is always safe. + To convert the other way, use {#link|@intFromFloat#}. This operation is legal + for all values of all integer types.
{#header_close#} From 56db624643bb506d2b8fa9d81f4146c1b1f4e3c3 Mon Sep 17 00:00:00 2001 From: Andrew KelleyThis build.zig file is automatically generated
- by zig init-exe.
This build.zig file is automatically generated
- by zig init-lib.
{#syntax#}
-lib.addCSourceFile(.{ .file = .{ .path = "src/lib.c" }, .flags = &.{
- "-Wall",
- "-Wextra",
- "-Werror",
- } });
- {#endsyntax#}
- {#header_close#}
-
+ + For the time being, the build system documentation is hosted externally: + Build System Documentation +
{#header_close#} {#header_open|C#}
From ab82132749f24702c215545212dd83538a04cdb9 Mon Sep 17 00:00:00 2001
From: Andrew Kelley
Non-named test blocks always run during test builds and are exempt from + {#link|Skip Tests#}.
Test declarations are similar to {#link|Functions#}: they have a return type and a block of code. The implicit return type of {#syntax#}test{#endsyntax#} is the {#link|Error Union Type#} {#syntax#}anyerror!void{#endsyntax#}, @@ -5009,12 +5007,12 @@ test "if error union with optional" { {#see_also|Optionals|Errors#} {#header_close#} {#header_open|defer#} +
Executes an expression unconditionally at scope exit.
{#code_begin|test|test_defer#} const std = @import("std"); const expect = std.testing.expect; const print = std.debug.print; -// defer will execute an expression at the end of the current scope. fn deferExample() !usize { var a: usize = 1; @@ -5031,10 +5029,14 @@ fn deferExample() !usize { test "defer basics" { try expect((try deferExample()) == 5); } + {#code_end#} +Defer expressions are evaluated in reverse order.
+ {#code_begin|test|defer_unwind#} +const std = @import("std"); +const expect = std.testing.expect; +const print = std.debug.print; -// If multiple defer statements are specified, they will be executed in -// the reverse order they were run. -fn deferUnwindExample() void { +test "defer unwinding" { print("\n", .{}); defer { @@ -5050,63 +5052,15 @@ fn deferUnwindExample() void { } } } - -test "defer unwinding" { - deferUnwindExample(); -} {#code_end#} +Inside a defer expression the return statement is not allowed.
{#code_begin|test_err|test_invalid_defer|cannot return from defer expression#} -// Inside a defer expression the return statement is not allowed. fn deferInvalidExample() !void { defer { return error.DeferError; } return error.DeferError; -} - {#code_end#} - {#code_begin|test|test_errdefer#} -const std = @import("std"); -const print = std.debug.print; - -// The errdefer keyword is similar to defer, but will only execute if the -// scope returns with an error. -// -// This is especially useful in allowing a function to clean up properly -// on error, and replaces goto error handling tactics as seen in c. -fn deferErrorExample(is_error: bool) !void { - print("\nstart of function\n", .{}); - - // This will always be executed on exit - defer { - print("end of function\n", .{}); - } - - errdefer { - print("encountered an error!\n", .{}); - } - - if (is_error) { - return error.DeferError; - } -} - -// The errdefer keyword also supports an alternative syntax to capture the -// generated error. -// -// This is useful for printing an additional error message during clean up. -fn deferErrorCaptureExample() !void { - errdefer |err| { - std.debug.print("the error is {s}\n", .{@errorName(err)}); - } - - return error.DeferError; -} - -test "errdefer unwinding" { - deferErrorExample(false) catch {}; - deferErrorExample(true) catch {}; - deferErrorCaptureExample() catch {}; } {#code_end#} {#see_also|Errors#}