summaryrefslogtreecommitdiff
path: root/corebinutils/test/tests
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:29:55 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 18:29:55 +0300
commit22343fc2bb8db94066d3e314c5a20a9b9278f4c9 (patch)
treed2a731892b60e63970796b567a6a2dd7eb209427 /corebinutils/test/tests
parent4cf86e37e42f9f04ec4a41a28ffe466d2510438a (diff)
parentceefe27a76f3b2075abbf01b0c44375363967af6 (diff)
downloadProject-Tick-22343fc2bb8db94066d3e314c5a20a9b9278f4c9.tar.gz
Project-Tick-22343fc2bb8db94066d3e314c5a20a9b9278f4c9.zip
Add 'corebinutils/test/' from commit 'ceefe27a76f3b2075abbf01b0c44375363967af6'
git-subtree-dir: corebinutils/test git-subtree-mainline: 4cf86e37e42f9f04ec4a41a28ffe466d2510438a git-subtree-split: ceefe27a76f3b2075abbf01b0c44375363967af6
Diffstat (limited to 'corebinutils/test/tests')
-rw-r--r--corebinutils/test/tests/fd_helper.c111
-rw-r--r--corebinutils/test/tests/legacy_test.sh209
-rw-r--r--corebinutils/test/tests/test.sh479
3 files changed, 799 insertions, 0 deletions
diff --git a/corebinutils/test/tests/fd_helper.c b/corebinutils/test/tests/fd_helper.c
new file mode 100644
index 0000000000..27d81f7164
--- /dev/null
+++ b/corebinutils/test/tests/fd_helper.c
@@ -0,0 +1,111 @@
+/*
+
+SPDX-License-Identifier: BSD-3-Clause
+
+Copyright (c) 2026
+ Project Tick. All rights reserved.
+
+This code is derived from software contributed to Berkeley by
+the Institute of Electrical and Electronics Engineers, Inc.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+*/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static void
+die_errno(const char *what)
+{
+ fprintf(stderr, "fd_helper: %s: %s\n", what, strerror(errno));
+ exit(126);
+}
+
+static int
+parse_fd(const char *text)
+{
+ char *end;
+ long value;
+
+ errno = 0;
+ value = strtol(text, &end, 10);
+ if (end == text || *end != '\0' || errno == ERANGE ||
+ value < 0 || value > INT_MAX) {
+ fprintf(stderr, "fd_helper: invalid file descriptor: %s\n", text);
+ exit(126);
+ }
+ return (int)value;
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ int master_fd;
+ int slave_fd;
+ char *slave_name;
+
+ if (argc < 4) {
+ fprintf(stderr, "usage: fd_helper fd program arg ...\n");
+ return 126;
+ }
+
+ fd = parse_fd(argv[1]);
+
+ master_fd = posix_openpt(O_RDWR | O_NOCTTY);
+ if (master_fd < 0)
+ die_errno("posix_openpt");
+ if (grantpt(master_fd) != 0)
+ die_errno("grantpt");
+ if (unlockpt(master_fd) != 0)
+ die_errno("unlockpt");
+
+ slave_name = ptsname(master_fd);
+ if (slave_name == NULL)
+ die_errno("ptsname");
+
+ slave_fd = open(slave_name, O_RDWR | O_NOCTTY);
+ if (slave_fd < 0)
+ die_errno("open slave pty");
+
+ if (dup2(slave_fd, fd) < 0)
+ die_errno("dup2");
+
+ if (!isatty(fd))
+ die_errno("isatty");
+
+ if (slave_fd != fd)
+ close(slave_fd);
+ close(master_fd);
+
+ execv(argv[2], &argv[2]);
+ die_errno("execv");
+}
diff --git a/corebinutils/test/tests/legacy_test.sh b/corebinutils/test/tests/legacy_test.sh
new file mode 100644
index 0000000000..94f51aefba
--- /dev/null
+++ b/corebinutils/test/tests/legacy_test.sh
@@ -0,0 +1,209 @@
+#!/bin/sh
+
+set -eu
+
+#-
+# Copyright (c) June 1996 Wolfram Schneider <wosch@FreeBSD.org>. Berlin.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+
+#
+# TEST.sh - check if test(1) or builtin test works
+#
+
+# force a specified test program, e.g. `env TEST_BIN=/bin/test sh legacy_test.sh'
+TEST_BIN=${TEST_BIN:-test}
+FAILED=0
+
+t ()
+{
+ # $1 -> exit code
+ # $2 -> $test expression
+
+ count=$((count+1))
+ # check for syntax errors
+ if syntax=$(eval "\"$TEST_BIN\" $2" 2>&1); then
+ ret=0
+ else
+ ret=$?
+ fi
+ if test -n "$syntax"; then
+ printf "not ok %s - (syntax error)\n" "$count $2"
+ FAILED=1
+ elif [ "$ret" != "$1" ]; then
+ printf "not ok %s - (got $ret, expected $1)\n" "$count $2"
+ FAILED=1
+ else
+ printf "ok %s\n" "$count $2"
+ fi
+}
+
+count=0
+echo "1..130"
+
+t 0 'b = b'
+t 0 'b == b'
+t 1 'b != b'
+t 0 '\( b = b \)'
+t 0 '\( b == b \)'
+t 1 '! \( b = b \)'
+t 1 '! \( b == b \)'
+t 1 '! -f /etc/passwd'
+
+t 0 '-h = -h'
+t 0 '-o = -o'
+t 1 '-f = h'
+t 1 '-h = f'
+t 1 '-o = f'
+t 1 'f = -o'
+t 0 '\( -h = -h \)'
+t 1 '\( a = -h \)'
+t 1 '\( -f = h \)'
+t 0 '-h = -h -o a'
+t 0 '\( -h = -h \) -o 1'
+t 0 '-h = -h -o -h = -h'
+t 0 '\( -h = -h \) -o \( -h = -h \)'
+t 0 'roedelheim = roedelheim'
+t 1 'potsdam = berlin-dahlem'
+
+t 0 '-d /'
+t 0 '-d / -a a != b'
+t 1 '-z "-z"'
+t 0 '-n -n'
+
+t 0 '0'
+t 0 '\( 0 \)'
+t 0 '-E'
+t 0 '-X -a -X'
+t 0 '-XXX'
+t 0 '\( -E \)'
+t 0 'true -o X'
+t 0 'true -o -X'
+t 0 '\( \( \( a = a \) -o 1 \) -a 1 \) -a true'
+t 1 '-h /'
+t 0 '-r /'
+t 1 '-w /'
+t 0 '-x /bin/sh'
+t 0 '-c /dev/null'
+t 0 '-f /etc/passwd'
+t 0 '-s /etc/passwd'
+
+t 1 '! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)'
+t 0 '100 -eq 100'
+t 0 '100 -lt 200'
+t 1 '1000 -lt 200'
+t 0 '1000 -gt 200'
+t 0 '1000 -ge 200'
+t 0 '1000 -ge 1000'
+t 1 '2 -ne 2'
+t 0 '0 -eq 0'
+t 1 '-5 -eq 5'
+t 0 '\( 0 -eq 0 \)'
+t 1 '1 -eq 0 -o a = a -a 1 -eq 0 -o a = aa'
+
+t 1 '"" -o ""'
+t 1 '"" -a ""'
+t 1 '"a" -a ""'
+t 0 '"a" -a ! ""'
+t 1 '""'
+t 0 '! ""'
+
+t 0 '!'
+t 0 '\('
+t 0 '\)'
+
+t 1 '\( = \)'
+t 0 '\( != \)'
+t 0 '\( ! \)'
+t 0 '\( \( \)'
+t 0 '\( \) \)'
+t 0 '! = !'
+t 1 '! != !'
+t 1 '-n = \)'
+t 0 '! != \)'
+t 1 '! = a'
+t 0 '! != -n'
+t 0 '! -c /etc/passwd'
+
+t 1 '! = = ='
+t 0 '! = = \)'
+t 0 '! "" -o ""'
+t 1 '! "x" -o ""'
+t 1 '! "" -o "x"'
+t 1 '! "x" -o "x"'
+t 0 '\( -f /etc/passwd \)'
+t 0 '\( ! "" \)'
+t 1 '\( ! -e \)'
+
+t 0 '0 -eq 0 -a -d /'
+t 0 '-s = "" -o "" = ""'
+t 0 '"" = "" -o -s = ""'
+t 1 '-s = "" -o -s = ""'
+t 0 '-z x -o x = "#" -o x = x'
+t 1 '-z y -o y = "#" -o y = x'
+t 0 '0 -ne 0 -o ! -f /'
+t 0 '1 -ne 0 -o ! -f /etc/passwd'
+t 1 '0 -ne 0 -o ! -f /etc/passwd'
+
+t 0 '-n ='
+t 1 '-z ='
+t 1 '! ='
+t 0 '-n -eq'
+t 1 '-z -eq'
+t 1 '! -eq'
+t 0 '-n -a'
+t 1 '-z -a'
+t 1 '! -a'
+t 0 '-n -o'
+t 1 '-z -o'
+t 1 '! -o'
+t 1 '! -n ='
+t 0 '! -z ='
+t 0 '! ! ='
+t 1 '! -n -eq'
+t 0 '! -z -eq'
+t 0 '! ! -eq'
+t 1 '! -n -a'
+t 0 '! -z -a'
+t 0 '! ! -a'
+t 1 '! -n -o'
+t 0 '! -z -o'
+t 0 '! ! -o'
+t 0 '\( -n = \)'
+t 1 '\( -z = \)'
+t 1 '\( ! = \)'
+t 0 '\( -n -eq \)'
+t 1 '\( -z -eq \)'
+t 1 '\( ! -eq \)'
+t 0 '\( -n -a \)'
+t 1 '\( -z -a \)'
+t 1 '\( ! -a \)'
+t 0 '\( -n -o \)'
+t 1 '\( -z -o \)'
+t 1 '\( ! -o \)'
+
+if [ "$FAILED" -ne 0 ]; then
+ exit 1
+fi
+
+printf '%s\n' "PASS"
diff --git a/corebinutils/test/tests/test.sh b/corebinutils/test/tests/test.sh
new file mode 100644
index 0000000000..debbbf81a1
--- /dev/null
+++ b/corebinutils/test/tests/test.sh
@@ -0,0 +1,479 @@
+#!/bin/sh
+set -eu
+
+ROOT=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
+TEST_BIN=${TEST_BIN:-"$ROOT/out/test"}
+BRACKET_BIN=${BRACKET_BIN:-"$ROOT/out/["}
+FD_HELPER_BIN=${FD_HELPER_BIN:-"$ROOT/build/fd_helper"}
+SHELL_BIN=$(command -v sh)
+
+TMPDIR=${TMPDIR:-/tmp}
+WORKDIR=$(mktemp -d "$TMPDIR/test-test.XXXXXX")
+STDOUT_FILE="$WORKDIR/stdout"
+STDERR_FILE="$WORKDIR/stderr"
+LAST_STATUS=0
+LAST_STDOUT=
+LAST_STDERR=
+
+export LC_ALL=C
+export TZ=UTC
+
+cleanup() {
+ rm -rf "$WORKDIR"
+}
+
+trap cleanup EXIT INT TERM HUP
+
+fail() {
+ printf 'FAIL: %s\n' "$1" >&2
+ exit 1
+}
+
+assert_status() {
+ name=$1
+ expected=$2
+ actual=$3
+
+ if [ "$expected" -ne "$actual" ]; then
+ printf 'FAIL: %s\n' "$name" >&2
+ printf 'expected status: %s\n' "$expected" >&2
+ printf 'actual status: %s\n' "$actual" >&2
+ exit 1
+ fi
+}
+
+assert_eq() {
+ name=$1
+ expected=$2
+ actual=$3
+
+ if [ "$expected" != "$actual" ]; then
+ printf 'FAIL: %s\n' "$name" >&2
+ printf '%s\n' '--- expected ---' >&2
+ printf '%s\n' "$expected" >&2
+ printf '%s\n' '--- actual ---' >&2
+ printf '%s\n' "$actual" >&2
+ exit 1
+ fi
+}
+
+assert_empty() {
+ name=$1
+ value=$2
+
+ if [ -n "$value" ]; then
+ printf 'FAIL: %s\n' "$name" >&2
+ printf '%s\n' '--- expected empty ---' >&2
+ printf '%s\n' '--- actual ---' >&2
+ printf '%s\n' "$value" >&2
+ exit 1
+ fi
+}
+
+assert_contains() {
+ name=$1
+ value=$2
+ pattern=$3
+
+ case $value in
+ *"$pattern"*) ;;
+ *) fail "$name" ;;
+ esac
+}
+
+run_capture() {
+ if "$@" >"$STDOUT_FILE" 2>"$STDERR_FILE"; then
+ LAST_STATUS=0
+ else
+ LAST_STATUS=$?
+ fi
+ LAST_STDOUT=$(cat "$STDOUT_FILE")
+ LAST_STDERR=$(cat "$STDERR_FILE")
+}
+
+run_in_shell() {
+ if sh -c "$1" >"$STDOUT_FILE" 2>"$STDERR_FILE"; then
+ LAST_STATUS=0
+ else
+ LAST_STATUS=$?
+ fi
+ LAST_STDOUT=$(cat "$STDOUT_FILE")
+ LAST_STDERR=$(cat "$STDERR_FILE")
+}
+
+find_socket_path() {
+ for candidate in \
+ /run/* /run/*/* /run/*/*/* \
+ /var/run/* /var/run/*/* /var/run/*/*/* \
+ /tmp/* /tmp/*/* /tmp/*/*/*; do
+ if [ -S "$candidate" ]; then
+ printf '%s\n' "$candidate"
+ return 0
+ fi
+ done
+ return 1
+}
+
+skip() {
+ printf 'SKIP: %s\n' "$1"
+}
+
+[ -x "$TEST_BIN" ] || fail "missing binary: $TEST_BIN"
+[ -x "$BRACKET_BIN" ] || fail "missing bracket binary: $BRACKET_BIN"
+[ -x "$FD_HELPER_BIN" ] || fail "missing fd helper: $FD_HELPER_BIN"
+
+run_capture "$TEST_BIN"
+assert_status "no expression status" 1 "$LAST_STATUS"
+assert_empty "no expression stdout" "$LAST_STDOUT"
+assert_empty "no expression stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" ""
+assert_status "empty operand status" 1 "$LAST_STATUS"
+assert_empty "empty operand stdout" "$LAST_STDOUT"
+assert_empty "empty operand stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" value
+assert_status "single operand status" 0 "$LAST_STATUS"
+assert_empty "single operand stdout" "$LAST_STDOUT"
+assert_empty "single operand stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -n ""
+assert_status "string -n status" 1 "$LAST_STATUS"
+assert_empty "string -n stdout" "$LAST_STDOUT"
+assert_empty "string -n stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -z ""
+assert_status "string -z status" 0 "$LAST_STATUS"
+assert_empty "string -z stdout" "$LAST_STDOUT"
+assert_empty "string -z stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -h = -h
+assert_status "operator-like operand status" 0 "$LAST_STATUS"
+assert_empty "operator-like operand stdout" "$LAST_STDOUT"
+assert_empty "operator-like operand stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" alpha = alpha
+assert_status "string equality status" 0 "$LAST_STATUS"
+assert_empty "string equality stdout" "$LAST_STDOUT"
+assert_empty "string equality stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" alpha == alpha
+assert_status "string double equals status" 0 "$LAST_STATUS"
+assert_empty "string double equals stdout" "$LAST_STDOUT"
+assert_empty "string double equals stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" alpha '!=' beta
+assert_status "string inequality status" 0 "$LAST_STATUS"
+assert_empty "string inequality stdout" "$LAST_STDOUT"
+assert_empty "string inequality stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" alpha '<' beta
+assert_status "string less-than status" 0 "$LAST_STATUS"
+assert_empty "string less-than stdout" "$LAST_STDOUT"
+assert_empty "string less-than stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" beta '>' alpha
+assert_status "string greater-than status" 0 "$LAST_STATUS"
+assert_empty "string greater-than stdout" "$LAST_STDOUT"
+assert_empty "string greater-than stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" 100 -eq 100
+assert_status "numeric eq status" 0 "$LAST_STATUS"
+assert_empty "numeric eq stdout" "$LAST_STDOUT"
+assert_empty "numeric eq stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -5 -lt 5
+assert_status "numeric lt status" 0 "$LAST_STATUS"
+assert_empty "numeric lt stdout" "$LAST_STDOUT"
+assert_empty "numeric lt stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" 7 -ge 8
+assert_status "numeric false status" 1 "$LAST_STATUS"
+assert_empty "numeric false stdout" "$LAST_STDOUT"
+assert_empty "numeric false stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" abc -eq 1
+assert_status "bad number status" 2 "$LAST_STATUS"
+assert_empty "bad number stdout" "$LAST_STDOUT"
+assert_eq "bad number stderr" "test: abc: bad number" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" 999999999999999999999999999999 -eq 1
+assert_status "out of range status" 2 "$LAST_STATUS"
+assert_empty "out of range stdout" "$LAST_STDOUT"
+assert_eq "out of range stderr" "test: 999999999999999999999999999999: out of range" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" '!' ""
+assert_status "bang empty status" 0 "$LAST_STATUS"
+assert_empty "bang empty stdout" "$LAST_STDOUT"
+assert_empty "bang empty stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" '!'
+assert_status "bare bang status" 0 "$LAST_STATUS"
+assert_empty "bare bang stdout" "$LAST_STDOUT"
+assert_empty "bare bang stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" '(' 0 -eq 0 ')' -a '(' 2 -gt 1 ')'
+assert_status "paren and status" 0 "$LAST_STATUS"
+assert_empty "paren and stdout" "$LAST_STDOUT"
+assert_empty "paren and stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" 1 -eq 0 -o a = a -a 1 -eq 0 -o a = aa
+assert_status "precedence status" 1 "$LAST_STATUS"
+assert_empty "precedence stdout" "$LAST_STDOUT"
+assert_empty "precedence stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" '(' 1 = 1
+assert_status "closing paren error status" 2 "$LAST_STATUS"
+assert_empty "closing paren error stdout" "$LAST_STDOUT"
+assert_eq "closing paren error stderr" "test: closing paren expected" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" 1 -eq
+assert_status "argument expected status" 2 "$LAST_STATUS"
+assert_empty "argument expected stdout" "$LAST_STDOUT"
+assert_eq "argument expected stderr" "test: -eq: argument expected" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" one two
+assert_status "unexpected operator status" 2 "$LAST_STATUS"
+assert_empty "unexpected operator stdout" "$LAST_STDOUT"
+assert_eq "unexpected operator stderr" "test: two: unexpected operator" "$LAST_STDERR"
+
+REGULAR_FILE="$WORKDIR/regular"
+EMPTY_FILE="$WORKDIR/empty"
+EXECUTABLE_FILE="$WORKDIR/executable"
+PERM_FILE="$WORKDIR/no-perm"
+FIFO_PATH="$WORKDIR/fifo"
+LINK_PATH="$WORKDIR/link"
+HARDLINK_PATH="$WORKDIR/hardlink"
+DIR_PATH="$WORKDIR/dir"
+STICKY_DIR="$WORKDIR/sticky"
+OLDER_FILE="$WORKDIR/older"
+NEWER_FILE="$WORKDIR/newer"
+MODE_FILE="$WORKDIR/mode"
+
+printf 'payload\n' >"$REGULAR_FILE"
+: >"$EMPTY_FILE"
+printf '#!/bin/sh\nexit 0\n' >"$EXECUTABLE_FILE"
+chmod 0755 "$EXECUTABLE_FILE"
+: >"$PERM_FILE"
+chmod 0000 "$PERM_FILE"
+mkfifo "$FIFO_PATH"
+ln -s "$REGULAR_FILE" "$LINK_PATH"
+ln "$REGULAR_FILE" "$HARDLINK_PATH"
+mkdir "$DIR_PATH"
+mkdir "$STICKY_DIR"
+chmod 1777 "$STICKY_DIR"
+: >"$MODE_FILE"
+chmod 6755 "$MODE_FILE"
+: >"$OLDER_FILE"
+sleep 1
+: >"$NEWER_FILE"
+
+run_capture "$TEST_BIN" -e "$REGULAR_FILE"
+assert_status "file exists status" 0 "$LAST_STATUS"
+assert_empty "file exists stdout" "$LAST_STDOUT"
+assert_empty "file exists stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -f "$REGULAR_FILE"
+assert_status "regular file status" 0 "$LAST_STATUS"
+assert_empty "regular file stdout" "$LAST_STDOUT"
+assert_empty "regular file stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -d "$DIR_PATH"
+assert_status "directory status" 0 "$LAST_STATUS"
+assert_empty "directory stdout" "$LAST_STDOUT"
+assert_empty "directory stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -s "$REGULAR_FILE"
+assert_status "size greater than zero status" 0 "$LAST_STATUS"
+assert_empty "size greater than zero stdout" "$LAST_STDOUT"
+assert_empty "size greater than zero stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -s "$EMPTY_FILE"
+assert_status "size zero status" 1 "$LAST_STATUS"
+assert_empty "size zero stdout" "$LAST_STDOUT"
+assert_empty "size zero stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -p "$FIFO_PATH"
+assert_status "fifo status" 0 "$LAST_STATUS"
+assert_empty "fifo stdout" "$LAST_STDOUT"
+assert_empty "fifo stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -L "$LINK_PATH"
+assert_status "symlink L status" 0 "$LAST_STATUS"
+assert_empty "symlink L stdout" "$LAST_STDOUT"
+assert_empty "symlink L stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -h "$LINK_PATH"
+assert_status "symlink h status" 0 "$LAST_STATUS"
+assert_empty "symlink h stdout" "$LAST_STDOUT"
+assert_empty "symlink h stderr" "$LAST_STDERR"
+
+SOCKET_PATH=$(find_socket_path || true)
+if [ -n "$SOCKET_PATH" ]; then
+ run_capture "$TEST_BIN" -S "$SOCKET_PATH"
+ assert_status "socket status" 0 "$LAST_STATUS"
+ assert_empty "socket stdout" "$LAST_STDOUT"
+ assert_empty "socket stderr" "$LAST_STDERR"
+else
+ skip "socket positive test skipped because no UNIX socket path is visible"
+fi
+
+run_capture "$TEST_BIN" -O "$REGULAR_FILE"
+assert_status "owner matches euid status" 0 "$LAST_STATUS"
+assert_empty "owner matches euid stdout" "$LAST_STDOUT"
+assert_empty "owner matches euid stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -G "$REGULAR_FILE"
+assert_status "group matches egid status" 0 "$LAST_STATUS"
+assert_empty "group matches egid stdout" "$LAST_STDOUT"
+assert_empty "group matches egid stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -u "$MODE_FILE"
+assert_status "setuid bit status" 0 "$LAST_STATUS"
+assert_empty "setuid bit stdout" "$LAST_STDOUT"
+assert_empty "setuid bit stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -g "$MODE_FILE"
+assert_status "setgid bit status" 0 "$LAST_STATUS"
+assert_empty "setgid bit stdout" "$LAST_STDOUT"
+assert_empty "setgid bit stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -k "$STICKY_DIR"
+assert_status "sticky bit status" 0 "$LAST_STATUS"
+assert_empty "sticky bit stdout" "$LAST_STDOUT"
+assert_empty "sticky bit stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -r "$REGULAR_FILE"
+assert_status "readable status" 0 "$LAST_STATUS"
+assert_empty "readable stdout" "$LAST_STDOUT"
+assert_empty "readable stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -w "$REGULAR_FILE"
+assert_status "writable status" 0 "$LAST_STATUS"
+assert_empty "writable stdout" "$LAST_STDOUT"
+assert_empty "writable stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -x "$EXECUTABLE_FILE"
+assert_status "executable status" 0 "$LAST_STATUS"
+assert_empty "executable stdout" "$LAST_STDOUT"
+assert_empty "executable stderr" "$LAST_STDERR"
+
+if [ "$(id -u)" -ne 0 ]; then
+ run_capture "$TEST_BIN" -r "$PERM_FILE"
+ assert_status "unreadable status" 1 "$LAST_STATUS"
+ assert_empty "unreadable stdout" "$LAST_STDOUT"
+ assert_empty "unreadable stderr" "$LAST_STDERR"
+
+ run_capture "$TEST_BIN" -w "$PERM_FILE"
+ assert_status "unwritable status" 1 "$LAST_STATUS"
+ assert_empty "unwritable stdout" "$LAST_STDOUT"
+ assert_empty "unwritable stderr" "$LAST_STDERR"
+else
+ skip "permission-negative tests skipped for euid 0"
+fi
+
+run_capture "$TEST_BIN" "$NEWER_FILE" -nt "$OLDER_FILE"
+assert_status "newer-than status" 0 "$LAST_STATUS"
+assert_empty "newer-than stdout" "$LAST_STDOUT"
+assert_empty "newer-than stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" "$OLDER_FILE" -ot "$NEWER_FILE"
+assert_status "older-than status" 0 "$LAST_STATUS"
+assert_empty "older-than stdout" "$LAST_STDOUT"
+assert_empty "older-than stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" "$REGULAR_FILE" -ef "$HARDLINK_PATH"
+assert_status "same file status" 0 "$LAST_STATUS"
+assert_empty "same file stdout" "$LAST_STDOUT"
+assert_empty "same file stderr" "$LAST_STDERR"
+
+run_capture "$TEST_BIN" -c /dev/null
+assert_status "character device status" 0 "$LAST_STATUS"
+assert_empty "character device stdout" "$LAST_STDOUT"
+assert_empty "character device stderr" "$LAST_STDERR"
+
+BLOCK_DEVICE_FOUND=
+for candidate in /dev/* /dev/*/*; do
+ if [ -b "$candidate" ]; then
+ BLOCK_DEVICE_FOUND=$candidate
+ break
+ fi
+done
+if [ -n "${BLOCK_DEVICE_FOUND:-}" ]; then
+ run_capture "$TEST_BIN" -b "$BLOCK_DEVICE_FOUND"
+ assert_status "block device status" 0 "$LAST_STATUS"
+ assert_empty "block device stdout" "$LAST_STDOUT"
+ assert_empty "block device stderr" "$LAST_STDERR"
+else
+ skip "block-device positive test skipped because no block device is visible"
+fi
+
+run_capture "$TEST_BIN" -t 99
+assert_status "closed fd tty status" 1 "$LAST_STATUS"
+assert_empty "closed fd tty stdout" "$LAST_STDOUT"
+assert_empty "closed fd tty stderr" "$LAST_STDERR"
+
+run_capture "$FD_HELPER_BIN" 9 "$TEST_BIN" -t 9
+case $LAST_STATUS in
+ 0)
+ assert_empty "pty fd tty stdout" "$LAST_STDOUT"
+ assert_empty "pty fd tty stderr" "$LAST_STDERR"
+ ;;
+ 1)
+ run_capture "$FD_HELPER_BIN" 9 "$SHELL_BIN" -c 'test -t 9'
+ case $LAST_STATUS in
+ 1)
+ skip "pty-backed -t positive test skipped because shell test also reports non-tty"
+ ;;
+ 126)
+ case $LAST_STDERR in
+ *"posix_openpt"*|*"grantpt"*|*"unlockpt"*|*"ptsname"*|*"open slave pty"*|*"isatty"*)
+ skip "pty-backed -t positive test skipped because PTY checks are blocked"
+ ;;
+ *)
+ fail "pty helper unexpected failure: $LAST_STDERR"
+ ;;
+ esac
+ ;;
+ *)
+ fail "pty fd tty status mismatch: test returned 1 but shell test -t returned $LAST_STATUS"
+ ;;
+ esac
+ ;;
+ 126)
+ case $LAST_STDERR in
+ *"posix_openpt"*|*"grantpt"*|*"unlockpt"*|*"ptsname"*|*"open slave pty"*|*"isatty"*)
+ skip "pty-backed -t positive test skipped because PTY checks are blocked"
+ ;;
+ *)
+ fail "pty helper unexpected failure: $LAST_STDERR"
+ ;;
+ esac
+ ;;
+ *)
+ fail "pty helper unexpected status: $LAST_STATUS"
+ ;;
+esac
+
+run_capture "$BRACKET_BIN" alpha = alpha ']'
+assert_status "bracket true status" 0 "$LAST_STATUS"
+assert_empty "bracket true stdout" "$LAST_STDOUT"
+assert_empty "bracket true stderr" "$LAST_STDERR"
+
+run_capture "$BRACKET_BIN" ']'
+assert_status "bracket empty expression status" 1 "$LAST_STATUS"
+assert_empty "bracket empty expression stdout" "$LAST_STDOUT"
+assert_empty "bracket empty expression stderr" "$LAST_STDERR"
+
+run_capture "$BRACKET_BIN" alpha = alpha
+assert_status "missing closing bracket status" 2 "$LAST_STATUS"
+assert_empty "missing closing bracket stdout" "$LAST_STDOUT"
+assert_eq "missing closing bracket stderr" "[: missing ']'" "$LAST_STDERR"
+
+run_in_shell "TEST_BIN='$TEST_BIN' sh '$ROOT/tests/legacy_test.sh'"
+assert_status "legacy suite status" 0 "$LAST_STATUS"
+assert_contains "legacy suite stdout" "$LAST_STDOUT" "1..130"
+assert_contains "legacy suite stdout" "$LAST_STDOUT" "PASS"
+assert_empty "legacy suite stderr" "$LAST_STDERR"
+
+printf '%s\n' "PASS"