diff --git a/MODULE.bazel b/MODULE.bazel index e63fa5b..ad59fe2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -22,7 +22,8 @@ bazel_lib_toolchains.yq() bazel_lib_toolchains.coreutils() bazel_lib_toolchains.tar() bazel_lib_toolchains.expand_template() -use_repo(bazel_lib_toolchains, "bsd_tar_toolchains", "copy_directory_toolchains", "copy_to_directory_toolchains", "coreutils_toolchains", "expand_template_toolchains", "jq_toolchains", "yq_toolchains") +bazel_lib_toolchains.bats() +use_repo(bazel_lib_toolchains, "bats_toolchains", "bsd_tar_toolchains", "copy_directory_toolchains", "copy_to_directory_toolchains", "coreutils_toolchains", "expand_template_toolchains", "jq_toolchains", "yq_toolchains") register_toolchains( "@copy_directory_toolchains//:all", @@ -31,6 +32,7 @@ register_toolchains( "@yq_toolchains//:all", "@coreutils_toolchains//:all", "@expand_template_toolchains//:all", + "@bats_toolchains//:all", # Expand bsd_tar_toolchains "@bsd_tar_toolchains//:linux_amd64_toolchain", "@bsd_tar_toolchains//:linux_arm64_toolchain", diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index 5a0e479..ec54168 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -151,4 +151,9 @@ stardoc_with_diff_test( bzl_library_target = "//lib:strings", ) +stardoc_with_diff_test( + name = "bats", + bzl_library_target = "//lib:bats", +) + update_docs() diff --git a/docs/bats.md b/docs/bats.md new file mode 100644 index 0000000..6de99e0 --- /dev/null +++ b/docs/bats.md @@ -0,0 +1,25 @@ + + +Bats test runner + + + +## bats_test + +
+bats_test(name, data, env, srcs) ++ + + +**ATTRIBUTES** + + +| Name | Description | Type | Mandatory | Default | +| :------------- | :------------- | :------------- | :------------- | :------------- | +| name | A unique name for this target. | Name | required | | +| data | Runtime dependencies of the test. | List of labels | optional |
[]
|
+| env | Environment variables of the action.{}
|
+| srcs | Test files | List of labels | optional | []
|
+
+
diff --git a/docs/repositories.md b/docs/repositories.md
index 15e3d56..578fc40 100644
--- a/docs/repositories.md
+++ b/docs/repositories.md
@@ -29,6 +29,31 @@ call the individual toolchain registration macros.
+
+
+## register_bats_toolchains
+
++register_bats_toolchains(name, core_version, support_version, assert_version, file_version, + libraries, register) ++ +Registers bats toolchain and repositories + +**PARAMETERS** + + +| Name | Description | Default Value | +| :------------- | :------------- | :------------- | +| name | override the prefix for the generated toolchain repositories |
"bats"
|
+| core_version | bats-core version to use | "v1.10.0"
|
+| support_version | bats-support version to use | "v0.3.0"
|
+| assert_version | bats-assert version to use | "v2.1.0"
|
+| file_version | bats-file version to use | "v0.4.0"
|
+| libraries | additional labels for libraries | []
|
+| register | whether to call through to native.register_toolchains. Should be True for WORKSPACE users, but false when used under bzlmod extension | True
|
+
+
## register_copy_directory_toolchains
diff --git a/e2e/smoke/BUILD.bazel b/e2e/smoke/BUILD.bazel
index cc2fd20..a41fee5 100644
--- a/e2e/smoke/BUILD.bazel
+++ b/e2e/smoke/BUILD.bazel
@@ -1,3 +1,4 @@
+load("@aspect_bazel_lib//lib:bats.bzl", "bats_test")
load("@aspect_bazel_lib//lib:copy_directory.bzl", "copy_directory")
load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
load("@aspect_bazel_lib//lib:diff_test.bzl", "diff_test")
@@ -91,3 +92,10 @@ tar(
srcs = [],
mtree = [],
)
+
+bats_test(
+ name = "bats",
+ srcs = [
+ "basic.bats",
+ ],
+)
diff --git a/e2e/smoke/basic.bats b/e2e/smoke/basic.bats
new file mode 100644
index 0000000..03d254c
--- /dev/null
+++ b/e2e/smoke/basic.bats
@@ -0,0 +1,8 @@
+bats_load_library "bats-support"
+bats_load_library "bats-assert"
+
+@test 'basic' {
+ run echo 'have'
+ assert_output 'have'
+}
+
diff --git a/internal_deps.bzl b/internal_deps.bzl
index ff25756..45d0f9c 100644
--- a/internal_deps.bzl
+++ b/internal_deps.bzl
@@ -4,7 +4,7 @@ Users should *not* need to install these. If users see a load()
statement from these, that's a bug in our distribution.
"""
-load("//lib:repositories.bzl", "register_coreutils_toolchains", "register_jq_toolchains", "register_tar_toolchains", "register_yq_toolchains")
+load("//lib:repositories.bzl", "register_bats_toolchains", "register_coreutils_toolchains", "register_jq_toolchains", "register_tar_toolchains", "register_yq_toolchains")
load("//lib:utils.bzl", http_archive = "maybe_http_archive")
# buildifier: disable=unnamed-macro
@@ -72,3 +72,6 @@ def bazel_lib_internal_deps():
register_yq_toolchains()
register_coreutils_toolchains()
register_tar_toolchains()
+ register_bats_toolchains(
+ libraries = ["@aspect_bazel_lib//lib/tests/bats/bats-custom:custom"],
+ )
diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel
index d689dee..0a56285 100644
--- a/lib/BUILD.bazel
+++ b/lib/BUILD.bazel
@@ -59,11 +59,16 @@ toolchain_type(
name = "tar_toolchain_type",
)
+toolchain_type(
+ name = "bats_toolchain_type",
+)
+
bzl_library(
name = "expand_make_vars",
srcs = ["expand_make_vars.bzl"],
deps = [
- ":expand_template",
+ "//lib/private:expand_locations",
+ "//lib/private:expand_variables",
],
)
@@ -235,6 +240,7 @@ bzl_library(
srcs = ["repositories.bzl"],
deps = [
":utils",
+ "//lib/private:bats_toolchain",
"//lib/private:copy_directory_toolchain",
"//lib/private:copy_to_directory_toolchain",
"//lib/private:coreutils_toolchain",
@@ -295,3 +301,9 @@ bzl_library(
srcs = ["windows_utils.bzl"],
deps = ["//lib/private:paths"],
)
+
+bzl_library(
+ name = "bats",
+ srcs = ["bats.bzl"],
+ deps = ["//lib/private:bats"],
+)
diff --git a/lib/bats.bzl b/lib/bats.bzl
new file mode 100644
index 0000000..fbc018b
--- /dev/null
+++ b/lib/bats.bzl
@@ -0,0 +1,5 @@
+"Bats test runner"
+
+load("//lib/private:bats.bzl", _bats_test = "bats_test")
+
+bats_test = _bats_test
diff --git a/lib/extensions.bzl b/lib/extensions.bzl
index d3c46dc..8ba94dc 100644
--- a/lib/extensions.bzl
+++ b/lib/extensions.bzl
@@ -2,6 +2,8 @@
load(
"@aspect_bazel_lib//lib:repositories.bzl",
+ "DEFAULT_BATS_CORE_VERSION",
+ "DEFAULT_BATS_REPOSITORY",
"DEFAULT_COPY_DIRECTORY_REPOSITORY",
"DEFAULT_COPY_TO_DIRECTORY_REPOSITORY",
"DEFAULT_COREUTILS_REPOSITORY",
@@ -12,6 +14,7 @@ load(
"DEFAULT_TAR_REPOSITORY",
"DEFAULT_YQ_REPOSITORY",
"DEFAULT_YQ_VERSION",
+ "register_bats_toolchains",
"register_copy_directory_toolchains",
"register_copy_to_directory_toolchains",
"register_coreutils_toolchains",
@@ -94,6 +97,15 @@ def _toolchains_extension_impl(mctx):
get_version_fn = lambda attr: None,
)
+ extension_utils.toolchain_repos_bfs(
+ mctx = mctx,
+ get_tag_fn = lambda tags: tags.bats,
+ toolchain_name = "bats",
+ default_repository = DEFAULT_BATS_REPOSITORY,
+ toolchain_repos_fn = lambda name, version: register_bats_toolchains(name = name, core_version = version, register = False),
+ get_version_fn = lambda attr: attr.core_version,
+ )
+
toolchains = module_extension(
implementation = _toolchains_extension_impl,
tag_classes = {
@@ -104,5 +116,9 @@ toolchains = module_extension(
"coreutils": tag_class(attrs = {"name": attr.string(default = DEFAULT_COREUTILS_REPOSITORY), "version": attr.string(default = DEFAULT_COREUTILS_VERSION)}),
"tar": tag_class(attrs = {"name": attr.string(default = DEFAULT_TAR_REPOSITORY)}),
"expand_template": tag_class(attrs = {"name": attr.string(default = DEFAULT_EXPAND_TEMPLATE_REPOSITORY)}),
+ "bats": tag_class(attrs = {
+ "name": attr.string(default = DEFAULT_BATS_REPOSITORY),
+ "core_version": attr.string(default = DEFAULT_BATS_CORE_VERSION),
+ }),
},
)
diff --git a/lib/private/BUILD.bazel b/lib/private/BUILD.bazel
index bef7322..29fbccc 100644
--- a/lib/private/BUILD.bazel
+++ b/lib/private/BUILD.bazel
@@ -274,6 +274,23 @@ bzl_library(
deps = ["@aspect_bazel_lib//lib:paths"],
)
+bzl_library(
+ name = "bats",
+ srcs = ["bats.bzl"],
+ visibility = ["//lib:__subpackages__"],
+ deps = [
+ ":expand_locations",
+ ":expand_variables",
+ "@aspect_bazel_lib//lib:paths",
+ ],
+)
+
+bzl_library(
+ name = "bats_toolchain",
+ srcs = ["bats_toolchain.bzl"],
+ visibility = ["//lib:__subpackages__"],
+)
+
bzl_library(
name = "copy_common",
srcs = ["copy_common.bzl"],
diff --git a/lib/private/bats.bzl b/lib/private/bats.bzl
new file mode 100644
index 0000000..352319e
--- /dev/null
+++ b/lib/private/bats.bzl
@@ -0,0 +1,90 @@
+"bats_test"
+
+load("//lib:paths.bzl", "BASH_RLOCATION_FUNCTION", "to_rlocation_path")
+load(":expand_locations.bzl", "expand_locations")
+load(":expand_variables.bzl", "expand_variables")
+
+_RUNNER_TMPL = """#!/usr/bin/env bash
+set -o errexit -o nounset -o pipefail
+
+{BASH_RLOCATION_FUNCTION}
+
+readonly core_path="$(rlocation {core})"
+readonly bats="$core_path/bin/bats"
+readonly libs=( {libraries} )
+
+{envs}
+
+NEW_LIBS=()
+for lib in "${{libs[@]}}"; do
+ NEW_LIBS+=( $(cd "$(rlocation $lib)/.." && pwd) )
+done
+
+export BATS_LIB_PATH=$(
+ IFS=:
+ echo "${{NEW_LIBS[*]}}"
+)
+export BATS_TEST_TIMEOUT="$TEST_TIMEOUT"
+export BATS_TMPDIR="$TEST_TMPDIR"
+
+exec $bats {tests} $@
+"""
+
+_ENV_SET = """export {var}=\"{value}\""""
+
+def _bats_test_impl(ctx):
+ toolchain = ctx.toolchains["@aspect_bazel_lib//lib:bats_toolchain_type"]
+ batsinfo = toolchain.batsinfo
+
+ envs = []
+ for (key, value) in ctx.attr.env.items():
+ envs.append(_ENV_SET.format(
+ var = key,
+ value = " ".join([expand_variables(ctx, exp, attribute_name = "env") for exp in expand_locations(ctx, value, ctx.attr.data).split(" ")]),
+ ))
+
+ runner = ctx.actions.declare_file("%s_bats.sh" % ctx.label.name)
+ ctx.actions.write(
+ output = runner,
+ content = _RUNNER_TMPL.format(
+ core = to_rlocation_path(ctx, batsinfo.core),
+ libraries = " ".join([to_rlocation_path(ctx, lib) for lib in batsinfo.libraries]),
+ tests = " ".join([test.short_path for test in ctx.files.srcs]),
+ envs = "\n".join(envs),
+ BASH_RLOCATION_FUNCTION = BASH_RLOCATION_FUNCTION,
+ ),
+ is_executable = True,
+ )
+
+ runfiles = ctx.runfiles(ctx.files.srcs + ctx.files.data)
+ runfiles = runfiles.merge(toolchain.default.default_runfiles)
+ runfiles = runfiles.merge(ctx.attr._runfiles.default_runfiles)
+
+ return DefaultInfo(
+ executable = runner,
+ runfiles = runfiles,
+ )
+
+bats_test = rule(
+ implementation = _bats_test_impl,
+ attrs = {
+ "srcs": attr.label_list(
+ allow_files = [".bats"],
+ doc = "Test files",
+ ),
+ "data": attr.label_list(
+ allow_files = True,
+ doc = "Runtime dependencies of the test.",
+ ),
+ "env": attr.string_dict(
+ doc = """Environment variables of the action.
+
+ Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables)
+ and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution.
+ """,
+ ),
+ "_runfiles": attr.label(default = "@bazel_tools//tools/bash/runfiles"),
+ },
+ toolchains = ["@aspect_bazel_lib//lib:bats_toolchain_type"],
+ test = True,
+)
diff --git a/lib/private/bats_toolchain.bzl b/lib/private/bats_toolchain.bzl
new file mode 100644
index 0000000..7008674
--- /dev/null
+++ b/lib/private/bats_toolchain.bzl
@@ -0,0 +1,103 @@
+"Provide access to a bats executable"
+
+BATS_CORE_VERSIONS = {
+ "v1.10.0": "a1a9f7875aa4b6a9480ca384d5865f1ccf1b0b1faead6b47aa47d79709a5c5fd",
+}
+
+BATS_SUPPORT_VERSIONS = {
+ "v0.3.0": "7815237aafeb42ddcc1b8c698fc5808026d33317d8701d5ec2396e9634e2918f",
+}
+
+BATS_ASSERT_VERSIONS = {
+ "v2.1.0": "98ca3b685f8b8993e48ec057565e6e2abcc541034ed5b0e81f191505682037fd",
+}
+
+BATS_FILE_VERSIONS = {
+ "v0.4.0": "9b69043241f3af1c2d251f89b4fcafa5df3f05e97b89db18d7c9bdf5731bb27a",
+}
+
+BATS_CORE_TEMPLATE = """\
+load("@local_config_platform//:constraints.bzl", "HOST_CONSTRAINTS")
+load("@aspect_bazel_lib//lib/private:bats_toolchain.bzl", "bats_toolchain")
+load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
+
+copy_to_directory(
+ name = "core",
+ hardlink = "on",
+ srcs = glob([
+ "lib/**",
+ "libexec/**"
+ ]) + ["bin/bats"],
+ out = "bats-core",
+)
+
+bats_toolchain(
+ name = "toolchain",
+ core = ":core",
+ libraries = {libraries}
+)
+
+toolchain(
+ name = "bats_toolchain",
+ exec_compatible_with = HOST_CONSTRAINTS,
+ toolchain = ":toolchain",
+ toolchain_type = "@aspect_bazel_lib//lib:bats_toolchain_type",
+)
+"""
+
+BATS_LIBRARY_TEMPLATE = """\
+load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
+
+copy_to_directory(
+ name = "{name}",
+ hardlink = "on",
+ srcs = glob([
+ "src/**",
+ "load.bash",
+ ]),
+ out = "bats-{name}",
+ visibility = ["//visibility:public"]
+)
+"""
+
+BatsInfo = provider(
+ doc = "Provide info for executing bats",
+ fields = {
+ "core": "bats executable",
+ "libraries": "bats helper libraries",
+ },
+)
+
+def _bats_toolchain_impl(ctx):
+ core = ctx.file.core
+
+ default_info = DefaultInfo(
+ files = depset(ctx.files.core + ctx.files.libraries),
+ runfiles = ctx.runfiles(ctx.files.core + ctx.files.libraries),
+ )
+
+ batsinfo = BatsInfo(
+ core = core,
+ libraries = ctx.files.libraries,
+ )
+
+ # Export all the providers inside our ToolchainInfo
+ # so the resolved_toolchain rule can grab and re-export them.
+ toolchain_info = platform_common.ToolchainInfo(
+ batsinfo = batsinfo,
+ default = default_info,
+ )
+
+ return [toolchain_info, default_info]
+
+bats_toolchain = rule(
+ implementation = _bats_toolchain_impl,
+ attrs = {
+ "core": attr.label(
+ doc = "Label to the bats executable",
+ allow_single_file = True,
+ mandatory = True,
+ ),
+ "libraries": attr.label_list(),
+ },
+)
diff --git a/lib/repositories.bzl b/lib/repositories.bzl
index ec577db..b108961 100644
--- a/lib/repositories.bzl
+++ b/lib/repositories.bzl
@@ -1,6 +1,7 @@
"Macros for loading dependencies and registering toolchains"
load("//lib:utils.bzl", http_archive = "maybe_http_archive")
+load("//lib/private:bats_toolchain.bzl", "BATS_ASSERT_VERSIONS", "BATS_CORE_TEMPLATE", "BATS_CORE_VERSIONS", "BATS_FILE_VERSIONS", "BATS_LIBRARY_TEMPLATE", "BATS_SUPPORT_VERSIONS")
load("//lib/private:copy_directory_toolchain.bzl", "COPY_DIRECTORY_PLATFORMS", "copy_directory_platform_repo", "copy_directory_toolchains_repo")
load("//lib/private:copy_to_directory_toolchain.bzl", "COPY_TO_DIRECTORY_PLATFORMS", "copy_to_directory_platform_repo", "copy_to_directory_toolchains_repo")
load("//lib/private:coreutils_toolchain.bzl", "COREUTILS_PLATFORMS", "coreutils_platform_repo", "coreutils_toolchains_repo", _DEFAULT_COREUTILS_VERSION = "DEFAULT_COREUTILS_VERSION")
@@ -103,6 +104,81 @@ def register_tar_toolchains(name = DEFAULT_TAR_REPOSITORY, register = True):
user_repository_name = name,
)
+DEFAULT_BATS_REPOSITORY = "bats"
+
+DEFAULT_BATS_CORE_VERSION = "v1.10.0"
+DEFAULT_BATS_SUPPORT_VERSION = "v0.3.0"
+DEFAULT_BATS_ASSERT_VERSION = "v2.1.0"
+DEFAULT_BATS_FILE_VERSION = "v0.4.0"
+
+def register_bats_toolchains(
+ name = DEFAULT_BATS_REPOSITORY,
+ core_version = DEFAULT_BATS_CORE_VERSION,
+ support_version = DEFAULT_BATS_SUPPORT_VERSION,
+ assert_version = DEFAULT_BATS_ASSERT_VERSION,
+ file_version = DEFAULT_BATS_FILE_VERSION,
+ libraries = [],
+ register = True):
+ """Registers bats toolchain and repositories
+
+ Args:
+ name: override the prefix for the generated toolchain repositories
+ core_version: bats-core version to use
+ support_version: bats-support version to use
+ assert_version: bats-assert version to use
+ file_version: bats-file version to use
+ libraries: additional labels for libraries
+ register: whether to call through to native.register_toolchains.
+ Should be True for WORKSPACE users, but false when used under bzlmod extension
+ """
+
+ http_archive(
+ name = "%s_support" % name,
+ sha256 = BATS_SUPPORT_VERSIONS[support_version],
+ urls = [
+ "https://github.com/bats-core/bats-support/archive/{}.tar.gz".format(support_version),
+ ],
+ strip_prefix = "bats-support-{}".format(support_version.removeprefix("v")),
+ build_file_content = BATS_LIBRARY_TEMPLATE.format(name = "support"),
+ )
+
+ http_archive(
+ name = "%s_assert" % name,
+ sha256 = BATS_ASSERT_VERSIONS[assert_version],
+ urls = [
+ "https://github.com/bats-core/bats-assert/archive/{}.tar.gz".format(assert_version),
+ ],
+ strip_prefix = "bats-assert-{}".format(assert_version.removeprefix("v")),
+ build_file_content = BATS_LIBRARY_TEMPLATE.format(name = "assert"),
+ )
+
+ http_archive(
+ name = "%s_file" % name,
+ sha256 = BATS_FILE_VERSIONS[file_version],
+ urls = [
+ "https://github.com/bats-core/bats-file/archive/{}.tar.gz".format(file_version),
+ ],
+ strip_prefix = "bats-file-{}".format(file_version.removeprefix("v")),
+ build_file_content = BATS_LIBRARY_TEMPLATE.format(name = "file"),
+ )
+
+ http_archive(
+ name = "%s_toolchains" % name,
+ sha256 = BATS_CORE_VERSIONS[core_version],
+ urls = [
+ "https://github.com/bats-core/bats-core/archive/{}.tar.gz".format(core_version),
+ ],
+ strip_prefix = "bats-core-{}".format(core_version.removeprefix("v")),
+ build_file_content = BATS_CORE_TEMPLATE.format(libraries = [
+ "@%s_support//:support" % name,
+ "@%s_assert//:assert" % name,
+ "@%s_file//:file" % name,
+ ] + libraries),
+ )
+
+ if register:
+ native.register_toolchains("@%s_toolchains//:bats_toolchain" % name)
+
DEFAULT_COREUTILS_REPOSITORY = "coreutils"
DEFAULT_COREUTILS_VERSION = _DEFAULT_COREUTILS_VERSION
@@ -248,3 +324,4 @@ def aspect_bazel_lib_register_toolchains():
register_jq_toolchains()
register_yq_toolchains()
register_tar_toolchains()
+ register_bats_toolchains()
diff --git a/lib/tests/bats/BUILD.bazel b/lib/tests/bats/BUILD.bazel
new file mode 100644
index 0000000..32743c1
--- /dev/null
+++ b/lib/tests/bats/BUILD.bazel
@@ -0,0 +1,56 @@
+load("//lib:bats.bzl", "bats_test")
+
+bats_test(
+ name = "basic",
+ size = "small",
+ srcs = [
+ "basic.bats",
+ ],
+)
+
+bats_test(
+ name = "env",
+ size = "small",
+ srcs = [
+ "env.bats",
+ ],
+ env = {
+ "USE_BAZEL_VERSION": "latest",
+ },
+)
+
+bats_test(
+ name = "args",
+ size = "small",
+ srcs = [
+ "basic.bats",
+ ],
+ args = ["--timing"],
+)
+
+bats_test(
+ name = "env_expansion",
+ size = "small",
+ srcs = [
+ "env_expansion.bats",
+ ],
+ data = [
+ "data.bin",
+ ],
+ env = {
+ "DATA_PATH": "$(location :data.bin)",
+ },
+)
+
+bats_test(
+ name = "additional_lib",
+ size = "small",
+ srcs = [
+ "additional_lib.bats",
+ ],
+ target_compatible_with = select({
+ # TODO(thesayyn): incompatible with bzlmod
+ "@aspect_bazel_lib//lib:bzlmod": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ }),
+)
diff --git a/lib/tests/bats/additional_lib.bats b/lib/tests/bats/additional_lib.bats
new file mode 100644
index 0000000..0d0034e
--- /dev/null
+++ b/lib/tests/bats/additional_lib.bats
@@ -0,0 +1,8 @@
+bats_load_library 'bats-support'
+bats_load_library 'bats-assert'
+bats_load_library 'bats-custom'
+
+@test 'env' {
+ custom_test_fn
+}
+
diff --git a/lib/tests/bats/basic.bats b/lib/tests/bats/basic.bats
new file mode 100644
index 0000000..ded6a23
--- /dev/null
+++ b/lib/tests/bats/basic.bats
@@ -0,0 +1,8 @@
+bats_load_library 'bats-support'
+bats_load_library 'bats-assert'
+
+@test 'assert_output() check for existence' {
+ run echo 'have'
+ assert_output 'have'
+}
+
diff --git a/lib/tests/bats/bats-custom/BUILD.bazel b/lib/tests/bats/bats-custom/BUILD.bazel
new file mode 100644
index 0000000..be81fe6
--- /dev/null
+++ b/lib/tests/bats/bats-custom/BUILD.bazel
@@ -0,0 +1,10 @@
+load("@aspect_bazel_lib//lib:copy_to_directory.bzl", "copy_to_directory")
+
+copy_to_directory(
+ name = "custom",
+ srcs = [
+ "load.bash",
+ ],
+ out = "bats-custom",
+ visibility = ["//visibility:public"],
+)
diff --git a/lib/tests/bats/bats-custom/load.bash b/lib/tests/bats/bats-custom/load.bash
new file mode 100755
index 0000000..ae1c2af
--- /dev/null
+++ b/lib/tests/bats/bats-custom/load.bash
@@ -0,0 +1,3 @@
+custom_test_fn() {
+ :
+}
diff --git a/lib/tests/bats/data.bin b/lib/tests/bats/data.bin
new file mode 100644
index 0000000..e69de29
diff --git a/lib/tests/bats/env.bats b/lib/tests/bats/env.bats
new file mode 100644
index 0000000..c5f8689
--- /dev/null
+++ b/lib/tests/bats/env.bats
@@ -0,0 +1,8 @@
+bats_load_library 'bats-support'
+bats_load_library 'bats-assert'
+
+@test 'env' {
+ run echo $USE_BAZEL_VERSION
+ assert_output 'latest'
+}
+
diff --git a/lib/tests/bats/env_expansion.bats b/lib/tests/bats/env_expansion.bats
new file mode 100644
index 0000000..b9b55bd
--- /dev/null
+++ b/lib/tests/bats/env_expansion.bats
@@ -0,0 +1,10 @@
+bats_load_library 'bats-support'
+bats_load_library 'bats-assert'
+bats_load_library 'bats-file'
+
+@test 'env expansion' {
+ run echo $DATA_PATH
+ assert_output 'lib/tests/bats/data.bin'
+ assert_file_exists 'lib/tests/bats/data.bin'
+}
+