diff --git a/docs/rules.md b/docs/rules.md index b698e3b0..57beb4ff 100644 --- a/docs/rules.md +++ b/docs/rules.md @@ -65,3 +65,24 @@ zig_package(name, de | srcs | Other source files required when building the package. | List of labels | optional | [] | + + +## zig_test + +
+zig_test(name, deps, main, srcs)
+
+ + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| deps | Packages or libraries required to build the target. | List of labels | optional | [] | +| main | The main source file. | Label | required | | +| srcs | Other source files required to build the target. | List of labels | optional | [] | + + diff --git a/e2e/workspace/multiple-sources-and-packages-test/BUILD.bazel b/e2e/workspace/multiple-sources-and-packages-test/BUILD.bazel new file mode 100644 index 00000000..ded7351c --- /dev/null +++ b/e2e/workspace/multiple-sources-and-packages-test/BUILD.bazel @@ -0,0 +1,18 @@ +load("@rules_zig//zig:defs.bzl", "zig_package", "zig_test") + +zig_test( + name = "test", + srcs = [ + "test/a.zig", + "test/b.zig", + ], + main = "main.zig", + deps = [ + ":pkg", + ], +) + +zig_package( + name = "pkg", + main = "pkg/main.zig", +) diff --git a/e2e/workspace/multiple-sources-and-packages-test/main.zig b/e2e/workspace/multiple-sources-and-packages-test/main.zig new file mode 100644 index 00000000..f62985b8 --- /dev/null +++ b/e2e/workspace/multiple-sources-and-packages-test/main.zig @@ -0,0 +1,11 @@ +const std = @import("std"); +const pkg = @import("pkg"); + +test "1 + 1" { + try std.testing.expectEqual(@as(i64, 2), pkg.add(1, 1)); +} + +test { + _ = @import("test/a.zig"); + _ = @import("test/b.zig"); +} diff --git a/e2e/workspace/multiple-sources-and-packages-test/pkg/main.zig b/e2e/workspace/multiple-sources-and-packages-test/pkg/main.zig new file mode 100644 index 00000000..0e0658d1 --- /dev/null +++ b/e2e/workspace/multiple-sources-and-packages-test/pkg/main.zig @@ -0,0 +1,3 @@ +pub fn add(a: i64, b: i64) i64 { + return a + b; +} diff --git a/e2e/workspace/multiple-sources-and-packages-test/test/a.zig b/e2e/workspace/multiple-sources-and-packages-test/test/a.zig new file mode 100644 index 00000000..2348dd81 --- /dev/null +++ b/e2e/workspace/multiple-sources-and-packages-test/test/a.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const pkg = @import("pkg"); + +test "1 + 2" { + try std.testing.expectEqual(@as(i64, 3), pkg.add(1, 2)); +} diff --git a/e2e/workspace/multiple-sources-and-packages-test/test/b.zig b/e2e/workspace/multiple-sources-and-packages-test/test/b.zig new file mode 100644 index 00000000..092b6d74 --- /dev/null +++ b/e2e/workspace/multiple-sources-and-packages-test/test/b.zig @@ -0,0 +1,6 @@ +const std = @import("std"); +const pkg = @import("pkg"); + +test "1 + 3" { + try std.testing.expectEqual(@as(i64, 4), pkg.add(1, 3)); +} diff --git a/e2e/workspace/simple-test/BUILD.bazel b/e2e/workspace/simple-test/BUILD.bazel new file mode 100644 index 00000000..81e9ffb8 --- /dev/null +++ b/e2e/workspace/simple-test/BUILD.bazel @@ -0,0 +1,6 @@ +load("@rules_zig//zig:defs.bzl", "zig_test") + +zig_test( + name = "test", + main = "main.zig", +) diff --git a/e2e/workspace/simple-test/main.zig b/e2e/workspace/simple-test/main.zig new file mode 100644 index 00000000..f740796c --- /dev/null +++ b/e2e/workspace/simple-test/main.zig @@ -0,0 +1,5 @@ +const std = @import("std"); + +test "simple" { + try std.testing.expectEqual(2, 1 + 1); +} diff --git a/zig/BUILD.bazel b/zig/BUILD.bazel index 5b3f2a0b..cad3e968 100644 --- a/zig/BUILD.bazel +++ b/zig/BUILD.bazel @@ -31,6 +31,7 @@ bzl_library( "//zig/private:zig_binary", "//zig/private:zig_library", "//zig/private:zig_package", + "//zig/private:zig_test", ], ) diff --git a/zig/defs.bzl b/zig/defs.bzl index 8104f184..e7c82ada 100644 --- a/zig/defs.bzl +++ b/zig/defs.bzl @@ -3,7 +3,9 @@ load("//zig/private:zig_binary.bzl", _zig_binary = "zig_binary") load("//zig/private:zig_library.bzl", _zig_library = "zig_library") load("//zig/private:zig_package.bzl", _zig_package = "zig_package") +load("//zig/private:zig_test.bzl", _zig_test = "zig_test") zig_binary = _zig_binary zig_library = _zig_library zig_package = _zig_package +zig_test = _zig_test diff --git a/zig/private/BUILD.bazel b/zig/private/BUILD.bazel index 0fac081b..16bdb357 100644 --- a/zig/private/BUILD.bazel +++ b/zig/private/BUILD.bazel @@ -32,6 +32,17 @@ bzl_library( ], ) +bzl_library( + name = "zig_test", + srcs = ["zig_test.bzl"], + visibility = ["//zig:__subpackages__"], + deps = [ + "//zig/private/common:filetypes", + "//zig/private/common:zig_cache", + "//zig/private/providers:zig_package_info", + ], +) + bzl_library( name = "toolchains_repo", srcs = ["toolchains_repo.bzl"], diff --git a/zig/private/zig_test.bzl b/zig/private/zig_test.bzl new file mode 100644 index 00000000..f408701c --- /dev/null +++ b/zig/private/zig_test.bzl @@ -0,0 +1,90 @@ +"""Implementation of the zig_test rule.""" + +load("//zig/private/common:filetypes.bzl", "ZIG_SOURCE_EXTENSIONS") +load("//zig/private/common:zig_cache.bzl", "zig_cache_output") +load( + "//zig/private/providers:zig_package_info.bzl", + "ZigPackageInfo", + "zig_package_dependencies", +) + +DOC = """\ +""" + +ATTRS = { + "main": attr.label( + allow_single_file = ZIG_SOURCE_EXTENSIONS, + doc = "The main source file.", + mandatory = True, + ), + "srcs": attr.label_list( + allow_files = ZIG_SOURCE_EXTENSIONS, + doc = "Other source files required to build the target.", + mandatory = False, + ), + "deps": attr.label_list( + doc = "Packages or libraries required to build the target.", + mandatory = False, + providers = [ZigPackageInfo], + ), +} + +def _zig_test_impl(ctx): + ziginfo = ctx.toolchains["//zig:toolchain_type"].ziginfo + + outputs = [] + + direct_inputs = [] + transitive_inputs = [] + + args = ctx.actions.args() + args.use_param_file("@%s") + + # TODO[AH] Append `.exe` extension on Windows. + output = ctx.actions.declare_file(ctx.label.name) + outputs.append(output) + args.add(output, format = "-femit-bin=%s") + + direct_inputs.append(ctx.file.main) + direct_inputs.extend(ctx.files.srcs) + args.add(ctx.file.main) + + zig_package_dependencies( + deps = ctx.attr.deps, + inputs = transitive_inputs, + args = args, + ) + + zig_cache_output( + actions = ctx.actions, + name = ctx.label.name, + outputs = outputs, + args = args, + ) + + ctx.actions.run( + outputs = outputs, + inputs = depset(direct = direct_inputs, transitive = transitive_inputs), + executable = ziginfo.target_tool_path, + tools = ziginfo.tool_files, + arguments = ["test", "--test-no-exec", args], + mnemonic = "ZigBuildTest", + progress_message = "Building %{input} as Zig test %{output}", + execution_requirements = {tag: "" for tag in ctx.attr.tags}, + ) + + default = DefaultInfo( + executable = output, + files = depset([output]), + runfiles = ctx.runfiles(files = [output]), + ) + + return [default] + +zig_test = rule( + _zig_test_impl, + attrs = ATTRS, + doc = DOC, + test = True, + toolchains = ["//zig:toolchain_type"], +)