# Test suite for wordsplit -*- Autotest -*- # Copyright (C) 2014-2019 Sergey Poznyakoff # # Wordsplit is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # Wordsplit is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with wordsplit. If not, see . AT_TESTED(wsp) m4_pushdef([wspnum],[0]) m4_pushdef([wspid]) m4_pushdef([wspgroupnum]) m4_pushdef([wspgroupname]) m4_pushdef([genkw],[dnl m4_define([wspid],m4_format([wordsplit%03d wsp%03d],wspnum))dnl m4_if(wspgroupname,,,[m4_define([wspid],wspid[ ]dnl m4_format(wspgroupname[ ]wspgroupname[%03d],wspgroupnum))dnl m4_define([wspgroupnum],m4_incr(wspgroupnum))])dnl m4_define([wspnum],m4_incr(wspnum))dnl wspid]) m4_pushdef([WSPGROUP],[ m4_define([wspgroupname],$1) m4_define([wspgroupnum],0)]) dnl ------------------------------------------------------------ dnl TESTWSP([NAME], [KW = `'], [OPTS], [INPUT], [STDOUT = `'], dnl [STDERR = `'], [ENV], [PROLOGUE]) dnl m4_pushdef([TESTWSP],[ AT_SETUP([$1]) AT_KEYWORDS([wordsplit wsp ]genkw[ $2]) AT_CHECK([$8 $7 wsp $3 <<'EOT' [$4] EOT ], [0], [$5], [$6]) AT_CLEANUP ]) dnl ------------------------------------------------------------ dnl The first part reproduces legacy argcv tests dnl ------------------------------------------------------------ TESTWSP([simple input],[wsp-simple],[], [1 2 3], [NF: 3 0: 1 1: 2 2: 3 TOTAL: 3 ]) TESTWSP([quoted space],[wsp-quoted],[], [quoted\ space], [NF: 1 0: "quoted space" TOTAL: 1 ]) TESTWSP([tab character],[wsp-tab],[], [a "tab character"], [NF: 2 0: a 1: tab\tcharacter TOTAL: 2 ]) WSPGROUP(wsp-escape) TESTWSP([octal and hex escapes],[],[], [\157\143\164\141\154\40and\x20\x68\x65\x78], [NF: 1 0: "octal and hex" TOTAL: 1 ]) TESTWSP([octal and hex escapes 2],[],[], [\157\143\164\141\154\40 and \x20\x68\x65\x78], [NF: 3 0: "octal " 1: and 2: " hex" TOTAL: 3 ]) TESTWSP([escape representation],[],[], [A\x3-\48\39], [NF: 1 0: A\003-\0048\0039 TOTAL: 1 ]) WSPGROUP() dnl ------------------------------------------------------------ dnl Test worsplit-specific behavior dnl ------------------------------------------------------------ TESTWSP([append],[wsp-append],[-append], [jeden dwa trzy cztery piec szesc], [NF: 3 0: jeden 1: dwa 2: trzy TOTAL: 3 NF: 4 0: jeden 1: dwa 2: trzy 3: cztery TOTAL: 1 NF: 6 0: jeden 1: dwa 2: trzy 3: cztery 4: piec 5: szesc TOTAL: 2 ]) TESTWSP([dooffs],[wsp-doofs ],[-dooffs jeden dwa trzy], [cztery piec], [NF: 2 (3) (0): jeden (1): dwa (2): trzy 3: cztery 4: piec TOTAL: 2 ]) WSPGROUP(wsp-var) TESTWSP([variable substitutions: single var],[],[], [a $FOO test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([variable substitutions: concatenated vars],[], [], [a $FOO${BAR}ent test], [NF: 3 0: a 1: stringent 2: test TOTAL: 3 ], [], [FOO=str BAR=ing]) TESTWSP([variable substitutions: field splitting],[],[], [a $FOO test], [NF: 4 0: a 1: variable 2: substitution 3: test TOTAL: 4 ], [], [FOO="variable substitution"]) TESTWSP([variable substitutions: double-quoted variable],[],[], [a "$FOO" test], [NF: 3 0: a 1: "variable substitution" 2: test TOTAL: 3 ], [], [FOO="variable substitution"]) TESTWSP([variable substitutions: single-quoted variable],[],[], [a '$FOO' test], [NF: 3 0: a 1: $FOO 2: test TOTAL: 3 ], [], [FOO="variable substitution"]) TESTWSP([undefined variables 1],[],[], [a $FOO test a${FOO}b], [NF: 3 0: a 1: test 2: ab TOTAL: 3 ], [], [unset FOO;]) TESTWSP([undefined variables 2],[],[-keepundef], [a $FOO test a${FOO}b], [NF: 4 0: a 1: $FOO 2: test 3: a${FOO}b TOTAL: 4 ], [], [unset FOO;]) TESTWSP([warn about undefined variables],[],[-warnundef], [$FOO], [NF: 0 TOTAL: 0 ], [warning: undefined variable `FOO' ], [unset FOO;]) TESTWSP([bail out on undefined variables],[],[-undef], [$FOO], [], [undefined variable: FOO ], [unset FOO;]) TESTWSP([disable variable expansion],[],[-novar], [$FOO], [NF: 1 0: $FOO TOTAL: 1 ], [], [FOO=bar]) TESTWSP([K/V environment],[wsp-env-kv wsp-env_kv], [-env_kv], [$FOO a$BAZ], [NF: 2 0: bar 1: aqux TOTAL: 2 ], [], [FOO=bar BAZ=qux]) TESTWSP([nosplit with variable expansion],[wsp-var-nosplit],[-nosplit], [a $FOO test], [NF: 1 0: "a variable expansion test\n" TOTAL: 1 ], [], [FOO="variable expansion"]) TESTWSP([nosplit without variable expansion],[],[-nosplit -novar], [a $FOO test], [NF: 1 0: "a $FOO test\n" TOTAL: 1 ], [], [FOO="variable expansion"]) TESTWSP([nosplit: empty expansion],[],[-nosplit -trimnl], [$FOO], [NF: 1 0: "" TOTAL: 1 ], [], [FOO=""]) TESTWSP([default value],[],[], [${FOO:-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default value (defined)],[],[], [${FOO:-bar}], [NF: 1 0: qux TOTAL: 1 ], [], [FOO=qux]) TESTWSP([default value (:- null)],[],[], [${FOO:-bar}], [NF: 1 0: bar TOTAL: 1 ], [], [FOO=]) TESTWSP([default value (- null)],[],[], [${FOO-bar}], [NF: 0 TOTAL: 0 ], [], [FOO=]) TESTWSP([default value (- null, unset)],[],[], [${FOO-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([assign default values],[],[], [${FOO=bar} $FOO], [NF: 1 0: bar TOTAL: 1 NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default error message (var defined)],[],[], [a ${FOO:?} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([default error message],[],[], [${FOO:?}], [NF: 0 TOTAL: 0 ], [FOO: variable null or not set ]) TESTWSP([custom error message (defined)],[wsp-custom-err wsp-custom-err00],[], [a ${FOO:?please define it} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([custom error message],[wsp-custom-err wsp-custom-err01],[], [a ${FOO:?please define it} test], [NF: 2 0: a 1: test TOTAL: 2 ], [FOO: please define it ]) TESTWSP([alternate value (defined)],[wsp-alt wsp-alt00],[], [a ${FOO:+isset} test], [NF: 3 0: a 1: isset 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([alternate value],[wsp-alt wsp-alt01],[], [a ${FOO:+isset} test], [NF: 2 0: a 1: test TOTAL: 2 ], [], [unset FOO;]) TESTWSP([getvar],[wsp-getvar], [foo=bar x=quux], [begin $foo $x end], [NF: 4 0: begin 1: bar 2: quux 3: end TOTAL: 4 ], [], [], [unset foo; unset x]) TESTWSP([getvar and env],[wsp-getvar], [foo=bar x=quux y=xur], [begin $foo $TVAR $x $y end], [NF: 6 0: begin 1: bar 2: 12 3: quux 4: zwar 5: end TOTAL: 6 ], [], [TVAR=12 y=zwar], [unset foo; unset x]) TESTWSP([getvar, alternate value],[wsp-getvar], [foo=bar], [a ${foo:+isset}], [NF: 2 0: a 1: isset TOTAL: 2 ]) WSPGROUP() TESTWSP([ignore quotes],[wsp-ignore-quotes ],[-noquote], ["a text"], [NF: 2 0: "\"a" 1: "text\"" TOTAL: 2 ]) WSPGROUP(wsp-delim) TESTWSP([custom delimiters (squeeze)],[], [-delim : -nows -trimnl], [semicolon: separated::list: of :words], [NF: 5 0: semicolon 1: " separated" 2: list 3: " of " 4: words TOTAL: 5 ]) TESTWSP([custom delimiters (no squeeze)],[], [-delim : -nows -nosqueeze_delims -trimnl], [semicolon: separated::list: of :words], [NF: 6 0: semicolon 1: " separated" 2: "" 3: list 4: " of " 5: words TOTAL: 6 ]) TESTWSP([custom, with returned delimiters],[], [-delim : -nows -trimnl -return_delims], [semicolon: separated::list: of :words], [NF: 9 0: semicolon 1: : 2: " separated" 3: : 4: list 5: : 6: " of " 7: : 8: words TOTAL: 9 ]) TESTWSP([custom, with returned & squeezed delimiters],[], [-delim : -nows -trimnl -return_delims -nosqueeze_delims], [semicolon: separated::list: of :words], [NF: 10 0: semicolon 1: : 2: " separated" 3: : 4: : 5: list 6: : 7: " of " 8: : 9: words TOTAL: 10 ]) WSPGROUP(wsp-sed) TESTWSP([sed expressions],[],[-sed], [arg1 s/foo/bar/g;s/bar baz/quz quux/ arg2], [NF: 3 0: arg1 1: "s/foo/bar/g;s/bar baz/quz quux/" 2: arg2 TOTAL: 3 ]) WSPGROUP() TESTWSP([C escapes on],[wcp-c-escape],[-cescapes], [a\ttab form\ffeed and new\nline], [NF: 4 0: a\ttab 1: form\ffeed 2: and 3: new\nline TOTAL: 4 ]) TESTWSP([C escapes off],[wcp-c-escape-off],[-nocescapes], [a\ttab form\ffeed and new\nline], [NF: 4 0: attab 1: formffeed 2: and 3: newnline TOTAL: 4 ]) TESTWSP([ws elimination],[wsp-ws-elim],[-delim ' ()' -ws -return_delims], [( list items )], [NF: 4 0: ( 1: list 2: items 3: ) TOTAL: 4 ]) TESTWSP([ws elimination + return delim],[wsp-ws-elim-ret], [-nodefault -novar -nocmd -delim ":," -return_delims -ws -dquote], ["foo" : "bar", "quux" : "baaz" ], [NF: 7 0: foo 1: : 2: bar 3: , 4: quux 5: : 6: baaz TOTAL: 7 ]) TESTWSP([empty quotes],[wsp-empty-quotes],[-delim : -ws -return_delims], [t=""], [NF: 1 0: t= TOTAL: 1 ]) TESTWSP([delimiter following empty quotes], [],[-delim : -ws -return_delims], [t="":r], [NF: 3 0: t= 1: : 2: r TOTAL: 3 ]) TESTWSP([suppress ws trimming within quotes], [], [-default -delim , -ws -return_delims], [nocomponent,nonewline, formatfield="In message %{text}, "], [NF: 5 0: nocomponent 1: , 2: nonewline 3: , 4: "formatfield=In message %{text}, " TOTAL: 5 ]) TESTWSP([unescape], [wsp-unescape wsp-unescape-simple], [-nodefault -novar -nocmd -quote -escape ':+:\\""'], [\Seen "quote \"" "bs \\"], [NF: 3 0: \\Seen 1: "quote \"" 2: "bs \\" TOTAL: 3 ]) TESTWSP([unescape: word/quote], [wsp-unescape wsp-unescape-word], [-nodefault -novar -nocmd -quote -escape-word '\\""' -escape-quote ':+0x:\\""'], [\Seen "quote \"" "bs \\" "3\x31 \101" 3\x31 \101], [NF: 6 0: Seen 1: "quote \"" 2: "bs \\" 3: "31 A" 4: 3x31 5: 101 TOTAL: 6 ]) TESTWSP([dquote],[],[-nodefault -novar -nocmd -dquote], [a "quoted example" isn't it], [NF: 4 0: a 1: "quoted example" 2: isn't 3: it TOTAL: 4 ]) TESTWSP([squote],[],[-nodefault -novar -nocmd -squote], [a 'quoted example' isn"t it], [NF: 4 0: a 1: "quoted example" 2: "isn\"t" 3: it TOTAL: 4 ]) WSPGROUP(wsp-incr) TESTWSP([incremental],[],[-incremental], [incremental "input test" line ], [NF: 1 0: incremental TOTAL: 1 NF: 1 0: "input test" TOTAL: 2 NF: 1 0: line TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental append],[],[-incremental -append], [incremental "input test" line ], [NF: 1 0: incremental TOTAL: 1 NF: 2 0: incremental 1: "input test" TOTAL: 2 NF: 3 0: incremental 1: "input test" 2: line TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental ws], [],[-return_delims -nosqueeze_delims -incremental -ws], [a list test ], [NF: 1 0: a TOTAL: 1 NF: 1 0: list TOTAL: 2 NF: 1 0: test TOTAL: 3 ], [input exhausted ]) TESTWSP([incremental nosplit],[],[-incremental -nosplit], [incremental "input test" line ], [NF: 1 0: "incremental input test line" TOTAL: 1 ], [input exhausted ]) TESTWSP([simple command substitution],[],[-cmd], [begin $(words a b) end], [NF: 4 0: begin 1: a 2: b 3: end TOTAL: 4 ]) TESTWSP([quoted command substitution],[],[-cmd], [begin "$(words a b)" end], [NF: 3 0: begin 1: "a b" 2: end TOTAL: 3 ]) TESTWSP([coalesced command substitution],[],[-cmd], [begin($(words a b))end], [NF: 2 0: begin(a 1: b)end TOTAL: 2 ]) TESTWSP([quoted coalesced command substitution],[],[-cmd], ["begin($(words a b))end"], [NF: 1 0: "begin(a b)end" TOTAL: 1 ]) TESTWSP([variable and command substitution],[],[-cmd -var], [begin $X $(words $X $Y) end], [NF: 5 0: begin 1: a 2: a 3: b 4: end TOTAL: 5 ],[],[X=a Y=b]) TESTWSP([variable expansion and command substitution in quotes],[],[-cmd -var], ["${BEGIN}($(words $X $Y))end"], [NF: 1 0: "begin(a b)end" TOTAL: 1 ],[],[X=a Y=b BEGIN=begin]) TESTWSP([nested commands],[],[-cmd -var], [$(words output $(words in$SUFFIX text) end)], [NF: 4 0: output 1: input 2: text 3: end TOTAL: 4 ],[],[SUFFIX=put]) dnl Something that doesn't fit into TESTWSP AT_SETUP([pathname expansion]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-1]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.c > dir/3.b wsp -pathexpand<<'EOT' begin dir/*.c end EOT ], [0], [NF: 4 0: begin 1: dir/1.c 2: dir/2.c 3: end TOTAL: 4 ]) AT_CLEANUP AT_SETUP([pathname expansion: no match]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-2]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp -pathexpand<<'EOT' begin dir/*.d end EOT ], [0], [NF: 3 0: begin 1: dir/*.d 2: end TOTAL: 3 ]) AT_CLEANUP AT_SETUP([pathname expansion: nullglob]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-3]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp -pathexpand -nullglob<<'EOT' begin dir/*.d end EOT ], [0], [NF: 2 0: begin 1: end TOTAL: 2 ]) AT_CLEANUP AT_SETUP([pathname expansion: failglob]) AT_KEYWORDS([wordsplit wsp wsp-path wsp-path-4]) AT_CHECK([ mkdir dir > dir/1.c > dir/2.b wsp -pathexpand -failglob<<'EOT' begin dir/*.d end EOT ], [0], [], [no files match pattern dir/*.d ]) AT_CLEANUP TESTWSP([append],[],[-append-args extra arguments follow], [some words and], [NF: 6 0: some 1: words 2: and 3: extra 4: arguments 5: follow TOTAL: 3 ]) TESTWSP([append + dooffs + env],[], [-env none -dooffs preface words -- V=2 -append-args extra arguments follow], [some words and var=$V], [NF: 7 (2) (0): preface (1): words 2: some 3: words 4: and 5: var=2 6: extra 7: arguments 8: follow TOTAL: 4 ]) # Maxwords TESTWSP([maxwords],[], [-trimnl -maxwords 3], [ws_maxwords limits the number of returned words], [NF: 3 0: ws_maxwords 1: limits 2: "the number of returned words" TOTAL: 3 ]) TESTWSP([maxwords return_delims],[], [-trimnl -maxwords 8 -return_delims -delim :-], [foo:::bar-:baz-quux:ux:zu], [NF: 8 0: foo 1: : 2: bar 3: - 4: : 5: baz 6: - 7: quux:ux:zu TOTAL: 8 ]) TESTWSP([maxwords return_delims -squeeze_delims],[], [-trimnl -maxwords 8 -return_delims -nosqueeze_delims -delim :-], [foo:::bar-:baz:qux-], [NF: 8 0: foo 1: : 2: : 3: : 4: bar 5: - 6: : 7: baz:qux- TOTAL: 8 ]) TESTWSP([maxwords incremental],[], [-trimnl -maxwords 3 -incremental], [foo bar baz qux uz ], [NF: 1 0: foo TOTAL: 1 NF: 1 0: bar TOTAL: 2 NF: 1 0: "baz qux uz" TOTAL: 3 ], [input exhausted ])) TESTWSP([variable nosplit],[],[-novar -novarsplit], [begin ${VAR:- a b} end], [NF: 3 0: begin 1: "${VAR:- a b}" 2: end TOTAL: 3 ]) TESTWSP([command nosplit],[],[-nocmd -nocmdsplit], [begin $(words a b) end], [NF: 3 0: begin 1: "$(words a b)" 2: end TOTAL: 3 ]) TESTWSP([positional parameters],[],[one two three four five six seven eight nine ten eleven twelve], [$0 $5 ${10} $#], [NF: 3 0: one 1: six 2: eleven TOTAL: 3 NF: 1 0: 12 TOTAL: 1 ]) TESTWSP([$* and $@],[],['one two' three 'four five'], [$* $@ "$*" "$@"], [NF: 5 0: one 1: two 2: three 3: four 4: five TOTAL: 5 NF: 3 0: "one two" 1: three 2: "four five" TOTAL: 3 NF: 1 0: "one two three four five" TOTAL: 1 NF: 1 0: "one two three four five" TOTAL: 1 ]) TESTWSP([$* and $@ in nosplit mode],[], [-trimnl -nosplit 'one two' three 'four five'], [$* $@], [NF: 1 0: "one two three four five" TOTAL: 1 NF: 1 0: "one two three four five" TOTAL: 1 ]) TESTWSP([$* and $@ in nosplit mode with delimiter],[], [-trimnl -nosplit -delim : 'one two' three 'four five'], [$* $@], [NF: 1 0: "one two:three:four five" TOTAL: 1 NF: 1 0: "one two:three:four five" TOTAL: 1 ]) # Namechar modification tests TESTWSP([namechar modification],[], [-namechar ".:" -Dx.y=one -Dx:foo=bar], [one is $x.y, foo is $x:foo], [NF: 6 0: one 1: is 2: one, 3: foo 4: is 5: bar TOTAL: 6 ]) AT_BANNER([namechar modification]) TESTWSP([default value],[], [-namechar ":."], [${x:foo:-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default value (defined)],[], [-namechar ":." -Dx:foo=qux], [${x:foo:-bar}], [NF: 1 0: qux TOTAL: 1 ], []) TESTWSP([default value (:- null)],[], [-namechar ":." -Dx:foo=], [${x:foo:-bar}], [NF: 1 0: bar TOTAL: 1 ], []) TESTWSP([default value (- null)],[], [-namechar ":." -Dx:foo=], [${x:foo-bar}], [NF: 0 TOTAL: 0 ], []) TESTWSP([default value (- null, unset)],[], [-namechar ":."], [${x:foo-bar}], [NF: 1 0: bar TOTAL: 1 ]) TESTWSP([assign default values],[], [-namechar ":."], [${x:foo=bar} $x:foo], [NF: 1 0: bar TOTAL: 1 NF: 1 0: bar TOTAL: 1 ]) TESTWSP([default error message (var defined)],[], [-namechar ":." -Dx:foo=bar], [a ${x:foo:?} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ]) TESTWSP([default error message],[], [-namechar ":."], [${x:foo:?}], [NF: 0 TOTAL: 0 ], [x:foo: variable null or not set ]) TESTWSP([custom error message (defined)],[wsp-custom-err wsp-custom-err03], [-namechar ":." -Dx:foo=bar], [a ${x:foo:?please define it} test], [NF: 3 0: a 1: bar 2: test TOTAL: 3 ]) TESTWSP([custom error message],[wsp-custom-err wsp-custom-err04], [-namechar ":."], [a ${x:foo:?please define it} test], [NF: 2 0: a 1: test TOTAL: 2 ], [x:foo: please define it ]) TESTWSP([alternate value (defined)],[wsp-alt wsp-alt02], [-namechar ":." -Dx:foo=bar], [a ${x:foo:+isset} test], [NF: 3 0: a 1: isset 2: test TOTAL: 3 ], [], [FOO=bar]) TESTWSP([alternate value],[wsp-alt wsp-alt03], [-namechar ":."], [a ${x:foo:+isset} test], [NF: 2 0: a 1: test TOTAL: 2 ]) m4_popdef([TESTWSP]) m4_popdef([wspnum]) m4_popdef([wspid]) m4_popdef([genkw]) m4_popdef([wspgroupnum]) m4_popdef([wspgroupname]) m4_popdef([WSPGROUP])