fish-shell/tests/string.in
Lily Ballard 181e44d331 Invert the flag for string collect
Instead of requiring a flag to enable newline trimming, invert it so the
flag (now `--no-trim-newlines`) disables newline trimming. This way our
default behavior matches that of sh's `"$(cmd)"`.

Also change newline trimming to trim all newlines instead of just one,
again to match sh's behavior.
2019-06-16 16:40:14 -07:00

422 lines
14 KiB
Fish

# Tests for string builtin. Mostly taken from man page examples.
logmsg 'string match -r -v "c.*" dog can cat diz'
string match -r -v "c.*" dog can cat diz; and echo "exit 0"
logmsg 'string match -q -r -v "c.*" dog can cat diz'
string match -q -r -v "c.*" dog can cat diz; and echo "exit 0"
logmsg 'string match -v "c*" dog can cat diz'
string match -v "c*" dog can cat diz; and echo "exit 0"
logmsg 'string match -q -v "c*" dog can cat diz'
string match -q -v "c*" dog can cat diz; and echo "exit 0"
logmsg 'string match -v "d*" dog dan dat diz'
string match -v "d*" dog dan dat diz; or echo "exit 1"
logmsg 'string match -q -v "d*" dog dan dat diz'
string match -q -v "d*" dog dan dat diz; or echo "exit 1"
logmsg 'string match -r -v x y'
string match -r -v x y; and echo "exit 0"
logmsg 'string match -r -v x x'
string match -r -v x x; or echo "exit 1"
logmsg 'string match -q -r -v x y'
string match -q -r -v x y; and echo "exit 0"
logmsg 'string match -q -r -v x x'
string match -q -r -v x x; or echo "exit 1"
logmsg 'string length "hello, world"'
string length "hello, world"
logmsg 'string length -q ""'
string length -q ""; and echo not zero length; or echo zero length
logmsg 'string sub --length 2 abcde'
string sub --length 2 abcde
logmsg 'string sub -s 2 -l 2 abcde'
string sub -s 2 -l 2 abcde
logmsg 'string sub --start=-2 abcde'
string sub --start=-2 abcde
logmsg 'string split . example.com'
string split . example.com
logmsg 'string split -r -m1 / /usr/local/bin/fish'
string split -r -m1 / /usr/local/bin/fish
logmsg 'string split "" abc'
string split "" abc
logmsg 'seq 3 | string join ...'
seq 3 | string join ...
logmsg 'string trim " abc "'
string trim " abc "
logmsg 'string trim --right --chars=yz xyzzy zany'
string trim --right --chars=yz xyzzy zany
logmsg 'echo \x07 | string escape'
echo \x07 | string escape
logmsg 'string escape --style=script \'a b#c"\\\'d\''
string escape --style=script 'a b#c"\'d'
logmsg 'string escape --style=url \'a b#c"\\\'d\''
string escape --style=url 'a b#c"\'d'
logmsg 'string escape --style=url \\na\\nb%c~d\\n'
string escape --style=url \na\nb%c~d\n
logmsg 'string escape --style=var \'a b#c"\\\'d\''
string escape --style=var 'a b#c"\'d'
logmsg 'string escape --style=script a\nghi_'
string escape --style=var a\nghi_
logmsg 'string escape --style=var \'abc\''
string escape --style=var 'abc'
logmsg 'string escape --style=var \'_a_b_c_\''
string escape --style=var '_a_b_c_'
logmsg 'string escape --style=var -- -'
string escape --style=var -- -
logmsg 'string escape with multibyte chars'
string escape --style=url aöb
string escape --style=url 中
string escape --style=url aöb | string unescape --style=url
string escape --style=url 中 | string unescape --style=url
string escape --style=var aöb
string escape --style=var 中
string escape --style=var aöb | string unescape --style=var
string escape --style=var 中 | string unescape --style=var
# test regex escaping
logmsg 'string escape for literal pcre2 searching'
string escape --style=regex ".ext"
string escape --style=regex "bonjour, amigo"
string escape --style=regex "^this is a literal string"
# The following tests verify that we can correctly unescape the same strings
# we tested escaping above.
logmsg 'set x (string unescape (echo \x07 | string escape))'
set x (string unescape (echo \x07 | string escape))
test $x = \x07
and echo success
logmsg 'string unescape --style=script (string escape --style=script \'a b#c"\\\'d\')'
string unescape --style=script (string escape --style=script 'a b#c"\'d')
logmsg 'string unescape --style=url (string escape --style=url \'a b#c"\\\'d\')'
string unescape --style=url (string escape --style=url 'a b#c"\'d')
logmsg 'string unescape --style=url (string escape --style=url \na\nb%c~d\n)'
string unescape --style=url (string escape --style=url \na\nb%c~d\n)
logmsg 'string unescape --style=var (string escape --style=var \'a b#c"\\\'d\')'
string unescape --style=var (string escape --style=var 'a b#c"\'d')
logmsg 'string unescape --style=var (string escape --style=var a\nghi_)'
string unescape --style=var (string escape --style=var a\nghi_)
logmsg 'string unescape --style=var (string escape --style=var \'abc\')'
string unescape --style=var (string escape --style=var 'abc')
logmsg 'string unescape --style=var (string escape --style=var \'_a_b_c_\')'
string unescape --style=var (string escape --style=var '_a_b_c_')
logmsg 'string unescape --style=var (string escape --style=var -- -)'
string unescape --style=var -- (string escape --style=var -- -)
# The following tests verify that we can correctly match strings.
logmsg 'string match "*" a'
string match "*" a
logmsg 'string match "a*b" axxb'
string match "a*b" axxb
logmsg 'string match -i "a**B" Axxb'
string match -i "a**B" Axxb
logmsg 'echo "ok?" | string match "*?"'
echo "ok?" | string match "*?"
logmsg 'string match -r "cat|dog|fish" "nice dog"'
string match -r "cat|dog|fish" "nice dog"
logmsg 'string match -r "(\d\d?):(\d\d):(\d\d)" 2:34:56'
string match -r "(\d\d?):(\d\d):(\d\d)" 2:34:56
logmsg 'string match -r "^(\w{2,4})\g1\$" papa mud murmur'
string match -r "^(\w{2,4})\g1\$" papa mud murmur
logmsg 'string match -r -a -n at ratatat'
string match -r -a -n at ratatat
logmsg 'string match -r -i "0x[0-9a-f]{1,8}" "int magic = 0xBadC0de;"'
string match -r -i "0x[0-9a-f]{1,8}" "int magic = 0xBadC0de;"
logmsg 'string replace is was "blue is my favorite"'
string replace is was "blue is my favorite"
logmsg 'string replace 3rd last 1st 2nd 3rd'
string replace 3rd last 1st 2nd 3rd
logmsg 'string replace -a " " _ "spaces to underscores"'
string replace -a " " _ "spaces to underscores"
logmsg 'string replace -r -a "[^\d.]+" " " "0 one two 3.14 four 5x"'
string replace -r -a "[^\d.]+" " " "0 one two 3.14 four 5x"
logmsg 'string replace -r "(\w+)\s+(\w+)" "\$2 \$1 \$\$" "left right"'
string replace -r "(\w+)\s+(\w+)" "\$2 \$1 \$\$" "left right"
logmsg 'string replace -r "\s*newline\s*" "\n" "put a newline here"'
string replace -r "\s*newline\s*" "\n" "put a newline here"
logmsg 'string replace -r -a "(\w)" "\$1\$1" ab'
string replace -r -a "(\w)" "\$1\$1" ab
logmsg 'string replace --filter x X abc axc x def jkx'
string replace --filter x X abc axc x def jkx
or echo Unexpected exit status at line (status --current-line-number)
string replace --filter y Y abc axc x def jkx
and echo Unexpected exit status at line (status --current-line-number)
logmsg 'string replace --regex -f "\d" X 1bc axc 2 d3f jk4 xyz'
string replace --regex -f "\d" X 1bc axc 2 d3f jk4 xyz
or echo Unexpected exit status at line (status --current-line-number)
string replace --regex -f "Z" X 1bc axc 2 d3f jk4 xyz
and echo Unexpected exit status at line (status --current-line-number)
# From https://github.com/fish-shell/fish-shell/issues/5201
logmsg 'string match -r with empty capture groups'
string match -r '^([ugoa]*)([=+-]?)([rwx]*)$' '=r'
# test some failure cases
logmsg 'string match -r "[" "a[sd"'
string match -r "[" "a[sd"; and echo "unexpected exit 0"
logmsg 'string invalidarg'
string invalidarg; and echo "unexpected exit 0"
logmsg 'string length'
string length; or echo "missing argument returns 1"
logmsg 'string match -r -v "[dcantg].*" dog can cat diz'
string match -r -v "[dcantg].*" dog can cat diz; or echo "no regexp invert match"
logmsg 'string match -v "*" dog can cat diz'
string match -v "*" dog can cat diz; or echo "no glob invert match"
logmsg 'string match -rvn a bbb'
string match -rvn a bbb; or echo "exit 1"
# test repeat subcommand
logmsg 'string repeat -n 2 "foo"'
string repeat -n 2 "foo"
logmsg 'string repeat --count 2 "foo"'
string repeat --count 2 "foo"
logmsg 'echo foo | string repeat -n 2'
echo foo | string repeat -n 2
logmsg 'string repeat -n2 -q "foo"'
string repeat -n2 -q "foo"; and echo "exit 0"
logmsg 'string repeat -n2 --quiet "foo"'
string repeat -n2 --quiet "foo"; and echo "exit 0"
logmsg 'string repeat -n0 "foo"'
string repeat -n0 "foo"; or echo "exit 1"
logmsg 'string repeat -n0'
string repeat -n0; or echo "exit 1"
logmsg 'string repeat -m0'
string repeat -m0; or echo "exit 1"
logmsg 'string repeat -n1 -N "there is "'
string repeat -n1 -N "there is "; echo "no newline"
logmsg 'string repeat -n1 --no-newline "there is "'
string repeat -n1 --no-newline "there is "; echo "no newline"
logmsg 'string repeat -n10 -m4 "foo"'
string repeat -n10 -m4 "foo"
logmsg 'string repeat -n10 --max 5 "foo"'
string repeat -n10 --max 5 "foo"
logmsg 'string repeat -n3 -m20 "foo"'
string repeat -n3 -m20 "foo"
logmsg 'string repeat -m4 "foo"'
string repeat -m4 "foo"
logmsg 'string repeat -n-1 "foo"'
string repeat -n-1 "foo"; and echo "exit 0"
logmsg 'string repeat -m-1 "foo"'
string repeat -m-1 "foo"; and echo "exit 0"
logmsg 'string repeat -n notanumber "foo"'
string repeat -n notanumber "foo"; and echo "exit 0"
logmsg 'string repeat -m notanumber "foo"'
string repeat -m notanumber "foo"; and echo "exit 0"
logmsg 'echo "stdin" | string repeat -n1 "and arg"'
echo "stdin" | string repeat -n1 "and arg"; and echo "exit 0"
logmsg 'string repeat -n'
string repeat -n; and echo "exit 0"
logmsg 'string repeat -l fakearg 2>&1'
string repeat -l fakearg
logmsg 'string repeat ""'
string repeat ""
or echo string repeat empty string failed
logmsg 'string repeat -n3 ""'
string repeat -n3 ""
or echo string repeat empty string failed
# Test equivalent matches with/without the --entire, --regex, and --invert flags.
logmsg 'string match -e x abc dxf xyz jkx x z'
string match -e x abc dxf xyz jkx x z
or echo exit 1
logmsg 'string match x abc dxf xyz jkx x z'
string match x abc dxf xyz jkx x z
logmsg 'string match --entire -r "a*b[xy]+" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz'
string match --entire -r "a*b[xy]+" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz
or echo exit 1
logmsg 'string match --entire "" -- banana'
string match --entire "" -- banana
or echo exit 1
logmsg 'string match -r "a*b[xy]+" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz'
string match -r "a*b[xy]+" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz
or echo exit 1
# Make sure that groups are handled correct with/without --entire.
logmsg 'string match --entire -r "a*b([xy]+)" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz'
string match --entire -r "a*b([xy]+)" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz
or echo exit 1
logmsg 'string match -r "a*b([xy]+)" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz'
string match -r "a*b([xy]+)" abc abxc bye aaabyz kaabxz abbxy abcx caabxyxz
or echo exit 1
# Test `string lower` and `string upper`.
set x (string lower abc DEF gHi)
or echo string lower exit 1
test $x[1] = 'abc' -a $x[2] = 'def' -a $x[3] = 'ghi'
or echo strings not converted to lowercase
set x (echo abc DEF gHi | string lower)
or echo string lower exit 1
test $x[1] = 'abc def ghi'
or echo strings not converted to lowercase
string lower -q abc
and echo lowercasing a lowercase string did not fail as expected
set x (string upper abc DEF gHi)
or echo string upper exit 1
test $x[1] = 'ABC' -a $x[2] = 'DEF' -a $x[3] = 'GHI'
or echo strings not converted to uppercase
set x (echo abc DEF gHi | string upper)
or echo string upper exit 1
test $x[1] = 'ABC DEF GHI'
or echo strings not converted to uppercase
string upper -q ABC DEF
and echo uppercasing a uppercase string did not fail as expected
logmsg 'Check NUL'
# Note: We do `string escape` at the end to make a `\0` literal visible.
printf 'a\0b' | string escape
printf 'a\0c' | string match -e 'a' | string escape
printf 'a\0d' | string split '' | string escape
printf 'a\0b' | string match -r '.*b$' | string escape
printf 'a\0b' | string replace b g | string escape
printf 'a\0b' | string replace -r b g | string escape
# TODO: These do not yet work!
# printf 'a\0b' | string match '*b' | string escape
logmsg string split0
count (echo -ne 'abcdefghi' | string split0)
count (echo -ne 'abc\x00def\x00ghi\x00' | string split0)
count (echo -ne 'abc\x00def\x00ghi\x00\x00' | string split0)
count (echo -ne 'abc\x00def\x00ghi' | string split0)
count (echo -ne 'abc\ndef\x00ghi\x00' | string split0)
count (echo -ne 'abc\ndef\nghi' | string split0)
# #5701 - split0 always returned 1
echo -ne 'a\x00b' | string split0
and echo Split something
logmsg string join0
set tmp beta alpha\ngamma
count (string join \n $tmp)
count (string join0 $tmp)
count (string join0 $tmp | string split0)
logmsg string split0 in functions
# This function outputs some newline-separated content, and some
# explicitly separated content.
function dualsplit
echo alpha
echo beta
echo -ne 'gamma\x00delta' | string split0
end
count (dualsplit)
logmsg string collect
count (echo one\ntwo\nthree\nfour | string collect)
count (echo one | string collect)
echo [(echo one\ntwo\nthree | string collect)]
echo [(echo one\ntwo\nthree | string collect -N)]
printf '[%s]\n' (string collect one\n\n two\n)
printf '[%s]\n' (string collect -N one\n\n two\n)
printf '[%s]\n' (string collect --no-trim-newlines one\n\n two\n)
# string collect returns 0 when it has any output, otherwise 1
string collect >/dev/null; and echo unexpected success; or echo expected failure
echo -n | string collect >/dev/null; and echo unexpected success; or echo expected failure
echo | string collect -N >/dev/null; and echo expected success; or echo unexpected failure
echo | string collect >/dev/null; and echo unexpected success; or echo expected failure
string collect a >/dev/null; and echo expected success; or echo unexpected failure
string collect -N '' >/dev/null; and echo unexpected success; or echo expected failure
string collect \n\n >/dev/null; and echo unexpected success; or echo expected failure
logmsg string collect in functions
# This function outputs some newline-separated content, and some
# explicitly un-separated content.
function dualcollect
echo alpha
echo beta
echo gamma\ndelta\nomega | string collect
end
count (dualcollect)
exit 0