mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-24 10:46:59 +08:00
4a7aa98e93
Fixes #4220
211 lines
5.7 KiB
Fish
211 lines
5.7 KiB
Fish
# vim: set filetype=fish:
|
|
#
|
|
# Test read builtin and IFS.
|
|
#
|
|
|
|
###########
|
|
# Start by testing that invocation errors are handled correctly.
|
|
echo '# Read with no vars is an error' >&2
|
|
read
|
|
echo '# Read with -a and anything other than exactly on var name is an error' >&2
|
|
read -a
|
|
read -a v1 v2
|
|
read -a v1
|
|
|
|
###########
|
|
# Verify correct behavior of subcommands and splitting of input.
|
|
count (echo one\ntwo)
|
|
set -l IFS \t
|
|
count (echo one\ntwo)
|
|
set -l IFS
|
|
count (echo one\ntwo)
|
|
echo [(echo -n one\ntwo)]
|
|
count (echo one\ntwo\n)
|
|
echo [(echo -n one\ntwo\n)]
|
|
count (echo one\ntwo\n\n)
|
|
echo [(echo -n one\ntwo\n\n)]
|
|
set -le IFS
|
|
|
|
function print_vars --no-scope-shadowing
|
|
set -l space
|
|
set -l IFS \n # ensure our command substitution works right
|
|
for var in $argv
|
|
echo -n $space (count $$var) \'$$var\'
|
|
set space ''
|
|
end
|
|
echo
|
|
end
|
|
|
|
echo
|
|
echo '# Test splitting input'
|
|
echo 'hello there' | read -l one two
|
|
print_vars one two
|
|
echo 'hello there' | read -l one
|
|
print_vars one
|
|
echo '' | read -l one
|
|
print_vars one
|
|
echo '' | read -l one two
|
|
print_vars one two
|
|
echo 'test' | read -l one two three
|
|
print_vars one two three
|
|
echo 'foo bar baz' | read -l one two three
|
|
print_vars one two three
|
|
echo -n 'a' | read -l one
|
|
echo "$status $one"
|
|
|
|
echo
|
|
echo '# Test splitting input with IFS empty'
|
|
set -l IFS
|
|
echo 'hello' | read -l one
|
|
print_vars one
|
|
echo 'hello' | read -l one two
|
|
print_vars one two
|
|
echo 'hello' | read -l one two three
|
|
print_vars one two three
|
|
echo '' | read -l one
|
|
print_vars one
|
|
echo 't' | read -l one two
|
|
print_vars one two
|
|
echo 't' | read -l one two three
|
|
print_vars one two three
|
|
echo ' t' | read -l one two
|
|
print_vars one two
|
|
set -le IFS
|
|
|
|
echo
|
|
echo 'hello there' | read -la ary
|
|
print_vars ary
|
|
echo 'hello' | read -la ary
|
|
print_vars ary
|
|
echo 'this is a bunch of words' | read -la ary
|
|
print_vars ary
|
|
echo ' one two three' | read -la ary
|
|
print_vars ary
|
|
echo '' | read -la ary
|
|
print_vars ary
|
|
|
|
echo
|
|
set -l IFS
|
|
echo 'hello' | read -la ary
|
|
print_vars ary
|
|
echo 'h' | read -la ary
|
|
print_vars ary
|
|
echo '' | read -la ary
|
|
print_vars ary
|
|
set -le IFS
|
|
|
|
# read -n tests
|
|
|
|
echo
|
|
echo '# read -n tests'
|
|
echo 'testing' | read -n 3 foo
|
|
echo $foo
|
|
echo 'test' | read -n 10 foo
|
|
echo $foo
|
|
echo 'test' | read -n 0 foo
|
|
echo $foo
|
|
echo 'testing' | begin; read -n 3 foo; read -n 3 bar; end
|
|
echo $foo
|
|
echo $bar
|
|
echo 'test' | read -n 1 foo
|
|
echo $foo
|
|
|
|
# read -0 tests
|
|
|
|
echo
|
|
echo '# read -z tests'
|
|
echo -n 'testing' | read -lz foo
|
|
echo $foo
|
|
echo -n 'test ing' | read -lz foo
|
|
echo $foo
|
|
echo 'newline' | read -lz foo
|
|
echo $foo
|
|
echo -n 'test ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'test\0ing' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'foo\nbar' | read -lz foo bar
|
|
print_vars foo bar
|
|
echo -ne 'foo\nbar\0baz\nquux' | while read -lza foo
|
|
print_vars foo
|
|
end
|
|
|
|
echo
|
|
echo '# chunked read tests'
|
|
set -l path /tmp/fish_chunked_read_test.txt
|
|
set -l longstr (seq 1024 | string join ',')
|
|
echo -n $longstr > $path
|
|
read -l longstr2 < $path
|
|
test "$longstr" = "$longstr2"
|
|
and echo "Chunked reads test pass"
|
|
or echo "Chunked reads test failure: long strings don't match!"
|
|
rm $path
|
|
|
|
# ==========
|
|
# The following tests verify that `read` correctly handles the limit on the
|
|
# number of bytes consumed.
|
|
#
|
|
set FISH_READ_BYTE_LIMIT 8192
|
|
set line abcdefghijklmnopqrstuvwxyz
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data. The var
|
|
# should be empty. We throw away any data we read if it exceeds the limit on
|
|
# what we consider reasonable.
|
|
yes $line | dd bs=1024 count=(math "1 + $FISH_READ_BYTE_LIMIT / 1024") ^/dev/null | read --null x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
# The read var should be defined but not have any elements when the read
|
|
# aborts due to too much data.
|
|
set -q x
|
|
or echo reading too much data did not define the var
|
|
set -q x[1]
|
|
and echo reading too much data resulted in a var with unexpected data
|
|
|
|
# Ensure the `read` command terminates if asked to read too much data even if
|
|
# given an explicit limit. The var should be empty. We throw away any data we
|
|
# read if it exceeds the limit on what we consider reasonable.
|
|
yes $line | read --null --nchars=(math "$FISH_READ_BYTE_LIMIT + 1") x
|
|
if test $status -ne 122
|
|
echo reading too much data did not terminate with failure status
|
|
end
|
|
set -q x
|
|
or echo reading too much data with --nchars did not define the var
|
|
set -q x[1]
|
|
and echo reading too much data with --nchars resulted in a var with unexpected data
|
|
|
|
# Now do the opposite of the previous test and confirm we can read reasonable
|
|
# amounts of data.
|
|
echo $line | read x
|
|
if test $status -ne 0
|
|
echo the read of a reasonable amount of data failed unexpectedly
|
|
end
|
|
set exp_length (string length $x)
|
|
set act_length (string length $line)
|
|
if test $exp_length -ne $act_length
|
|
echo reading a reasonable amount of data failed the length test
|
|
echo expected length $exp_length, actual length $act_length
|
|
end
|
|
|
|
# Confirm we can read exactly up to the limit.
|
|
yes $line | read --null --nchars $FISH_READ_BYTE_LIMIT x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data with --nchars failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $FISH_READ_BYTE_LIMIT
|
|
echo reading the max amount of data with --nchars failed the length test
|
|
end
|
|
|
|
# Same as previous test but limit the amount of data fed to `read` rather than
|
|
# using the `--nchars` flag.
|
|
yes $line | dd bs=1024 count=(math "$FISH_READ_BYTE_LIMIT / 1024") ^/dev/null | read --null x
|
|
if test $status -ne 0
|
|
echo the read of the max amount of data failed unexpectedly
|
|
end
|
|
if test (string length "$x") -ne $FISH_READ_BYTE_LIMIT
|
|
echo reading the max amount of data with --nchars failed the length test
|
|
end
|
|
|
|
echo '# Confirm reading non-interactively works (#4206 regression)'
|
|
echo abc\ndef | ../test/root/bin/fish -i -c 'read a; read b; show a; show b'
|