]> git.ipfire.org Git - thirdparty/libtool.git/commitdiff
gl/tests: new tests for func_quote* family
authorPavel Raiskup <praiskup@redhat.com>
Sat, 31 Oct 2015 13:33:18 +0000 (14:33 +0100)
committerPavel Raiskup <praiskup@redhat.com>
Tue, 3 Nov 2015 19:38:39 +0000 (20:38 +0100)
* gl/modules/funclib.sh-tests: New test module.
* gl/modules/all-shells-tests: New test (helper) module.
* gl/tests/test-funclib-quote.sh: New test case.
* gl/tests/test-all-shells.sh: New gl test helper.
* cfg.mk (sc_useless_braces_in_variable_derefs): Whitelist
new test-funclib-quote.sh as the pattern is used there
intentionally.
(sc_space_tab): Likewise.
(sc_useless_braces_in_variable_derefs): Remove /cvsu pattern as
the file is not used with git.
(sc_prohibit_command_in_subst): New checker.

cfg.mk
gl/modules/all-shells-tests [new file with mode: 0644]
gl/modules/funclib.sh-tests [new file with mode: 0644]
gl/tests/test-all-shells.sh [new file with mode: 0644]
gl/tests/test-funclib-quote.sh [new file with mode: 0755]

diff --git a/cfg.mk b/cfg.mk
index 6767b2d52ea5603c04c47dfe0814dfdfe0af6819..c04248f1a3a091978b3ae1814453f2591da35b55 100644 (file)
--- a/cfg.mk
+++ b/cfg.mk
@@ -112,6 +112,13 @@ sc_prohibit_bracket_as_test:
        halt="use 'if test' instead of 'if ['"                  \
          $(_sc_search_regexp)
 
+# : ${foo=`bar`} is not perfectly portable (see Shellology in autoconf's manual)
+exclude_file_name_regexp--sc_prohibit_command_in_subst = ^cfg.mk$$
+sc_prohibit_command_in_subst:
+       @prohibit='\$$\{[^`}]*`[^`]*`[^}]*}'                            \
+       halt='do not use `command` in $${ } substitution`'              \
+         $(_sc_search_regexp)
+
 # Check for quotes within backquotes within quotes "`"bar"`"
 exclude_file_name_regexp--sc_prohibit_nested_quotes = ^cfg.mk$$
 sc_prohibit_nested_quotes:
@@ -238,7 +245,8 @@ define _sc_search_regexp_or_exclude
   fi || :;
 endef
 
-exclude_file_name_regexp--sc_useless_braces_in_variable_derefs = /cvsu$$
+exclude_file_name_regexp--sc_useless_braces_in_variable_derefs = \
+       test-funclib-quote.sh$$
 sc_useless_braces_in_variable_derefs:
        @prohibit='\$${[0-9A-Za-z_]+}[^0-9A-Za-z_]'                     \
        halt='found spurious braces around variable dereference'        \
@@ -258,11 +266,9 @@ sc_useless_quotes_in_case:
          $(_sc_search_regexp)
 
 # List syntax-check exempted files.
-exclude_file_name_regexp--sc_error_message_uppercase = \
-  ^$(_build-aux)/cvsu$$
 exclude_file_name_regexp--sc_prohibit_strcmp = \
   ^doc/libtool.texi$$
 exclude_file_name_regexp--sc_prohibit_test_minus_ao = \
   ^m4/libtool.m4$$
-exclude_file_name_regexp--sc_space_tab = \.diff$$
+exclude_file_name_regexp--sc_space_tab = (\.diff|test-funclib-quote.sh)$$
 exclude_file_name_regexp--sc_trailing_blank-non-rfc3676 = \.diff$$
