102 lines
3.1 KiB
Bash
102 lines
3.1 KiB
Bash
#!/bin/sh
|
|
set -eu
|
|
|
|
tool=${1:-zig-out/bin/pick}
|
|
tmp=${TMPDIR:-.zig-cache}/pick-smoke.$$
|
|
mkdir -p "$tmp"
|
|
trap 'rm -rf "$tmp"' EXIT HUP INT TERM
|
|
|
|
# req: pick/008
|
|
# req: pick/009
|
|
# req: pick/010
|
|
|
|
assert_eq() {
|
|
want=$1
|
|
got=$2
|
|
cmp "$want" "$got"
|
|
}
|
|
|
|
assert_empty() {
|
|
file=$1
|
|
if [ -s "$file" ]; then
|
|
echo "pick: expected empty file: $file" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
assert_fails() {
|
|
if "$@"; then
|
|
echo "pick: command unexpectedly succeeded: $*" >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Numeric field selection preserves records and stdout contains only selected TSV.
|
|
printf 'a\tb\tc\n1\t2\t3\n' | "$tool" 2 > "$tmp/pick-one.out"
|
|
printf 'b\n2\n' > "$tmp/pick-one.want"
|
|
assert_eq "$tmp/pick-one.want" "$tmp/pick-one.out"
|
|
|
|
# Header selection emits the selected header and selected data columns.
|
|
printf 'path\tsize\tkind\na\t10\tfile\n' | "$tool" --header path size > "$tmp/pick-header.out"
|
|
printf 'path\tsize\na\t10\n' > "$tmp/pick-header.want"
|
|
assert_eq "$tmp/pick-header.want" "$tmp/pick-header.out"
|
|
|
|
# Missing fields are empty fields, not pipeline failures.
|
|
printf 'a\tb\n1\n' | "$tool" 1 2 > "$tmp/pick-missing.out"
|
|
printf 'a\tb\n1\t\n' > "$tmp/pick-missing.want"
|
|
assert_eq "$tmp/pick-missing.want" "$tmp/pick-missing.out"
|
|
|
|
# CRLF input is accepted and normalized to LF records.
|
|
printf 'a\tb\r\n1\t2\r\n' | "$tool" 2 > "$tmp/pick-crlf.out"
|
|
printf 'b\n2\n' > "$tmp/pick-crlf.want"
|
|
assert_eq "$tmp/pick-crlf.want" "$tmp/pick-crlf.out"
|
|
|
|
# A record longer than the internal read buffer still streams correctly across
|
|
# chunk boundaries without whole-input buffering.
|
|
: > "$tmp/pick-long.in"
|
|
i=0
|
|
while [ "$i" -lt 9000 ]; do
|
|
printf x >> "$tmp/pick-long.in"
|
|
i=$((i + 1))
|
|
done
|
|
printf '\tb\n' >> "$tmp/pick-long.in"
|
|
"$tool" 2 < "$tmp/pick-long.in" > "$tmp/pick-long.out"
|
|
printf 'b\n' > "$tmp/pick-long.want"
|
|
assert_eq "$tmp/pick-long.want" "$tmp/pick-long.out"
|
|
|
|
# Help is stdout-only and successful.
|
|
"$tool" --help > "$tmp/pick-help.out" 2> "$tmp/pick-help.err"
|
|
grep -q '^usage: pick' "$tmp/pick-help.out"
|
|
assert_empty "$tmp/pick-help.err"
|
|
|
|
# Usage errors are stderr-only and nonzero.
|
|
assert_fails "$tool" > "$tmp/pick-noargs.out" 2> "$tmp/pick-noargs.err"
|
|
assert_empty "$tmp/pick-noargs.out"
|
|
grep -q '^usage: pick' "$tmp/pick-noargs.err"
|
|
|
|
assert_fails "$tool" 0 > "$tmp/pick-zero.out" 2> "$tmp/pick-zero.err"
|
|
assert_empty "$tmp/pick-zero.out"
|
|
grep -q 'fields are 1-based' "$tmp/pick-zero.err"
|
|
|
|
assert_fails "$tool" nope > "$tmp/pick-invalid.out" 2> "$tmp/pick-invalid.err"
|
|
assert_empty "$tmp/pick-invalid.out"
|
|
grep -q 'invalid field' "$tmp/pick-invalid.err"
|
|
|
|
# Forbidden near miss: option-looking regex/expression input is rejected as data,
|
|
# not interpreted as another command language.
|
|
assert_fails "$tool" --regex '.*' > "$tmp/pick-regex.out" 2> "$tmp/pick-regex.err"
|
|
assert_empty "$tmp/pick-regex.out"
|
|
grep -q 'invalid field' "$tmp/pick-regex.err"
|
|
|
|
# Head-style consumers may close stdout early; that must not pollute stderr.
|
|
i=0
|
|
{
|
|
while [ "$i" -lt 20000 ]; do
|
|
printf 'a\tb\n'
|
|
i=$((i + 1))
|
|
done
|
|
} | "$tool" 1 2> "$tmp/pick-head.err" | sed 1q > "$tmp/pick-head.out"
|
|
printf 'a\n' > "$tmp/pick-head.want"
|
|
assert_eq "$tmp/pick-head.want" "$tmp/pick-head.out"
|
|
assert_empty "$tmp/pick-head.err"
|