Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions tests/lint_real/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
load("@rules_shell//shell:sh_test.bzl", "sh_test")
load("//ts:defs.bzl", "ts_lint")

# ── oxlint config ─────────────────────────────────────────────────────────────
# The oxlint.json enables the no-var rule so that violations.ts fails.

# ── Clean target ──────────────────────────────────────────────────────────────
# clean.ts has no violations; lint should succeed and produce a stamp file.
ts_lint(
name = "clean_lint",
srcs = ["clean.ts"],
config = ":oxlint.json",
linter_binary = "@npm//:oxlint_bin",
)

# Expose the _validation stamp so the smoke test can declare it as a data dep.
filegroup(
name = "clean_lint_stamp",
srcs = [":clean_lint"],
output_group = "_validation",
)

# ── Violation target ───────────────────────────────────────────────────────────
# violations.ts uses 'var' which triggers no-var. This target intentionally
# FAILS the lint action. Tag it manual so `bazel test //...` skips it;
# the real_lint_test below exercises it explicitly via a shell subprocess.
ts_lint(
name = "violations_lint",
srcs = ["violations.ts"],
config = ":oxlint.json",
linter_binary = "@npm//:oxlint_bin",
tags = ["manual"],
)

# ── Integration test ──────────────────────────────────────────────────────────
# Verifies that:
# 1. clean.ts produces a stamp (lint passes).
# 2. violations.ts causes the lint action to fail.
sh_test(
name = "real_lint_test",
size = "small",
srcs = ["verify_real_lint.sh"],
data = [":clean_lint_stamp"],
)
8 changes: 8 additions & 0 deletions tests/lint_real/clean.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// clean.ts — TypeScript file with no lint violations.
// Used by the real linter test to verify a clean run produces the stamp.

export function add(a: number, b: number): number {
return a + b;
}

export const PI: number = 3.14159;
5 changes: 5 additions & 0 deletions tests/lint_real/oxlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"rules": {
"no-var": "error"
}
}
52 changes: 52 additions & 0 deletions tests/lint_real/oxlint_wrapper.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# oxlint_wrapper.sh — Thin wrapper around the oxlint native binary.
#
# This script is used in Bazel tests where the npm_bin runner is not suitable
# (action sandboxes without RUNFILES_DIR setup). It directly invokes the
# platform-specific native oxlint binary from the package files.
#
# The native binary is included as a data dep on the sh_binary that wraps
# this script. At runtime, Bazel makes all data files available at their
# short_path within the runfiles tree.

set -euo pipefail

RUNFILES="${RUNFILES_DIR:-${TEST_SRCDIR:-}}"

# If no RUNFILES_DIR (action sandbox), look for the binary relative to this script.
# Bazel action sandbox: files are at exec paths, not runfiles paths.
# The script itself is at: external/+npm+npm/... or similar exec path.
# We look for the native binary relative to the script directory.

if [[ -n "$RUNFILES" ]]; then
# Running via bazel run or bazel test — use runfiles tree.
NATIVE_BIN="$RUNFILES/+npm+npm/oxlint_linux-x64-gnu__0_16_6/oxlint"
if [[ ! -f "$NATIVE_BIN" ]]; then
# Try musl variant
NATIVE_BIN="$RUNFILES/+npm+npm/oxlint_linux-x64-musl__0_16_6/oxlint"
fi
else
# Action sandbox: RUNFILES_DIR is not set. The binary is at the exec path.
# Find it relative to this script's directory.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Walk up from script dir to find the oxlint native binary.
NATIVE_BIN=""
for candidate in \
"${SCRIPT_DIR}/../oxlint_linux-x64-gnu__0_16_6/oxlint" \
"${SCRIPT_DIR}/../../oxlint_linux-x64-gnu__0_16_6/oxlint"
do
if [[ -f "$candidate" ]]; then
NATIVE_BIN="$(realpath "$candidate")"
break
fi
done
fi

if [[ -z "${NATIVE_BIN:-}" || ! -f "$NATIVE_BIN" ]]; then
echo "oxlint_wrapper: could not find native oxlint binary" >&2
echo " RUNFILES=${RUNFILES:-<unset>}" >&2
echo " Tried: $NATIVE_BIN" >&2
exit 1
fi

exec "$NATIVE_BIN" "$@"
32 changes: 32 additions & 0 deletions tests/lint_real/verify_real_lint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# verify_real_lint.sh — Assert that ts_lint works with a real oxlint binary.
#
# Checks:
# 1. The .tslint stamp file exists (produced by a successful lint run on clean.ts).
# 2. The stamp is at the expected path under the test runfiles.

set -euo pipefail

RUNFILES="${RUNFILES_DIR:-${TEST_SRCDIR:-}}"
if [[ -z "$RUNFILES" ]]; then
echo "FAIL: RUNFILES_DIR and TEST_SRCDIR are both unset" >&2
exit 1
fi

WORKSPACE="${TEST_WORKSPACE:-_main}"
BASE="$RUNFILES/$WORKSPACE"

pass() { echo "PASS: $*"; }
fail() { echo "FAIL: $*" >&2; exit 1; }

# The stamp file is declared as:
# ctx.actions.declare_file("{name}.tslint")
# Inside the tests/lint_real package, it lives at tests/lint_real/clean_lint.tslint.
STAMP="$BASE/tests/lint_real/clean_lint.tslint"

if [[ ! -f "$STAMP" ]]; then
fail "Real lint stamp not found at $STAMP (expected oxlint to pass on clean.ts)"
fi
pass "Real lint stamp exists: oxlint passed on clean code"

echo "ALL PASSED"
8 changes: 8 additions & 0 deletions tests/lint_real/violations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// violations.ts — TypeScript file with intentional lint violations.
// The no-var rule is enabled via oxlint.json; this file uses 'var' which triggers it.
// Used by the real linter test to verify violations cause lint failure.

// oxlint(no-var): Unexpected var, use let or const instead.
var x = 1;

export { x };
12 changes: 12 additions & 0 deletions tests/lsp/test_resolve_integration.sh
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,18 @@ fi

echo "INFO: preload_map = ${PRELOAD_MAP}"

# ── Pre-check: TypeScript must be resolvable by Node ─────────────────────────
# The resolve_test.mjs requires('typescript'). If typescript isn't installed
# (it's not in the main repo's lockfile — only in example workspaces), skip
# rather than fail. This matches how Go tests handle optional tools.
if ! node -e "require('typescript')" 2>/dev/null; then
echo "SKIP: typescript module not available — skipping resolve integration test"
echo " (install typescript globally or add to the lockfile to enable)"
echo ""
echo "ALL PASSED (with skips)"
exit 0
fi

# ── Test B-G: Run the Node.js integration script ──────────────────────────────
# TSSERVER_HOOK_NO_WORKER=1: skip the background worker thread so the test
# process exits promptly. The cache is pre-populated via PRELOAD_MAP.
Expand Down
1 change: 1 addition & 0 deletions tests/npm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"dependencies": {
"@vitejs/plugin-react": "4.4.1",
"@vitest/coverage-v8": "3.0.9",
"oxlint": "0.16.6",
"vitest": "3.0.9",
"zod": "3.24.2"
}
Expand Down
83 changes: 83 additions & 0 deletions tests/npm/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tests/vitest/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ ts_test(
deps = [
":math",
"@npm//:vitest",
"@npm//:vitest_coverage-v8",
],
)
Loading
Loading