diff --git a/gl/modules/all-shells-tests b/gl/modules/all-shells-tests
new file mode 100644 (file)
index 0000000..e47a943
--- /dev/null
@@ -0,0 +1,10 @@
+Files:
+tests/test-all-shells.sh
+
+Depends-on:
+funclib.sh
+
+Makefile.am:
+TESTS_ENVIRONMENT += \
+       abs_aux_dir='$(abs_aux_dir)' \
+       abs_srcdir='$(abs_srcdir)'
diff --git a/gl/modules/funclib.sh-tests b/gl/modules/funclib.sh-tests
new file mode 100644 (file)
index 0000000..80991c7
--- /dev/null
@@ -0,0 +1,12 @@
+Files:
+tests/test-funclib-quote.sh
+
+Depends-on:
+test-framework-sh
+all-shells-tests
+
+configure.ac:
+
+Makefile.am:
+TESTS += \
+       test-funclib-quote.sh
diff --git a/gl/tests/test-all-shells.sh b/gl/tests/test-all-shells.sh
new file mode 100644 (file)
index 0000000..d56c305
--- /dev/null
@@ -0,0 +1,104 @@
+#! /bin/sh
+
+# Unit test helper.
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+# This shell snippet (when sourced) tries to find as many /bin/sh compatible
+# shells as possible on tested box -- and then re-executes the calling script
+# in all of them.  At the end, the default shell (/bin/sh usually) is also
+# tested.
+#
+# To write compatible test-case, you usually need only those lines:
+#
+#   #! /bin/sh
+#
+#   all_shells_script=$0
+#   . "$abs_srcdir/test-all-shells.sh"
+#
+#   your_check && all_shells_error "failed your_check"
+#
+#   $all_shells_exit_cmd
+
+
+# List of shells we try to check in.
+: ${GL_ALL_SHELLS='ash bash dash ksh zsh busybox'}
+
+# List of directories to search for the shell interpreter.
+: ${GL_ALL_SHELLS_DIRS='/bin /sbin'}
+
+# List of shell emulations to test with BusyBox.
+: ${GL_ALL_SHELLS_BBE='sh ash'}
+
+. "$abs_aux_dir"/funclib.sh || exit 1
+
+all_shells_exit_cmd=:
+
+: ${all_shells_script=false}
+
+
+all_shells_error ()
+{
+    $ECHO "error: $*" >&2
+    all_shells_exit_cmd=false
+}
+
+
+__notify_shell ()
+{
+    $ECHO "== running in '$*' ==" >&2
+}
+
+
+__reexec_in_all_shells ()
+{
+    for _G_dir in $GL_ALL_SHELLS_DIRS
+    do
+      for _G_shell in $GL_ALL_SHELLS
+      do
+        _G_abs_shell=$_G_dir/$_G_shell
+        test -f "$_G_abs_shell" || continue
+
+        case $_G_abs_shell in
+          *busybox)
+            for _G_bbe in $GL_ALL_SHELLS_BBE
+            do
+              _G_full_bb="$_G_abs_shell $_G_bbe"
+              __notify_shell "$_G_full_bb"
+              __GL_ALL_SHELLS_SHELL="$_G_full_bb" \
+              "$_G_abs_shell" "$_G_bbe" "$all_shells_script" ${1+"$@"} \
+                  || all_shells_error "can't run in $_G_bbe"
+            done
+            ;;
+          *)
+            __notify_shell "$_G_abs_shell"
+            __GL_ALL_SHELLS_SHELL="$_G_abs_shell" \
+            "$_G_abs_shell" "$all_shells_script" ${1+"$@"} \
+                || all_shells_error "can't run in $_G_abs_shell"
+            ;;
+        esac
+      done
+    done
+}
+
+
+test x = "x$__GL_ALL_SHELLS_SHELL" \
+    && __reexec_in_all_shells ${1+"$@"} \
+    && __notify_shell "default shell"
+
+:
diff --git a/gl/tests/test-funclib-quote.sh b/gl/tests/test-funclib-quote.sh
new file mode 100755 (executable)
index 0000000..7669a44
--- /dev/null
@@ -0,0 +1,184 @@
+#! /bin/sh
+
+# Unit tests for funclib.sh
+#
+# Copyright (C) 2015 Free Software Foundation, Inc.
+# This file is part of the GNUlib Library.
+#
+# This program 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 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+all_shells_script=$0
+. "$abs_srcdir/test-all-shells.sh" || exit 1
+
+
+_compare_or_error ()
+{
+    _G_msg="strings differ:
+    a: $2
+    b: $3"
+    test "$2" = "$3" || all_shells_error "$_G_msg"
+}
+
+
+dump_args ()
+{
+    dump_args_result=
+    _separator=
+    for arg
+    do
+      func_append dump_args_result "$_separator$arg"
+      _separator=' '
+    done
+}
+
+
+# test_q_eval DESC ARGs...
+# ------------------------
+# Apply 'func_quote eval' on ARGs and eval the result.  The eval-ed result must
+# 100% match the original ARGs.
+test_q_eval ()
+{
+    description="$1" ; shift
+
+    dump_args ${1+"$@"}
+    original=$dump_args_result
+
+    $ECHO "~> func_quote eval: $description: $original"
+
+    # Pretty implementation
+    func_quote eval,pretty ${1+"$@"} \
+      || all_shells_error "can't pretty func_quote args '$*'"
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+    pretty=$dump_args_result
+
+    # Fast implementation (if available)
+    func_quote eval ${1+"$@"} || all_shells_error "can't fast func_quote args '$*'"
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+    fast=$dump_args_result
+
+    _compare_or_error "$description (pretty)"     "$original" "$pretty"
+    _compare_or_error "$description (fast)"       "$original" "$fast"
+}
+
+
+# test_q_arg_eval DESC ARG
+# ------------------------
+# Apply 'func_quote_arg eval' on ARG and eval the result.  Echo-ed result within
+# eval must match original echo-ed ARG.
+test_q_arg_eval ()
+{
+    description=$1
+    original=$2
+    original_echo=`$ECHO "$original"`
+
+    $ECHO "~> func_quote_arg eval: $description: $original_echo"
+
+    func_quote_arg pretty,unquoted "$original" \
+        || all_shells_error "can't quote_arg: $original"
+    pretty=$func_quote_arg_result
+    pretty_unquoted=$func_quote_arg_unquoted_result
+    pretty_echo=`eval '$ECHO '"$pretty"` \
+        || all_shells_error "can't eval: $pretty"
+
+    pretty_unquoted_echo=`eval '$ECHO '"\"$pretty_unquoted\""` \
+        || all_shells_error "can't eval: $pretty"
+
+    # Fast implementation.
+    func_quote_arg eval "$original"
+    fast=$func_quote_arg_result
+    fast_echo=`eval '$ECHO '"$fast"` || all_shells_error "can't eval: $pretty"
+
+    _compare_or_error "$description (pretty)" \
+        "$original_echo" "$pretty_echo"
+    _compare_or_error "$description (pretty_unquoted)" \
+        "$original_echo" "$pretty_unquoted_echo"
+    _compare_or_error "$description (fast)" \
+        "$original_echo" "$fast_echo"
+}
+
+
+# test_q_expand DESC EXP_RESULT ARG
+# ---------------------------------
+# Test that 'func_quote expand' works fine --> all shell special characters are
+# quoted except '$' -- while all variables are expanded.
+test_q_expand ()
+{
+    description=$1 ; shift
+    exp_result=$1 ; shift
+
+    dump_args ${1+"$@"}
+    $ECHO "~> func_quote expand: $description: $dump_args_result"
+
+    func_quote expand ${1+"$@"}
+    eval "set dummy $func_quote_result" ; shift
+    dump_args ${1+"$@"}
+
+    _compare_or_error "$description (expand)" "$exp_result" "$dump_args_result"
+}
+
+
+## ============== ##
+## Start testing! ##
+## ============== ##
+
+aaa=aaa ; bbb=bbb ; ccc=ccc ; ddd=ddd
+
+# Needed for later testing of globbing.
+touch fltestA fltestB
+
+test_q_eval     basic             a b c
+# TODO: Intentionally not checking newline here yet, it never worked.
+test_q_eval     spaces            'space space' 'tab   tab'
+test_q_eval     empty_arg         '' '' ''
+test_q_eval     globs             '*' '.*' '[a-zA-Z0-9_]' '?' '~'
+test_q_eval     variables         '$aaa' '${bbb}' '"${ccc} $ddd"'
+test_q_eval     exclamation-mark  '$!' '!$' '!'
+test_q_eval     tilde             '"~"'
+test_q_eval     single-quotes     "'a'" "'"'$bbb'"'"
+test_q_eval     shell-vars        '$1' '$@' '$*' 'ending$'
+test_q_eval     complicated-cmd   grep b '>' /noperm '<' /noperm
+
+test_q_arg_eval basic             a
+test_q_arg_eval single-quotes     "'''"
+test_q_arg_eval double-quotes     '"""'
+test_q_arg_eval tilde             '~'
+test_q_arg_eval ampersand         '&'
+test_q_arg_eval pipe              '|'
+test_q_arg_eval questionmark      'fltest?'
+test_q_arg_eval glob-bracket      'fltest[A-Z]'
+test_q_arg_eval space             'space space'
+test_q_arg_eval tab               'tab tab'
+test_q_arg_eval '`command`'       '`false command`'
+test_q_arg_eval '$(command)'      '$(false command)'
+test_q_arg_eval semicolon         '; false'
+test_q_arg_eval vars              '$aaa ${bbb} "${ccc} $ddd"'
+test_q_arg_eval if-then-else      'if false; then false; else false; fi'
+test_q_arg_eval file-redirect     'echo a > /no-perm 2> /no-perm'
+test_q_arg_eval case-stmt         'case $empty in "") false;; a) broken ;; esac'
+test_q_arg_eval comment           'unexistent #'
+test_q_arg_eval func              'func () { } # syntax error'
+
+test_q_expand   basic             'a b c aaa d'   a b c '$aaa' d
+test_q_expand   double-quotes     '" " " "bbb"'   '"' '" "' '"$bbb"'
+test_q_expand   spaces            '     ccc'     ' ' ' ' '${ccc}'
+# Note the *no expected space* here!
+test_q_expand   non-existent      ''              '$empty' '${empty}'
+test_q_expand   non-existent-2    '"" ""'         '"$empty"' '"${empty}"'
+# TODO: Intentionally not checking '$(cmd)' yet.
+test_q_expand   '`command`'       '`aaa bbb`'     '`$aaa $empty${bbb}`'
+
+$all_shells_exit_cmd && rm -rf fltest*