feat: proper windows support

This commit is contained in:
eric
2026-03-15 11:04:44 +01:00
parent 4f8e27cd74
commit 626a6640f8
70 changed files with 3410 additions and 1689 deletions

View File

@@ -1,5 +1,5 @@
load("//bun:defs.bzl", "bun_binary")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//bun:defs.bzl", "bun_binary")
bun_binary(
name = "hello_js_bin",
@@ -8,8 +8,12 @@ bun_binary(
sh_test(
name = "bun_binary_js_test",
size = "small",
srcs = ["run_binary.sh"],
args = ["$(location :hello_js_bin)", "hello-js"],
args = [
"$(location :hello_js_bin)",
"hello-js",
],
data = [":hello_js_bin"],
)
@@ -20,19 +24,24 @@ bun_binary(
sh_test(
name = "bun_binary_ts_test",
size = "small",
srcs = ["run_binary.sh"],
args = ["$(location :hello_ts_bin)", "hello-ts"],
args = [
"$(location :hello_ts_bin)",
"hello-ts",
],
data = [":hello_ts_bin"],
)
bun_binary(
name = "hello_js_with_data_bin",
entry_point = "hello.js",
data = ["payload.txt"],
entry_point = "hello.js",
)
sh_test(
name = "bun_binary_data_test",
size = "small",
srcs = ["verify_data_shape.sh"],
args = [
"$(location //internal:bun_binary.bzl)",
@@ -46,13 +55,14 @@ sh_test(
bun_binary(
name = "env_cwd_bin",
entry_point = "env.ts",
data = [".env"],
entry_point = "env.ts",
working_dir = "entry_point",
)
sh_test(
name = "bun_binary_env_cwd_test",
size = "small",
srcs = ["run_env_binary.sh"],
args = ["$(location :env_cwd_bin)"],
data = [":env_cwd_bin"],
@@ -60,13 +70,14 @@ sh_test(
bun_binary(
name = "env_parent_cwd_bin",
entry_point = "env_parent/src/main.ts",
data = ["env_parent/.env"],
entry_point = "env_parent/src/main.ts",
working_dir = "entry_point",
)
sh_test(
name = "bun_binary_env_parent_cwd_test",
size = "small",
srcs = ["run_parent_env_binary.sh"],
args = ["$(location :env_parent_cwd_bin)"],
data = [":env_parent_cwd_bin"],
@@ -74,14 +85,18 @@ sh_test(
bun_binary(
name = "runtime_flag_bin",
args = [
"one",
"two",
],
entry_point = "flag_probe.ts",
args = ["one", "two"],
preload = ["preload.ts"],
env_files = ["runtime.env"],
preload = ["preload.ts"],
)
sh_test(
name = "bun_binary_runtime_flags_test",
size = "small",
srcs = ["run_flag_binary.sh"],
args = ["$(location :runtime_flag_bin)"],
data = [":runtime_flag_bin"],
@@ -89,6 +104,7 @@ sh_test(
sh_test(
name = "bun_binary_runtime_flags_shape_test",
size = "small",
srcs = ["verify_runtime_flags_shape.sh"],
args = ["$(location :runtime_flag_bin)"],
data = [":runtime_flag_bin"],
@@ -96,24 +112,52 @@ sh_test(
bun_binary(
name = "configured_launcher_bin",
entry_point = "hello.ts",
node_modules = "@script_test_vite_node_modules//:node_modules",
smol = True,
conditions = [
"browser",
"development",
],
entry_point = "hello.ts",
inherit_host_path = True,
install_mode = "force",
node_modules = "@script_test_vite_node_modules//:node_modules",
run_flags = [
"--hot",
"--console-depth",
"4",
],
smol = True,
visibility = ["//tests/ci_test:__pkg__"],
)
sh_test(
name = "bun_binary_configured_launcher_shape_test",
size = "small",
srcs = ["verify_configured_launcher_shape.sh"],
args = ["$(location :configured_launcher_bin)"],
data = [":configured_launcher_bin"],
)
bun_binary(
name = "path_default_bin",
entry_point = "path_probe.ts",
)
bun_binary(
name = "path_inherit_bin",
entry_point = "path_probe.ts",
inherit_host_path = True,
)
sh_test(
name = "bun_binary_host_path_test",
size = "small",
srcs = ["run_path_binary.sh"],
args = [
"$(location :path_default_bin)",
"$(location :path_inherit_bin)",
],
data = [
":path_default_bin",
":path_inherit_bin",
],
)

View File

@@ -0,0 +1,5 @@
const pathValue = process.env.PATH ?? "";
console.log(JSON.stringify({
hasHostSentinel: pathValue.includes("rules_bun_host_path_sentinel"),
}));

View File

@@ -3,7 +3,23 @@ set -euo pipefail
binary="$1"
expected="$2"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "${expected}" ]]; then
echo "Unexpected output from ${binary}: ${output}" >&2

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "from-dotenv" ]]; then
echo "Expected .env value from entry-point directory, got: ${output}" >&2

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
expected='{"preloaded":"yes","env":"from-env-file","argv":["one","two"]}'

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "from-parent-dotenv" ]]; then
echo "Expected .env value from parent directory, got: ${output}" >&2

View File

@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail
default_binary="$1"
inherit_binary="$2"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
env PATH="rules_bun_host_path_sentinel:${PATH:-}" cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
env PATH="rules_bun_host_path_sentinel:${PATH:-}" "${launcher}" "$@"
}
default_output="$(run_launcher "${default_binary}")"
inherit_output="$(run_launcher "${inherit_binary}")"
if [[ ${default_output} != '{"hasHostSentinel":false}' ]]; then
echo "Expected default launcher to hide host PATH, got: ${default_output}" >&2
exit 1
fi
if [[ ${inherit_output} != '{"hasHostSentinel":true}' ]]; then
echo "Expected inherit_host_path launcher to preserve host PATH, got: ${inherit_output}" >&2
exit 1
fi

View File

@@ -1,16 +1,23 @@
#!/usr/bin/env bash
set -euo pipefail
binary="$1"
launcher="$1"
grep -Fq -- 'install_metadata="${runfiles_dir}/_main/' "${binary}"
grep -Fq -- 'node_modules/.rules_bun/install.json' "${binary}"
grep -Fq -- "--smol" "${binary}"
grep -Fq -- "--conditions" "${binary}"
grep -Fq -- "'browser'" "${binary}"
grep -Fq -- "'development'" "${binary}"
grep -Fq -- "--install" "${binary}"
grep -Fq -- "'force'" "${binary}"
grep -Fq -- "'--hot'" "${binary}"
grep -Fq -- "'--console-depth'" "${binary}"
grep -Fq -- "'4'" "${binary}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
argv = spec["argv"]
assert spec["install_metadata_short_path"].endswith("node_modules/.rules_bun/install.json"), spec
assert spec["inherit_host_path"] is True, spec
assert spec["node_modules_roots"], spec
assert all(not root.startswith("../") for root in spec["node_modules_roots"]), spec
for value in ["--smol", "--conditions", "browser", "development", "--install", "force", "--hot", "--console-depth", "4"]:
assert value in argv, (value, spec)
PY

View File

@@ -1,8 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
binary="$1"
launcher="$1"
grep -Fq -- '--no-install' "${binary}"
grep -Fq -- '--preload' "${binary}"
grep -Fq -- '--env-file' "${binary}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
assert "--no-install" in spec["argv"], spec
assert spec["inherit_host_path"] is False, spec
assert spec["preload_short_paths"] and spec["preload_short_paths"][0].endswith("tests/binary_test/preload.ts"), spec
assert spec["env_file_short_paths"] and spec["env_file_short_paths"][0].endswith("tests/binary_test/runtime.env"), spec
PY

View File

@@ -3,42 +3,62 @@ load("//bun:defs.bzl", "bun_test")
bun_test(
name = "passing_suite",
size = "small",
srcs = ["passing.test.ts"],
)
bun_test(
name = "failing_suite",
size = "small",
srcs = ["failing.test.ts"],
)
bun_test(
name = "configured_suite",
size = "small",
srcs = ["passing.test.ts"],
preload = ["preload.ts"],
env_files = ["test.env"],
no_env_file = True,
timeout_ms = 250,
update_snapshots = True,
rerun_each = 2,
concurrent = True,
randomize = True,
seed = 7,
bail = 1,
reporter = "junit",
max_concurrency = 4,
concurrent = True,
coverage = True,
coverage_reporters = ["lcov"],
env_files = ["test.env"],
max_concurrency = 4,
no_env_file = True,
preload = ["preload.ts"],
randomize = True,
reporter = "junit",
rerun_each = 2,
seed = 7,
test_flags = ["--only-failures"],
timeout_ms = 250,
update_snapshots = True,
visibility = ["//tests/ci_test:__pkg__"],
)
bun_test(
name = "configured_retry_suite",
size = "small",
srcs = ["passing.test.ts"],
retry = 3,
)
sh_test(
name = "bun_test_configured_suite_shape_test",
size = "small",
srcs = ["configured_suite_shape.sh"],
args = [
"$(location :configured_suite)",
"$(location :configured_retry_suite)",
],
data = [
":configured_retry_suite",
":configured_suite",
],
)
sh_test(
name = "bun_test_failing_suite_test",
size = "small",
srcs = ["failing_suite_shape.sh"],
args = ["$(location //tests/bun_test_test:BUILD.bazel)"],
data = ["//tests/bun_test_test:BUILD.bazel"],
@@ -46,34 +66,24 @@ sh_test(
sh_test(
name = "bun_test_cache_hit_test",
size = "small",
srcs = ["cache_hit_shape.sh"],
args = ["$(location //internal:bun_test.bzl)"],
data = ["//internal:bun_test.bzl"],
args = ["$(location :passing_suite)"],
data = [":passing_suite"],
)
sh_test(
name = "bun_test_cache_miss_test",
size = "small",
srcs = ["cache_miss_shape.sh"],
args = ["$(location //internal:bun_test.bzl)"],
data = ["//internal:bun_test.bzl"],
args = ["$(location :configured_suite)"],
data = [":configured_suite"],
)
sh_test(
name = "bun_test_junit_output_test",
size = "small",
srcs = ["junit_shape.sh"],
args = ["$(location //internal:bun_test.bzl)"],
data = ["//internal:bun_test.bzl"],
)
sh_test(
name = "bun_test_configured_suite_shape_test",
srcs = ["configured_suite_shape.sh"],
args = [
"$(location :configured_suite)",
"$(location :configured_retry_suite)",
],
data = [
":configured_suite",
":configured_retry_suite",
],
args = ["$(location :configured_suite)"],
data = [":configured_suite"],
)

View File

@@ -1,7 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail
rule_file="$1"
launcher="$1"
grep -Fq 'launcher_lines = [render_shell_array("bun_args", ["--bun", "test"])]' "${rule_file}"
grep -Fq 'exec "${bun_bin}" "${bun_args[@]}" "$@"' "${rule_file}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
assert spec["kind"] == "bun_test", spec
assert spec["argv"][:2] == ["--bun", "test"], spec
assert spec["test_short_paths"], spec
PY

View File

@@ -1,8 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
rule_file="$1"
launcher="$1"
grep -Fq 'extra_files = ctx.files.srcs + ctx.files.data + ctx.files.preload + ctx.files.env_files + [bun_bin]' "${rule_file}"
grep -Eq '"srcs": attr\.label_list\(' "${rule_file}"
grep -Eq '"coverage": attr\.bool\(' "${rule_file}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
assert spec["coverage"] is True, spec
assert spec["preload_short_paths"], spec
assert spec["env_file_short_paths"], spec
assert spec["test_short_paths"], spec
PY

View File

@@ -4,21 +4,39 @@ set -euo pipefail
launcher="$1"
retry_launcher="$2"
grep -Fq -- '--no-install' "${launcher}"
grep -Fq -- '--preload' "${launcher}"
grep -Fq -- '--env-file' "${launcher}"
grep -Fq -- '--no-env-file' "${launcher}"
grep -Fq -- '--timeout' "${launcher}"
grep -Fq -- '--update-snapshots' "${launcher}"
grep -Fq -- '--rerun-each' "${launcher}"
grep -Fq -- '--concurrent' "${launcher}"
grep -Fq -- '--randomize' "${launcher}"
grep -Fq -- '--seed' "${launcher}"
grep -Fq -- '--bail' "${launcher}"
grep -Fq -- '--max-concurrency' "${launcher}"
grep -Fq -- '--reporter' "${launcher}"
grep -Fq -- '--reporter-outfile' "${launcher}"
grep -Fq -- '--coverage' "${launcher}"
grep -Fq -- '--coverage-dir' "${launcher}"
grep -Fq -- '--coverage-reporter' "${launcher}"
grep -Fq -- '--retry' "${retry_launcher}"
python3 - "${launcher}" "${retry_launcher}" <<'PY'
import json
import pathlib
import sys
def read_spec(launcher: str):
path = pathlib.Path(launcher)
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
return json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
launcher_spec = read_spec(sys.argv[1])
retry_spec = read_spec(sys.argv[2])
for value in [
"--no-install",
"--no-env-file",
"--timeout",
"--update-snapshots",
"--rerun-each",
"--concurrent",
"--randomize",
"--seed",
"--bail",
"--max-concurrency",
]:
assert value in launcher_spec["argv"], (value, launcher_spec)
assert launcher_spec["preload_short_paths"], launcher_spec
assert launcher_spec["env_file_short_paths"], launcher_spec
assert launcher_spec["reporter"] == "junit", launcher_spec
assert launcher_spec["coverage"] is True, launcher_spec
assert launcher_spec["coverage_reporters"] == ["lcov"], launcher_spec
assert "--retry" in retry_spec["argv"], retry_spec
assert "3" in retry_spec["argv"], retry_spec
PY

View File

@@ -1,7 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail
rule_file="$1"
launcher="$1"
grep -Fq 'reporter_out="${XML_OUTPUT_FILE:-${runtime_workspace}/junit.xml}"' "${rule_file}"
grep -Fq 'bun_args+=("--reporter" "junit" "--reporter-outfile" "${reporter_out}")' "${rule_file}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
assert spec["reporter"] == "junit", spec
PY

View File

@@ -1,5 +1,5 @@
load("//bun:defs.bzl", "bun_build", "bun_bundle", "bun_compile")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//bun:defs.bzl", "bun_build", "bun_bundle", "bun_compile")
bun_bundle(
name = "simple_bundle",
@@ -18,64 +18,53 @@ bun_bundle(
external = ["left-pad"],
)
bun_bundle(
name = "collision_bundle",
entry_points = [
"collision_case/a/main.ts",
"collision_case/b/main.ts",
],
)
bun_build(
name = "site_build",
entry_points = ["site/index.html"],
data = [
"site/main.ts",
"site/styles.css",
],
entry_points = ["site/index.html"],
splitting = True,
)
bun_build(
name = "site_build_with_meta",
entry_points = ["site/index.html"],
data = [
"site/main.ts",
"site/styles.css",
],
entry_points = ["site/index.html"],
metafile = True,
metafile_md = True,
)
bun_build(
name = "advanced_site_build",
tags = ["manual"],
entry_points = ["site/index.html"],
data = [
"site/main.ts",
"site/styles.css",
],
install_mode = "fallback",
target = "node",
format = "cjs",
production = True,
splitting = True,
root = "tests/bundle_test/site",
sourcemap = "linked",
banner = "/* bundle banner */",
footer = "// bundle footer",
public_path = "/static/",
packages = "external",
external = [
"left-pad",
"react",
],
entry_naming = "entries/[name]-[hash].[ext]",
chunk_naming = "chunks/[name]-[hash].[ext]",
asset_naming = "assets/[name]-[hash].[ext]",
minify = True,
minify_syntax = True,
minify_whitespace = True,
minify_identifiers = True,
keep_names = True,
css_chunking = True,
banner = "/* bundle banner */",
build_flags = [
"--app",
"--server-components",
],
chunk_naming = "chunks/[name]-[hash].[ext]",
conditions = [
"browser",
"custom",
],
env = "PUBLIC_*",
css_chunking = True,
data = [
"site/main.ts",
"site/styles.css",
],
define = [
"process.env.NODE_ENV:\"production\"",
"__DEV__:false",
@@ -84,26 +73,44 @@ bun_build(
"console",
"debugger",
],
emit_dce_annotations = True,
entry_naming = "entries/[name]-[hash].[ext]",
entry_points = ["site/index.html"],
env = "PUBLIC_*",
external = [
"left-pad",
"react",
],
feature = [
"react_fast_refresh",
"server_components",
],
loader = [
".svg:file",
".txt:text",
],
footer = "// bundle footer",
format = "cjs",
jsx_factory = "h",
jsx_fragment = "Fragment",
jsx_import_source = "preact",
jsx_runtime = "automatic",
jsx_side_effects = True,
react_fast_refresh = True,
emit_dce_annotations = True,
no_bundle = True,
build_flags = [
"--app",
"--server-components",
keep_names = True,
loader = [
".svg:file",
".txt:text",
],
minify = True,
minify_identifiers = True,
minify_syntax = True,
minify_whitespace = True,
no_bundle = True,
packages = "external",
production = True,
public_path = "/static/",
react_fast_refresh = True,
root = "tests/bundle_test/site",
sourcemap = "linked",
splitting = True,
tags = ["manual"],
target = "node",
)
bun_compile(
@@ -113,29 +120,30 @@ bun_compile(
bun_compile(
name = "compiled_cli_with_flags",
tags = ["manual"],
entry_point = "cli.ts",
bytecode = True,
compile_autoload_bunfig = False,
compile_autoload_dotenv = False,
compile_autoload_package_json = True,
compile_autoload_tsconfig = True,
compile_exec_argv = [
"--smol",
"--inspect-wait",
],
compile_executable = "fake_cross_bun.bin",
compile_autoload_dotenv = False,
compile_autoload_bunfig = False,
compile_autoload_tsconfig = True,
compile_autoload_package_json = True,
entry_point = "cli.ts",
tags = ["manual"],
windows_copyright = "(c) rules_bun",
windows_description = "compile flag coverage",
windows_hide_console = True,
windows_icon = "branding/icon.ico",
windows_title = "Rules Bun Test App",
windows_publisher = "rules_bun",
windows_title = "Rules Bun Test App",
windows_version = "1.2.3.4",
windows_description = "compile flag coverage",
windows_copyright = "(c) rules_bun",
)
sh_test(
name = "bundle_output_test",
size = "small",
srcs = ["verify_bundle.sh"],
args = ["$(location :simple_bundle)"],
data = [":simple_bundle"],
@@ -143,19 +151,21 @@ sh_test(
sh_test(
name = "bundle_minify_test",
size = "small",
srcs = ["verify_minify.sh"],
args = [
"$(location :simple_bundle)",
"$(location :minified_bundle)",
],
data = [
":simple_bundle",
":minified_bundle",
":simple_bundle",
],
)
sh_test(
name = "bundle_hermetic_digest_test",
size = "small",
srcs = ["verify_hermetic_shape.sh"],
args = ["$(location //internal:bun_bundle.bzl)"],
data = ["//internal:bun_bundle.bzl"],
@@ -163,6 +173,7 @@ sh_test(
sh_test(
name = "bundle_external_exclusion_test",
size = "small",
srcs = ["verify_external_shape.sh"],
args = [
"$(location //internal:bun_bundle.bzl)",
@@ -174,22 +185,32 @@ sh_test(
],
)
sh_test(
name = "bundle_collision_output_test",
size = "small",
srcs = ["verify_collision_outputs.sh"],
args = ["$(locations :collision_bundle)"],
data = [":collision_bundle"],
)
sh_test(
name = "bundle_sourcemap_shape_test",
size = "small",
srcs = ["verify_sourcemap_shape.sh"],
env_inherit = ["PATH"],
data = [
"BUILD.bazel",
"//:repo_runtime_files",
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
"BUILD.bazel",
"//tests/bundle_test/sourcemap_case:BUILD.bazel",
"//tests/bundle_test/sourcemap_case:entry.ts",
],
env_inherit = ["PATH"],
)
sh_test(
name = "bun_build_site_output_test",
size = "small",
srcs = ["verify_site_build.sh"],
args = ["$(location :site_build)"],
data = [":site_build"],
@@ -197,6 +218,7 @@ sh_test(
sh_test(
name = "bun_build_site_meta_test",
size = "small",
srcs = ["verify_site_build_meta.sh"],
args = ["$(locations :site_build_with_meta)"],
data = [":site_build_with_meta"],
@@ -204,6 +226,7 @@ sh_test(
sh_test(
name = "bun_compile_output_test",
size = "small",
srcs = ["run_compiled_binary.sh"],
args = ["$(location :compiled_cli)"],
data = [":compiled_cli"],
@@ -211,17 +234,18 @@ sh_test(
sh_test(
name = "bun_build_compile_flag_shape_test",
size = "small",
srcs = ["verify_flag_aquery.sh"],
env_inherit = ["PATH"],
data = [
"//:repo_runtime_files",
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
"BUILD.bazel",
"cli.ts",
"fake_cross_bun.bin",
"site/index.html",
"site/main.ts",
"site/styles.css",
"//:repo_runtime_files",
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
],
env_inherit = ["PATH"],
)

View File

@@ -0,0 +1 @@
console.log("a");

View File

@@ -0,0 +1 @@
console.log("b");

View File

@@ -0,0 +1,25 @@
#!/usr/bin/env bash
set -euo pipefail
first_output="$1"
second_output="$2"
if [[ ${first_output} == "${second_output}" ]]; then
echo "Expected distinct bundle outputs for same-basename entry points" >&2
exit 1
fi
if [[ ! -f ${first_output} || ! -f ${second_output} ]]; then
echo "Expected both bundle outputs to exist" >&2
exit 1
fi
if [[ ${first_output} != *"collision_bundle__tests_bundle_test_collision_case_a_main.js" ]]; then
echo "Unexpected first output path: ${first_output}" >&2
exit 1
fi
if [[ ${second_output} != *"collision_bundle__tests_bundle_test_collision_case_b_main.js" ]]; then
echo "Unexpected second output path: ${second_output}" >&2
exit 1
fi

View File

@@ -68,8 +68,6 @@ expect_line() {
build_output="$(run_aquery "BunBuild" "//tests/bundle_test:advanced_site_build")"
for expected in \
'arguments: "--install"' \
'arguments: "fallback"' \
'arguments: "--target"' \
'arguments: "node"' \
'arguments: "--format"' \

View File

@@ -4,6 +4,6 @@ set -euo pipefail
rule_file="$1"
grep -Fq 'def _output_name(target_name, entry):' "${rule_file}"
grep -Fq 'return "{}__{}.js".format(target_name, stem)' "${rule_file}"
grep -Fq 'inputs = depset(' "${rule_file}"
grep -Fq 'direct = [entry] + ctx.files.data' "${rule_file}"
grep -Fq 'stem = entry.short_path.rsplit(".", 1)[0]' "${rule_file}"
grep -Fq 'validate_hermetic_install_mode(ctx.attr, "bun_bundle")' "${rule_file}"
grep -Fq 'declare_staged_bun_build_action(' "${rule_file}"

View File

@@ -2,7 +2,26 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test")
sh_test(
name = "phase8_ci_matrix_shape_test",
size = "small",
srcs = ["phase8_ci_matrix_shape_test.sh"],
args = ["$(location //.github/workflows:ci.yml)"],
data = ["//.github/workflows:ci.yml"],
)
sh_test(
name = "native_wrapper_shape_test",
size = "small",
srcs = ["verify_native_wrapper_shape.sh"],
args = [
"$(location //tests/binary_test:configured_launcher_bin)",
"$(location //tests/script_test:workspace_flagged_script)",
"$(location //tests/js_compat_test:compat_devserver)",
"$(location //tests/bun_test_test:configured_suite)",
],
data = [
"//tests/binary_test:configured_launcher_bin",
"//tests/bun_test_test:configured_suite",
"//tests/js_compat_test:compat_devserver",
"//tests/script_test:workspace_flagged_script",
],
)

View File

@@ -0,0 +1,17 @@
#!/usr/bin/env bash
set -euo pipefail
python3 - "$@" <<'PY'
import pathlib
import sys
windows = sys.platform.startswith("win")
for launcher in sys.argv[1:]:
suffix = pathlib.Path(launcher).suffix.lower()
if windows:
if suffix != ".cmd":
raise SystemExit(f"expected .cmd launcher on Windows: {launcher}")
elif suffix == ".sh":
raise SystemExit(f"unexpected .sh launcher executable: {launcher}")
PY

View File

@@ -2,6 +2,7 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test")
sh_test(
name = "bun_install_extension_shape_test",
size = "small",
srcs = ["extension_shape_test.sh"],
args = ["$(location //bun:extensions.bzl)"],
data = ["//bun:extensions.bzl"],
@@ -9,6 +10,7 @@ sh_test(
sh_test(
name = "npm_translate_lock_extension_shape_test",
size = "small",
srcs = ["npm_extension_shape_test.sh"],
args = ["$(location //npm:extensions.bzl)"],
data = ["//npm:extensions.bzl"],

View File

@@ -10,3 +10,4 @@ grep -Eq '"package_json":[[:space:]]*attr\.label\(mandatory[[:space:]]*=[[:space
grep -Eq '"bun_lockfile":[[:space:]]*attr\.label\(mandatory[[:space:]]*=[[:space:]]*True\)' "${extension_file}"
grep -Eq '"install_inputs":[[:space:]]*attr\.label_list\(allow_files[[:space:]]*=[[:space:]]*True\)' "${extension_file}"
grep -Eq '"isolated_home":[[:space:]]*attr\.bool\(default[[:space:]]*=[[:space:]]*True\)' "${extension_file}"
grep -Eq '"ignore_scripts":[[:space:]]*attr\.bool\(default[[:space:]]*=[[:space:]]*True\)' "${extension_file}"

View File

@@ -34,6 +34,7 @@ config_setting(
sh_test(
name = "bun_install_clean_install_test",
size = "small",
srcs = ["clean_install.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
@@ -53,6 +54,7 @@ sh_test(
sh_test(
name = "bun_install_stale_lockfile_test",
size = "small",
srcs = ["stale_lockfile.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
@@ -72,6 +74,7 @@ sh_test(
sh_test(
name = "bun_install_determinism_test",
size = "small",
srcs = ["determinism.sh"],
args = ["$(location //internal:bun_install.bzl)"],
data = ["//internal:bun_install.bzl"],
@@ -79,6 +82,7 @@ sh_test(
sh_test(
name = "bun_install_environment_shape_test",
size = "small",
srcs = ["environment_shape.sh"],
args = ["$(location //internal:bun_install.bzl)"],
data = ["//internal:bun_install.bzl"],
@@ -86,6 +90,7 @@ sh_test(
sh_test(
name = "bun_install_workspaces_test",
size = "small",
srcs = ["workspaces.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
@@ -105,6 +110,7 @@ sh_test(
sh_test(
name = "bun_install_workspaces_catalog_test",
size = "small",
srcs = ["workspaces_catalog.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
@@ -125,7 +131,6 @@ sh_test(
sh_test(
name = "bun_install_workspace_parity_test",
srcs = ["workspace_parity.sh"],
env_inherit = ["PATH"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"],
@@ -144,11 +149,63 @@ sh_test(
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
],
env_inherit = ["PATH"],
)
sh_test(
name = "bun_install_install_flags_shape_test",
size = "small",
srcs = ["install_flags_shape.sh"],
args = ["$(location //internal:bun_install.bzl)"],
data = ["//internal:bun_install.bzl"],
)
sh_test(
name = "bun_install_repeatability_test",
size = "small",
srcs = ["repeatability.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"],
":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"],
":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"],
"//conditions:default": ["$(location @bun_linux_x64//:bun)"],
}),
data = select({
":linux_x86_64": ["@bun_linux_x64//:bun"],
":linux_aarch64": ["@bun_linux_aarch64//:bun"],
":darwin_x86_64": ["@bun_darwin_x64//:bun"],
":darwin_aarch64": ["@bun_darwin_aarch64//:bun"],
"//conditions:default": ["@bun_linux_x64//:bun"],
}) + [
"//:repo_runtime_files",
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
],
env_inherit = ["PATH"],
)
sh_test(
name = "bun_install_lifecycle_scripts_test",
size = "small",
srcs = ["lifecycle_scripts.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"],
":darwin_x86_64": ["$(location @bun_darwin_x64//:bun)"],
":darwin_aarch64": ["$(location @bun_darwin_aarch64//:bun)"],
"//conditions:default": ["$(location @bun_linux_x64//:bun)"],
}),
data = select({
":linux_x86_64": ["@bun_linux_x64//:bun"],
":linux_aarch64": ["@bun_linux_aarch64//:bun"],
":darwin_x86_64": ["@bun_darwin_x64//:bun"],
":darwin_aarch64": ["@bun_darwin_aarch64//:bun"],
"//conditions:default": ["@bun_linux_x64//:bun"],
}) + [
"//:repo_runtime_files",
"//bun:repo_runtime_files",
"//internal:repo_runtime_files",
],
env_inherit = ["PATH"],
)

View File

@@ -0,0 +1,118 @@
#!/usr/bin/env bash
set -euo pipefail
bun_path="$1"
if command -v bazel >/dev/null 2>&1; then
bazel_cmd=(bazel)
elif command -v bazelisk >/dev/null 2>&1; then
bazel_cmd=(bazelisk)
else
echo "bazel or bazelisk is required on PATH" >&2
exit 1
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
rules_bun_root="$(cd "${script_dir}/../.." && pwd -P)"
workdir="$(mktemp -d)"
trap 'rm -rf "${workdir}"' EXIT
fixture_dir="${workdir}/fixture"
mkdir -p "${fixture_dir}"
cat >"${fixture_dir}/package.json" <<'JSON'
{
"name": "lifecycle-script-test",
"version": "1.0.0",
"dependencies": {
"is-number": "7.0.0"
},
"scripts": {
"postinstall": "bun -e \"require('node:fs').writeFileSync('postinstall.txt', 'ran')\""
}
}
JSON
"${bun_path}" install --cwd "${fixture_dir}" >/dev/null
rm -rf "${fixture_dir}/node_modules" "${fixture_dir}/postinstall.txt"
cat >"${fixture_dir}/MODULE.bazel" <<EOF
module(
name = "bun_install_lifecycle_scripts_test",
)
bazel_dep(name = "rules_bun", version = "0.2.2")
local_path_override(
module_name = "rules_bun",
path = "${rules_bun_root}",
)
bun_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun")
use_repo(
bun_ext,
"bun_darwin_aarch64",
"bun_darwin_x64",
"bun_linux_aarch64",
"bun_linux_x64",
"bun_windows_x64",
)
bun_install_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun_install")
bun_install_ext.install(
name = "scripts_blocked",
package_json = "//:package.json",
bun_lockfile = "//:bun.lock",
)
bun_install_ext.install(
name = "scripts_allowed",
package_json = "//:package.json",
bun_lockfile = "//:bun.lock",
ignore_scripts = False,
)
use_repo(
bun_install_ext,
"scripts_allowed",
"scripts_blocked",
)
register_toolchains(
"@rules_bun//bun:darwin_aarch64_toolchain",
"@rules_bun//bun:darwin_x64_toolchain",
"@rules_bun//bun:linux_aarch64_toolchain",
"@rules_bun//bun:linux_x64_toolchain",
"@rules_bun//bun:windows_x64_toolchain",
)
EOF
cat >"${fixture_dir}/BUILD.bazel" <<'EOF'
exports_files([
"package.json",
"bun.lock",
])
EOF
(
cd "${fixture_dir}"
"${bazel_cmd[@]}" build @scripts_blocked//:node_modules @scripts_allowed//:node_modules >/dev/null
)
output_base="$(cd "${fixture_dir}" && "${bazel_cmd[@]}" info output_base)"
blocked_repo="$(find "${output_base}/external" -maxdepth 1 -type d -name '*+scripts_blocked' | head -n 1)"
allowed_repo="$(find "${output_base}/external" -maxdepth 1 -type d -name '*+scripts_allowed' | head -n 1)"
if [[ -z ${blocked_repo} || -z ${allowed_repo} ]]; then
echo "Unable to locate generated lifecycle test repositories" >&2
exit 1
fi
if [[ -e "${blocked_repo}/postinstall.txt" ]]; then
echo "Lifecycle scripts should be disabled by default" >&2
exit 1
fi
if [[ ! -f "${allowed_repo}/postinstall.txt" ]]; then
echo "Lifecycle scripts should run when ignore_scripts = False" >&2
exit 1
fi

View File

@@ -0,0 +1,128 @@
#!/usr/bin/env bash
set -euo pipefail
bun_path="$1"
if command -v bazel >/dev/null 2>&1; then
bazel_cmd=(bazel)
elif command -v bazelisk >/dev/null 2>&1; then
bazel_cmd=(bazelisk)
else
echo "bazel or bazelisk is required on PATH" >&2
exit 1
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
rules_bun_root="$(cd "${script_dir}/../.." && pwd -P)"
workdir="$(mktemp -d)"
trap 'rm -rf "${workdir}"' EXIT
fixture_dir="${workdir}/fixture"
mkdir -p "${fixture_dir}"
cat >"${fixture_dir}/package.json" <<'JSON'
{
"name": "repeatability-test",
"version": "1.0.0",
"dependencies": {
"is-number": "7.0.0"
}
}
JSON
"${bun_path}" install --cwd "${fixture_dir}" >/dev/null
rm -rf "${fixture_dir}/node_modules"
cat >"${fixture_dir}/MODULE.bazel" <<EOF
module(
name = "bun_install_repeatability_test",
)
bazel_dep(name = "rules_bun", version = "0.2.2")
local_path_override(
module_name = "rules_bun",
path = "${rules_bun_root}",
)
bun_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun")
use_repo(
bun_ext,
"bun_darwin_aarch64",
"bun_darwin_x64",
"bun_linux_aarch64",
"bun_linux_x64",
"bun_windows_x64",
)
bun_install_ext = use_extension("@rules_bun//bun:extensions.bzl", "bun_install")
bun_install_ext.install(
name = "node_modules_a",
package_json = "//:package.json",
bun_lockfile = "//:bun.lock",
)
bun_install_ext.install(
name = "node_modules_b",
package_json = "//:package.json",
bun_lockfile = "//:bun.lock",
)
use_repo(
bun_install_ext,
"node_modules_a",
"node_modules_b",
)
register_toolchains(
"@rules_bun//bun:darwin_aarch64_toolchain",
"@rules_bun//bun:darwin_x64_toolchain",
"@rules_bun//bun:linux_aarch64_toolchain",
"@rules_bun//bun:linux_x64_toolchain",
"@rules_bun//bun:windows_x64_toolchain",
)
EOF
cat >"${fixture_dir}/BUILD.bazel" <<'EOF'
exports_files([
"package.json",
"bun.lock",
])
EOF
(
cd "${fixture_dir}"
"${bazel_cmd[@]}" build @node_modules_a//:node_modules @node_modules_b//:node_modules >/dev/null
)
output_base="$(cd "${fixture_dir}" && "${bazel_cmd[@]}" info output_base)"
repo_a="$(find "${output_base}/external" -maxdepth 1 -type d -name '*+node_modules_a' | head -n 1)"
repo_b="$(find "${output_base}/external" -maxdepth 1 -type d -name '*+node_modules_b' | head -n 1)"
if [[ -z ${repo_a} || -z ${repo_b} ]]; then
echo "Unable to locate generated node_modules repositories" >&2
exit 1
fi
snapshot_tree() {
local root="$1"
(
cd "${root}"
while IFS= read -r -d '' path; do
local rel="${path#./}"
if [[ -L ${path} ]]; then
local target
target="$(readlink "${path}")"
target="${target//node_modules_a/node_modules}"
target="${target//node_modules_b/node_modules}"
printf 'L %s %s\n' "${rel}" "${target}"
else
printf 'F %s %s\n' "${rel}" "$(shasum -a 256 "${path}" | awk '{print $1}')"
fi
done < <(find . \( -type f -o -type l \) -print0 | sort -z)
)
}
snapshot_tree "${repo_a}/node_modules" >"${workdir}/repo_a.snapshot"
snapshot_tree "${repo_b}/node_modules" >"${workdir}/repo_b.snapshot"
diff -u "${workdir}/repo_a.snapshot" "${workdir}/repo_b.snapshot"

View File

@@ -2,6 +2,9 @@
set -euo pipefail
bun_path="$1"
if [[ ${bun_path} != /* ]]; then
bun_path="$(cd "$(dirname "${bun_path}")" && pwd -P)/$(basename "${bun_path}")"
fi
workdir="$(mktemp -d)"
trap 'rm -rf "${workdir}"' EXIT

View File

@@ -2,6 +2,9 @@
set -euo pipefail
bun_path="$1"
if [[ ${bun_path} != /* ]]; then
bun_path="$(cd "$(dirname "${bun_path}")" && pwd -P)/$(basename "${bun_path}")"
fi
workdir="$(mktemp -d)"
trap 'rm -rf "${workdir}"' EXIT

View File

@@ -3,17 +3,18 @@ load("@rules_shell//shell:sh_test.bzl", "sh_test")
test_suite(
name = "examples_test",
tests = [
":examples_basic_run_e2e_test",
":examples_basic_hot_restart_shape_test",
":examples_workspace_bundle_e2e_test",
":examples_workspace_catalog_shape_test",
":examples_basic_run_e2e_test",
":examples_vite_monorepo_catalog_shape_test",
":examples_vite_monorepo_e2e_test",
":examples_workspace_bundle_e2e_test",
":examples_workspace_catalog_shape_test",
],
)
sh_test(
name = "examples_basic_e2e_build_test",
size = "small",
srcs = ["examples_basic_e2e_build_test.sh"],
args = [
"$(location //examples/basic:BUILD.bazel)",
@@ -27,6 +28,7 @@ sh_test(
sh_test(
name = "examples_basic_run_e2e_test",
size = "small",
srcs = ["examples_basic_run_e2e_test.sh"],
args = ["$(location //examples/basic:web_dev)"],
data = ["//examples/basic:web_dev"],
@@ -34,6 +36,7 @@ sh_test(
sh_test(
name = "examples_basic_hot_restart_shape_test",
size = "small",
srcs = ["examples_basic_hot_restart_shape_test.sh"],
args = ["$(location //examples/basic:web_dev_hot_restart)"],
data = ["//examples/basic:web_dev_hot_restart"],
@@ -41,6 +44,7 @@ sh_test(
sh_test(
name = "examples_workspace_bundle_e2e_test",
size = "small",
srcs = ["examples_workspace_bundle_e2e_test.sh"],
args = ["$(location //examples/workspace:pkg_b_bundle)"],
data = ["//examples/workspace:pkg_b_bundle"],
@@ -48,6 +52,7 @@ sh_test(
sh_test(
name = "examples_workspace_catalog_shape_test",
size = "small",
srcs = ["examples_workspace_catalog_shape_test.sh"],
args = [
"$(location //examples/workspace:package.json)",
@@ -63,6 +68,7 @@ sh_test(
sh_test(
name = "examples_vite_monorepo_catalog_shape_test",
size = "small",
srcs = ["examples_vite_monorepo_catalog_shape_test.sh"],
args = [
"$(location //examples/vite_monorepo:package.json)",
@@ -70,14 +76,15 @@ sh_test(
"$(location //examples/vite_monorepo:apps/app-b/package.json)",
],
data = [
"//examples/vite_monorepo:package.json",
"//examples/vite_monorepo:apps/app-a/package.json",
"//examples/vite_monorepo:apps/app-b/package.json",
"//examples/vite_monorepo:package.json",
],
)
sh_test(
name = "examples_vite_monorepo_e2e_test",
size = "small",
srcs = ["examples_vite_monorepo_e2e_test.sh"],
args = [
"$(location //examples/vite_monorepo:app_a_dev)",
@@ -91,6 +98,7 @@ sh_test(
sh_test(
name = "repo_all_targets_test",
size = "small",
srcs = ["repo_all_targets_test.sh"],
args = ["$(location //.github/workflows:ci.yml)"],
data = ["//.github/workflows:ci.yml"],

View File

@@ -1,11 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
binary="$1"
launcher="$1"
grep -Fq -- 'watch_mode="hot"' "${binary}"
grep -Fq -- 'bun_args+=("--hot")' "${binary}"
grep -Fq -- '--no-clear-screen' "${binary}"
grep -Fq -- 'if [[ 1 -eq 0 ]]; then' "${binary}"
grep -Fq -- 'readarray -t restart_paths' "${binary}"
grep -Fq -- 'examples/basic/README.md' "${binary}"
python3 - "${launcher}" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
assert spec["kind"] == "bun_run", spec
assert spec["watch_mode"] == "hot", spec
assert "--no-clear-screen" in spec["argv"], spec
assert spec["restart_on"], spec
assert spec["restart_on"][0].endswith("examples/basic/README.md"), spec
PY

View File

@@ -14,8 +14,24 @@ cleanup() {
}
trap cleanup EXIT
"${binary}" >"${log_file}" 2>&1 &
server_pid=$!
start_launcher() {
local launcher="$1"
local log_target="$2"
shift 2
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" >"${log_target}" 2>&1 &
else
"${launcher}" "$@" >"${log_target}" 2>&1 &
fi
server_pid=$!
}
start_launcher "${binary}" "${log_file}"
for _ in {1..20}; do
if grep -Fq "rules_bun bun_dev example" "${log_file}"; then

View File

@@ -17,6 +17,23 @@ cleanup() {
}
trap cleanup EXIT
start_launcher() {
local launcher="$1"
local log_target="$2"
shift 2
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" >"${log_target}" 2>&1 &
else
"${launcher}" "$@" >"${log_target}" 2>&1 &
fi
server_pid=$!
}
pick_port() {
python3 - <<'PY'
import socket
@@ -37,8 +54,7 @@ verify_vite_app() {
port="$(pick_port)"
log_file="${workdir}/${log_name}.log"
"${binary}" --host 127.0.0.1 --port "${port}" --strictPort >"${log_file}" 2>&1 &
server_pid=$!
start_launcher "${binary}" "${log_file}" --host 127.0.0.1 --port "${port}" --strictPort
for _ in {1..60}; do
if ! kill -0 "${server_pid}" 2>/dev/null; then

View File

@@ -1,5 +1,5 @@
load("//js:defs.bzl", "js_binary", "js_run_devserver", "js_test", "ts_library")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//js:defs.bzl", "js_binary", "js_run_devserver", "js_test", "ts_library")
ts_library(
name = "helper_lib",
@@ -9,13 +9,14 @@ ts_library(
js_binary(
name = "compat_bin",
args = ["compat-mode"],
entry_point = "main.ts",
deps = [":helper_lib"],
args = ["compat-mode"],
)
sh_test(
name = "js_binary_compat_test",
size = "small",
srcs = ["run_binary.sh"],
args = ["$(location :compat_bin)"],
data = [":compat_bin"],
@@ -23,18 +24,21 @@ sh_test(
js_test(
name = "compat_suite",
size = "small",
entry_point = "app.test.ts",
deps = [":helper_lib"],
)
js_run_devserver(
name = "compat_devserver",
tool = ":compat_bin",
args = ["devserver-mode"],
tool = ":compat_bin",
visibility = ["//tests/ci_test:__pkg__"],
)
sh_test(
name = "js_run_devserver_compat_test",
size = "small",
srcs = ["run_devserver.sh"],
args = ["$(location :compat_devserver)"],
data = [":compat_devserver"],
@@ -42,27 +46,28 @@ sh_test(
js_run_devserver(
name = "compat_devserver_with_package_json",
tool = ":compat_bin",
package_json = "app/package.json",
tool = ":compat_bin",
working_dir = "package",
)
js_run_devserver(
name = "compat_devserver_with_package_dir_hint",
tool = ":compat_bin",
package_dir_hint = "app",
tool = ":compat_bin",
working_dir = "package",
)
sh_test(
name = "js_run_devserver_workspace_shape_test",
size = "small",
srcs = ["verify_workspace_shape.sh"],
args = [
"$(location :compat_devserver_with_package_json)",
"$(location :compat_devserver_with_package_dir_hint)",
],
data = [
":compat_devserver_with_package_json",
":compat_devserver_with_package_dir_hint",
":compat_devserver_with_package_json",
],
)

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$("${binary}")"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "helper:payload-from-lib compat-mode" ]]; then
echo "unexpected output: ${output}" >&2

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$("${binary}")"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "helper:payload-from-lib compat-mode devserver-mode" ]]; then
echo "unexpected output: ${output}" >&2

View File

@@ -4,10 +4,25 @@ set -euo pipefail
package_json_launcher="$1"
package_dir_hint_launcher="$2"
grep -Fq -- 'package_json="${runfiles_dir}/_main/tests/js_compat_test/app/package.json"' "${package_json_launcher}"
grep -Fq -- 'package_rel_dir_hint="."' "${package_json_launcher}"
grep -Fq -- 'working_dir_mode="package"' "${package_json_launcher}"
python3 - "${package_json_launcher}" "${package_dir_hint_launcher}" <<'PY'
import json
import pathlib
import sys
grep -Fq -- 'package_json=""' "${package_dir_hint_launcher}"
grep -Fq -- 'package_rel_dir_hint="app"' "${package_dir_hint_launcher}"
grep -Fq -- 'working_dir_mode="package"' "${package_dir_hint_launcher}"
def read_spec(launcher: str):
path = pathlib.Path(launcher)
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
return json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
package_json_spec = read_spec(sys.argv[1])
package_dir_hint_spec = read_spec(sys.argv[2])
assert package_json_spec["package_json_short_path"].endswith("tests/js_compat_test/app/package.json"), package_json_spec
assert package_json_spec["package_dir_hint"] == ".", package_json_spec
assert package_json_spec["working_dir_mode"] == "package", package_json_spec
assert package_dir_hint_spec["package_json_short_path"] == "", package_dir_hint_spec
assert package_dir_hint_spec["package_dir_hint"] == "app", package_dir_hint_spec
assert package_dir_hint_spec["working_dir_mode"] == "package", package_dir_hint_spec
PY

View File

@@ -1,5 +1,5 @@
load("//bun:defs.bzl", "bun_bundle", "bun_test", "ts_library")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//bun:defs.bzl", "bun_bundle", "bun_test", "ts_library")
ts_library(
name = "helper_lib",
@@ -14,6 +14,7 @@ bun_bundle(
sh_test(
name = "bundle_dep_propagation_test",
size = "small",
srcs = ["verify_bundle.sh"],
args = ["$(location :bundle_with_deps)"],
data = [":bundle_with_deps"],
@@ -21,6 +22,7 @@ sh_test(
bun_test(
name = "test_with_deps",
size = "small",
srcs = ["app.test.ts"],
deps = [":helper_lib"],
)

View File

@@ -34,8 +34,8 @@ config_setting(
sh_test(
name = "npm_translate_lock_workspace_test",
size = "small",
srcs = ["npm_translate_lock_workspace_test.sh"],
env_inherit = ["PATH"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
":linux_aarch64": ["$(location @bun_linux_aarch64//:bun)"],
@@ -56,4 +56,5 @@ sh_test(
"//js:repo_runtime_files",
"//npm:repo_runtime_files",
],
env_inherit = ["PATH"],
)

View File

@@ -1,32 +1,37 @@
load("//bun:defs.bzl", "bun_script")
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//bun:defs.bzl", "bun_script")
bun_script(
name = "hello_script",
script = "hello",
package_json = "package.json",
data = ["hello.ts"],
package_json = "package.json",
script = "hello",
)
sh_test(
name = "bun_script_ts_test",
size = "small",
srcs = ["run_script.sh"],
args = ["$(location :hello_script)", "hello-script"],
args = [
"$(location :hello_script)",
"hello-script",
],
data = [":hello_script"],
)
bun_script(
name = "env_script",
script = "print-env",
package_json = "package.json",
data = [
".env",
"env.ts",
],
package_json = "package.json",
script = "print-env",
)
sh_test(
name = "bun_script_package_cwd_test",
size = "small",
srcs = ["run_env_script.sh"],
args = ["$(location :env_script)"],
data = [":env_script"],
@@ -34,17 +39,18 @@ sh_test(
bun_script(
name = "vite_dev_server",
script = "dev",
package_json = "vite_app/package.json",
node_modules = "@script_test_vite_node_modules//:node_modules",
data = [
"vite_app/index.html",
"vite_app/main.js",
],
node_modules = "@script_test_vite_node_modules//:node_modules",
package_json = "vite_app/package.json",
script = "dev",
)
sh_test(
name = "bun_script_vite_app_test",
size = "small",
srcs = ["run_vite_app.sh"],
args = ["$(location :vite_dev_server)"],
data = [":vite_dev_server"],
@@ -52,28 +58,29 @@ sh_test(
bun_script(
name = "vite_monorepo_app_a_dev_server",
script = "dev",
package_json = "vite_monorepo/apps/app-a/package.json",
node_modules = "@script_test_vite_monorepo_node_modules//:node_modules",
data = [
"vite_monorepo/apps/app-a/index.html",
"vite_monorepo/apps/app-a/main.js",
],
node_modules = "@script_test_vite_monorepo_node_modules//:node_modules",
package_json = "vite_monorepo/apps/app-a/package.json",
script = "dev",
)
bun_script(
name = "vite_monorepo_app_b_dev_server",
script = "dev",
package_json = "vite_monorepo/apps/app-b/package.json",
node_modules = "@script_test_vite_monorepo_node_modules//:node_modules",
data = [
"vite_monorepo/apps/app-b/index.html",
"vite_monorepo/apps/app-b/main.js",
],
node_modules = "@script_test_vite_monorepo_node_modules//:node_modules",
package_json = "vite_monorepo/apps/app-b/package.json",
script = "dev",
)
sh_test(
name = "bun_script_vite_monorepo_apps_test",
size = "small",
srcs = ["run_vite_monorepo_apps.sh"],
args = [
"$(location :vite_monorepo_app_a_dev_server)",
@@ -85,54 +92,69 @@ sh_test(
],
)
sh_test(
name = "bun_script_monorepo_launcher_shape_test",
size = "small",
srcs = ["verify_monorepo_launcher_shape.sh"],
args = [
"$(location :vite_monorepo_app_a_dev_server)",
"$(location :paraglide_monorepo_app_a_build)",
],
data = [
":paraglide_monorepo_app_a_build",
":vite_monorepo_app_a_dev_server",
],
)
bun_script(
name = "paraglide_monorepo_app_a_build",
script = "build:app-a",
package_json = "paraglide_monorepo/package.json",
node_modules = "@script_test_paraglide_monorepo_node_modules//:node_modules",
data = [
"paraglide_monorepo/scripts/build-app-a.mjs",
"paraglide_monorepo/scripts/build-app-b.mjs",
"paraglide_monorepo/packages/i18n/package.json",
"paraglide_monorepo/packages/i18n/project.inlang/settings.json",
"paraglide_monorepo/packages/i18n/messages/en.json",
"paraglide_monorepo/packages/i18n/messages/sv.json",
"paraglide_monorepo/packages/app-a/package.json",
"paraglide_monorepo/packages/app-a/index.html",
"paraglide_monorepo/packages/app-a/main.js",
"paraglide_monorepo/packages/app-a/package.json",
"paraglide_monorepo/packages/app-a/vite.config.js",
"paraglide_monorepo/packages/app-b/package.json",
"paraglide_monorepo/packages/app-b/index.html",
"paraglide_monorepo/packages/app-b/main.js",
"paraglide_monorepo/packages/app-b/package.json",
"paraglide_monorepo/packages/app-b/vite.config.js",
"paraglide_monorepo/packages/i18n/messages/en.json",
"paraglide_monorepo/packages/i18n/messages/sv.json",
"paraglide_monorepo/packages/i18n/package.json",
"paraglide_monorepo/packages/i18n/project.inlang/settings.json",
"paraglide_monorepo/scripts/build-app-a.mjs",
"paraglide_monorepo/scripts/build-app-b.mjs",
],
node_modules = "@script_test_paraglide_monorepo_node_modules//:node_modules",
package_json = "paraglide_monorepo/package.json",
script = "build:app-a",
)
bun_script(
name = "paraglide_monorepo_app_b_build",
script = "build:app-b",
package_json = "paraglide_monorepo/package.json",
node_modules = "@script_test_paraglide_monorepo_node_modules//:node_modules",
data = [
"paraglide_monorepo/scripts/build-app-a.mjs",
"paraglide_monorepo/scripts/build-app-b.mjs",
"paraglide_monorepo/packages/i18n/package.json",
"paraglide_monorepo/packages/i18n/project.inlang/settings.json",
"paraglide_monorepo/packages/i18n/messages/en.json",
"paraglide_monorepo/packages/i18n/messages/sv.json",
"paraglide_monorepo/packages/app-a/package.json",
"paraglide_monorepo/packages/app-a/index.html",
"paraglide_monorepo/packages/app-a/main.js",
"paraglide_monorepo/packages/app-a/package.json",
"paraglide_monorepo/packages/app-a/vite.config.js",
"paraglide_monorepo/packages/app-b/package.json",
"paraglide_monorepo/packages/app-b/index.html",
"paraglide_monorepo/packages/app-b/main.js",
"paraglide_monorepo/packages/app-b/package.json",
"paraglide_monorepo/packages/app-b/vite.config.js",
"paraglide_monorepo/packages/i18n/messages/en.json",
"paraglide_monorepo/packages/i18n/messages/sv.json",
"paraglide_monorepo/packages/i18n/package.json",
"paraglide_monorepo/packages/i18n/project.inlang/settings.json",
"paraglide_monorepo/scripts/build-app-a.mjs",
"paraglide_monorepo/scripts/build-app-b.mjs",
],
node_modules = "@script_test_paraglide_monorepo_node_modules//:node_modules",
package_json = "paraglide_monorepo/package.json",
script = "build:app-b",
)
sh_test(
name = "bun_script_paraglide_monorepo_build_test",
size = "small",
srcs = ["run_paraglide_monorepo_builds.sh"],
args = [
"$(location :paraglide_monorepo_app_a_build)",
@@ -146,21 +168,22 @@ sh_test(
bun_script(
name = "workspace_filtered_script",
script = "say",
package_json = "workspace_run/package.json",
data = [
"workspace_run/packages/pkg-a/package.json",
"workspace_run/packages/pkg-a/say.ts",
"workspace_run/packages/pkg-b/package.json",
"workspace_run/packages/pkg-b/say.ts",
],
filters = ["./packages/pkg-a"],
execution_mode = "sequential",
filters = ["./packages/pkg-a"],
package_json = "workspace_run/package.json",
script = "say",
silent = True,
)
sh_test(
name = "bun_script_workspace_filter_test",
size = "small",
srcs = ["run_workspace_script.sh"],
args = ["$(location :workspace_filtered_script)"],
data = [":workspace_filtered_script"],
@@ -168,20 +191,21 @@ sh_test(
bun_script(
name = "workspace_parallel_script",
script = "say",
package_json = "workspace_run/package.json",
data = [
"workspace_run/packages/pkg-a/package.json",
"workspace_run/packages/pkg-a/say.ts",
"workspace_run/packages/pkg-b/package.json",
"workspace_run/packages/pkg-b/say.ts",
],
workspaces = True,
execution_mode = "parallel",
package_json = "workspace_run/package.json",
script = "say",
workspaces = True,
)
sh_test(
name = "bun_script_workspace_parallel_test",
size = "small",
srcs = ["run_workspace_parallel.sh"],
args = ["$(location :workspace_parallel_script)"],
data = [":workspace_parallel_script"],
@@ -189,22 +213,24 @@ sh_test(
bun_script(
name = "workspace_flagged_script",
script = "say",
package_json = "workspace_run/package.json",
data = [
"workspace_run/packages/pkg-a/package.json",
"workspace_run/packages/pkg-a/say.ts",
"workspace_run/packages/pkg-b/package.json",
"workspace_run/packages/pkg-b/say.ts",
],
workspaces = True,
execution_mode = "parallel",
no_exit_on_error = True,
package_json = "workspace_run/package.json",
script = "say",
shell = "system",
visibility = ["//tests/ci_test:__pkg__"],
workspaces = True,
)
sh_test(
name = "bun_script_workspace_flag_shape_test",
size = "small",
srcs = ["verify_launcher_flags.sh"],
args = [
"$(location :workspace_flagged_script)",

View File

@@ -2,7 +2,23 @@
set -euo pipefail
binary="$1"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "from-dotenv" ]]; then
echo "Expected .env value from package directory, got: ${output}" >&2

View File

@@ -10,13 +10,28 @@ cleanup() {
}
trap cleanup EXIT
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
verify_build() {
local binary="$1"
local out_dir="$2"
local expected_title="$3"
local expected_text="$4"
"${binary}" --outDir "${out_dir}" >/dev/null
run_launcher "${binary}" --outDir "${out_dir}" >/dev/null
if [[ ! -f "${out_dir}/index.html" ]]; then
echo "missing build output index.html for ${binary}" >&2

View File

@@ -3,7 +3,23 @@ set -euo pipefail
binary="$1"
expected="$2"
output="$(${binary})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${binary}")"
if [[ ${output} != "${expected}" ]]; then
echo "Unexpected output from ${binary}: ${output}" >&2

View File

@@ -14,6 +14,23 @@ cleanup() {
}
trap cleanup EXIT
start_launcher() {
local launcher="$1"
local log_target="$2"
shift 2
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" >"${log_target}" 2>&1 &
else
"${launcher}" "$@" >"${log_target}" 2>&1 &
fi
server_pid=$!
}
port="$(
python3 - <<'PY'
import socket
@@ -24,8 +41,7 @@ sock.close()
PY
)"
"${binary}" --host 127.0.0.1 --port "${port}" --strictPort >"${log_file}" 2>&1 &
server_pid=$!
start_launcher "${binary}" "${log_file}" --host 127.0.0.1 --port "${port}" --strictPort
for _ in {1..60}; do
if ! kill -0 "${server_pid}" 2>/dev/null; then

View File

@@ -17,6 +17,23 @@ cleanup() {
}
trap cleanup EXIT
start_launcher() {
local launcher="$1"
local log_target="$2"
shift 2
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" >"${log_target}" 2>&1 &
else
"${launcher}" "$@" >"${log_target}" 2>&1 &
fi
server_pid=$!
}
pick_port() {
python3 - <<'PY'
import socket
@@ -37,8 +54,7 @@ verify_vite_app() {
port="$(pick_port)"
log_file="${workdir}/${log_name}.log"
"${binary}" --host 127.0.0.1 --port "${port}" --strictPort >"${log_file}" 2>&1 &
server_pid=$!
start_launcher "${binary}" "${log_file}" --host 127.0.0.1 --port "${port}" --strictPort
for _ in {1..60}; do
if ! kill -0 "${server_pid}" 2>/dev/null; then

View File

@@ -2,7 +2,23 @@
set -euo pipefail
script_bin="$1"
output="$(${script_bin})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${script_bin}")"
if [[ ${output} != *"pkg-a"* ]]; then
echo "Expected workspace parallel run output to include pkg-a: ${output}" >&2

View File

@@ -2,7 +2,23 @@
set -euo pipefail
script_bin="$1"
output="$(${script_bin})"
run_launcher() {
local launcher="$1"
shift
if [[ ${launcher} == *.cmd ]]; then
local command
printf -v command '"%s"' "${launcher}"
for arg in "$@"; do
printf -v command '%s "%s"' "${command}" "${arg}"
done
cmd.exe /c "${command}" | tr -d '\r'
return 0
fi
"${launcher}" "$@"
}
output="$(run_launcher "${script_bin}")"
if [[ ${output} != *"pkg-a"* ]]; then
echo "Expected workspace run output to include pkg-a: ${output}" >&2

View File

@@ -1,12 +1,21 @@
#!/usr/bin/env bash
set -euo pipefail
binary="$1"
launcher="$1"
shift
for expected in "$@"; do
if ! grep -Fq -- "${expected}" "${binary}"; then
echo "Expected ${binary} to contain ${expected}" >&2
exit 1
fi
done
python3 - "${launcher}" "$@" <<'PY'
import json
import pathlib
import sys
path = pathlib.Path(sys.argv[1])
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
spec = json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
argv = spec["argv"]
for value in sys.argv[2:]:
if value not in argv:
raise SystemExit(f"missing {value!r} in argv {argv!r}")
PY

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env bash
set -euo pipefail
vite_launcher="$1"
paraglide_launcher="$2"
python3 - "${vite_launcher}" "${paraglide_launcher}" <<'PY'
import json
import pathlib
import sys
def read_spec(launcher: str):
path = pathlib.Path(launcher)
if path.suffix.lower() == ".cmd":
path = pathlib.Path(str(path)[:-4])
return json.loads(pathlib.Path(f"{path}.launcher.json").read_text())
vite_spec = read_spec(sys.argv[1])
paraglide_spec = read_spec(sys.argv[2])
assert all(not root.startswith("../") for root in vite_spec["node_modules_roots"]), vite_spec
assert "node_modules" in vite_spec["node_modules_roots"], vite_spec
assert all(not root.startswith("../") for root in paraglide_spec["node_modules_roots"]), paraglide_spec
assert "node_modules" in paraglide_spec["node_modules_roots"], paraglide_spec
assert "packages/i18n/node_modules" in paraglide_spec["node_modules_roots"], paraglide_spec
PY

View File

@@ -34,6 +34,7 @@ config_setting(
sh_test(
name = "bun_version_test",
size = "small",
srcs = ["toolchain_version.sh"],
args = select({
":linux_x86_64": ["$(location @bun_linux_x64//:bun)"],
@@ -53,6 +54,7 @@ sh_test(
sh_test(
name = "toolchain_resolution_matrix_test",
size = "small",
srcs = ["toolchain_resolution_matrix.sh"],
args = ["$(location //tests/toolchain_test:BUILD.bazel)"],
data = ["//tests/toolchain_test:BUILD.bazel"],