# Tests for string builtin. Mostly taken from man page examples.

echo '# string match -r -v "c.*" dog can cat diz'
string match -r -v "c.*" dog can cat diz; and echo "exit 0"

echo
echo '# string match -q -r -v "c.*" dog can cat diz'
string match -q -r -v "c.*" dog can cat diz; and echo "exit 0"

echo
echo '# string match -v "c*" dog can cat diz'
string match -v "c*" dog can cat diz; and echo "exit 0"

echo
echo '# string match -q -v "c*" dog can cat diz'
string match -q -v "c*" dog can cat diz; and echo "exit 0"

echo
echo '# string match -v "d*" dog dan dat diz'
string match -v "d*" dog dan dat diz; or echo "exit 1"

echo
echo '# string match -q -v "d*" dog dan dat diz'
string match -q -v "d*" dog dan dat diz; or echo "exit 1"

echo
echo '# string match -r -v x y'
string match -r -v x y; and echo "exit 0"

echo
echo '# string match -r -v x x'
string match -r -v x x; or echo "exit 1"

echo
echo '# string match -q -r -v x y'
string match -q -r -v x y; and echo "exit 0"

echo
echo '# string match -q -r -v x x'
string match -q -r -v x x; or echo "exit 1"

echo
echo '# string length "hello, world"'
string length "hello, world"

echo
echo '# string length -q ""'
string length -q ""; and echo not zero length; or echo zero length

echo
echo '# string sub --length 2 abcde'
string sub --length 2 abcde

echo
echo '# string sub -s 2 -l 2 abcde'
string sub -s 2 -l 2 abcde

echo
echo '# string sub --start=-2 abcde'
string sub --start=-2 abcde

echo
echo '# string split . example.com'
string split . example.com

echo
echo '# string split -r -m1 / /usr/local/bin/fish'
string split -r -m1 / /usr/local/bin/fish

echo
echo '# string split "" abc'
string split "" abc

echo
echo '# seq 3 | string join ...'
seq 3 | string join ...

echo
echo '# string trim " abc  "'
string trim " abc  "

echo
echo '# string trim --right --chars=yz xyzzy zany'
string trim --right --chars=yz xyzzy zany

echo
echo '# echo \x07 | string escape'
echo \x07 | string escape

echo
echo '# string escape --style=script \'a b#c"\\\'d\''
string escape --style=script 'a b#c"\'d'

echo
echo '# string escape --style=url \'a b#c"\\\'d\''
string escape --style=url 'a b#c"\'d'

echo
echo '# string escape --style=url \\na\\nb%c~d\\n'
string escape --style=url \na\nb%c~d\n

echo
echo '# string escape --style=var \'a b#c"\\\'d\''
string escape --style=var 'a b#c"\'d'

echo
echo '# string escape --style=script a\nghi_'
string escape --style=var a\nghi_

echo
echo '# string escape --style=var \'abc\''
string escape --style=var 'abc'

echo
echo '# string escape --style=var \'_a_b_c_\''
string escape --style=var '_a_b_c_'

echo
echo '# string escape --style=var -- -'
string escape --style=var -- -

# The following tests verify that we can correctly unescape the same strings
# we tested escaping above.

echo
echo '# set x (string unescape (echo \x07 | string escape))'
set x (string unescape (echo \x07 | string escape))
test $x = \x07
and echo success

echo
echo '# string unescape --style=script (string escape --style=script \'a b#c"\\\'d\')'
string unescape --style=script (string escape --style=script 'a b#c"\'d')

echo
echo '# string unescape --style=url (string escape --style=url \'a b#c"\\\'d\')'
string unescape --style=url (string escape --style=url 'a b#c"\'d')

echo
echo '# 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)

echo
echo '# string unescape --style=var (string escape --style=var \'a b#c"\\\'d\')'
string unescape --style=var (string escape --style=var 'a b#c"\'d')

echo
echo '# string unescape --style=var (string escape --style=var a\nghi_)'
string unescape --style=var (string escape --style=var a\nghi_)

echo
echo '# string unescape --style=var (string escape --style=var \'abc\')'
string unescape --style=var (string escape --style=var 'abc')

echo
echo '# string unescape --style=var (string escape --style=var \'_a_b_c_\')'
string unescape --style=var (string escape --style=var '_a_b_c_')

echo
echo '# 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.

echo
echo '# string match "?" a'
string match "?" a

echo
echo '# string match "a*b" axxb'
string match "a*b" axxb

echo
echo '# string match -i "a??B" Axxb'
string match -i "a??B" Axxb

echo
echo '# echo "ok?" | string match "*\?"'
echo "ok?" | string match "*\?"

echo
echo '# string match -r "cat|dog|fish" "nice dog"'
string match -r "cat|dog|fish" "nice dog"

echo
echo '# string match -r "(\d\d?):(\d\d):(\d\d)" 2:34:56'
string match -r "(\d\d?):(\d\d):(\d\d)" 2:34:56

echo
echo '# string match -r "^(\w{2,4})\g1\$" papa mud murmur'
string match -r "^(\w{2,4})\g1\$" papa mud murmur

echo
echo '# string match -r -a -n at ratatat'
string match -r -a -n at ratatat

echo
echo '# 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;"

echo
echo '# string replace is was "blue is my favorite"'
string replace is was "blue is my favorite"

echo
echo '# string replace 3rd last 1st 2nd 3rd'
string replace 3rd last 1st 2nd 3rd

echo
echo '# string replace -a " " _ "spaces to underscores"'
string replace -a " " _ "spaces to underscores"

echo
echo '# string replace -r -a "[^\d.]+" " " "0 one two 3.14 four 5x"'
string replace -r -a "[^\d.]+" " " "0 one two 3.14 four 5x"

echo
echo '# string replace -r "(\w+)\s+(\w+)" "\$2 \$1 \$\$" "left right"'
string replace -r "(\w+)\s+(\w+)" "\$2 \$1 \$\$" "left right"

echo
echo '# string replace -r "\s*newline\s*" "\n" "put a newline here"'
string replace -r "\s*newline\s*" "\n" "put a newline here"

echo
echo '# string replace -r -a "(\w)" "\$1\$1" ab'
string replace -r -a "(\w)" "\$1\$1" ab

echo
echo '# 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)

echo
echo '# 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)

# test some failure cases
echo '# string match -r "[" "a[sd"' >&2
string match -r "[" "a[sd"; and echo "unexpected exit 0" >&2

echo >&2
echo '# string invalidarg' >&2
string invalidarg; and echo "unexpected exit 0" >&2

echo
echo '# string length'
string length; or echo "missing argument returns 1"

echo
echo '# string match -r -v "[dcantg].*" dog can cat diz'
string match -r -v "[dcantg].*" dog can cat diz; or echo "no regexp invert match"

echo
echo '# string match -v "???" dog can cat diz'
string match -v "???" dog can cat diz; or echo "no glob invert match"

echo
echo '# string match -rvn a bbb'
string match -rvn a bbb; or echo "exit 1"

# test repeat subcommand
echo
echo '# string repeat -n 2 "foo"'
string repeat -n 2 "foo"

echo
echo '# string repeat --count 2 "foo"'
string repeat --count 2 "foo"

echo
echo '# echo foo | string repeat -n 2'
echo foo | string repeat -n 2

echo
echo '# string repeat -n2 -q "foo"'
string repeat -n2 -q "foo"; and echo "exit 0"

echo
echo '# string repeat -n2 --quiet "foo"'
string repeat -n2 --quiet "foo"; and echo "exit 0"

echo
echo '# string repeat -n0 "foo"'
string repeat -n0 "foo"; or echo "exit 1"

echo
echo '# string repeat -n0'
string repeat -n0; or echo "exit 1"

echo
echo '# string repeat -m0'
string repeat -m0; or echo "exit 1"

echo
echo '# string repeat -n1 -N "there is "'
string repeat -n1 -N "there is "; echo "no newline"

echo
echo '# string repeat -n1 --no-newline "there is "'
string repeat -n1 --no-newline "there is "; echo "no newline"

echo
echo '# string repeat -n10 -m4 "foo"'
string repeat -n10 -m4 "foo"

echo
echo '# string repeat -n10 --max 5 "foo"'
string repeat -n10 --max 5 "foo"

echo
echo '# string repeat -n3 -m20 "foo"'
string repeat -n3 -m20 "foo"

echo
echo '# string repeat -m4 "foo"'
string repeat -m4 "foo"

echo >&2
echo '# string repeat -n-1 "foo"' >&2
string repeat -n-1 "foo"; and echo "exit 0" >&2

echo >&2
echo '# string repeat -m-1 "foo"' >&2
string repeat -m-1 "foo"; and echo "exit 0" >&2

echo >&2
echo '# string repeat -n notanumber "foo"' >&2
string repeat -n notanumber "foo"; and echo "exit 0" >&2

echo >&2
echo '# string repeat -m notanumber "foo"' >&2
string repeat -m notanumber "foo"; and echo "exit 0" >&2

echo >&2
echo '# echo "stdin" | string repeat -n1 "and arg"' >&2
echo "stdin" | string repeat -n1 "and arg"; and echo "exit 0" >&2

echo >&2
echo '# string repeat -n' >&2
string repeat -n; and echo "exit 0" >&2

echo >&2
echo '# string repeat -l fakearg 2>&1' >&2
string repeat -l fakearg

echo
echo '# string repeat ""'
string repeat ""
or echo string repeat empty string failed

echo
echo '# string repeat -n3 ""'
string repeat -n3 ""
or echo string repeat empty string failed

# Test equivalent matches with/without the --entire, --regex, and --invert flags.
echo
echo '# string match -e x abc dxf xyz jkx x z'
string match -e x abc dxf xyz jkx x z
or echo exit 1

echo
echo '# string match x abc dxf xyz jkx x z'
string match x abc dxf xyz jkx x z

echo
echo '# 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

echo
echo '# 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.
echo
echo '# 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

echo
echo '# 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

exit 0
