| #!/bin/bash | |
| # Licensed to the Apache Software Foundation (ASF) under one | |
| # or more contributor license agreements. See the NOTICE file | |
| # distributed with this work for additional information | |
| # regarding copyright ownership. The ASF licenses this file | |
| # to you under the Apache License, Version 2.0 (the | |
| # "License"); you may not use this file except in compliance | |
| # with the License. You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, | |
| # software distributed under the License is distributed on an | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| # KIND, either express or implied. See the License for the | |
| # specific language governing permissions and limitations | |
| # under the License. | |
| # Checks that the "_svn" function defined in the specified "bash_completion" | |
| # script produces appropriate lists of completions for various incomplete svn | |
| # command lines. | |
| THIS_DIR=`dirname "$0"` | |
| SCRIPT="$1" | |
| if [ -z "$SCRIPT" ]; then | |
| SCRIPT="$THIS_DIR/bash_completion" | |
| fi | |
| if [ ! -r "$SCRIPT" ] || [ "$2" ]; then | |
| echo "Usage: bash_completion_test [BASH_COMPLETION_PATHNAME]" | |
| echo "Tests the specified \"bash_completion\" script," | |
| echo "defaulting to the one in the same directory as this test," | |
| echo "including checking it against the \"svn\" program found in the current PATH." | |
| exit 1 | |
| fi | |
| set -e # Exit on error | |
| shopt -s extglob | |
| export LC_ALL=C | |
| # Execute the script which is to be tested. | |
| . "$SCRIPT" | |
| # From the given incomplete command, print a space-separated list of | |
| # possible completions of the last argument (or of an empty first argument | |
| # if no subcommand is given). | |
| # | |
| # Usage: get_completions SVN-CMD [SVN-SUBCOMMAND [SVN-OPTION...]] | |
| # where SVN-CMD is "svn", "svnadmin", etc.; such that when a leading | |
| # underscore is added, it must name one of the completion functions in | |
| # "bash_completion". | |
| get_completions() { | |
| SVN_CMD="$1" | |
| COMP_WORDS=("$@") | |
| if [ $# == 1 ]; then | |
| COMP_CWORD=1 | |
| else | |
| COMP_CWORD=$(($#-1)) | |
| fi | |
| # Call the appropriate completion function (e.g. "_svn") with no arguments. | |
| "_$SVN_CMD" | |
| echo -n "${COMPREPLY[*]}" | |
| } | |
| # Print a failure message, record the failure, and return "false". | |
| # Usage: fail MESSAGE | |
| fail() { | |
| PREFIX="FAIL: " | |
| for LINE in "$@"; do | |
| echo "$PREFIX$LINE" | |
| PREFIX=" " | |
| done | |
| TESTS_FAILED=1 | |
| false | |
| } | |
| # Check that EXPECTED-WORD is among the completions of the last word in | |
| # SVN-ARGS. SVN-ARGS is a single argument to this function, split | |
| # into multiple arguments when passed to "get_completions()". | |
| # Usage: includes SVN-CMD SVN-ARGS EXPECTED-WORD | |
| includes() { | |
| SVN_CMD="$1" | |
| SVN_ARGS="$2" | |
| EXPECTED_WORD="$3" | |
| COMPLETIONS=`get_completions "$SVN_CMD" $SVN_ARGS` | |
| if [[ "$EXPECTED_WORD" != @(${COMPLETIONS// /|}) ]]; then | |
| fail "completions of \"$SVN_CMD $SVN_ARGS\" should include \"$EXPECTED_WORD\"" \ | |
| "(completions: $COMPLETIONS)" | |
| fi | |
| } | |
| excludes() { | |
| SVN_CMD="$1" | |
| SVN_ARGS="$2" | |
| EXPECTED_WORD="$3" | |
| COMPLETIONS=`get_completions "$SVN_CMD" $SVN_ARGS` | |
| if [[ "$EXPECTED_WORD" == @(${COMPLETIONS// /|}) ]]; then | |
| fail "completions of \"$SVN_CMD $SVN_ARGS\" should exclude \"$EXPECTED_WORD\"" \ | |
| "(completions: $COMPLETIONS)" | |
| fi | |
| } | |
| # Print the valid subcommands for an "svn"-like program, one per line, sorted. | |
| # Exclude any synonym that is just a truncation of its full name. | |
| # Usage: get_svn_subcommands SVN-CMD | |
| # where SVN-CMD is "svn" or another program that outputs similar help. | |
| get_svn_subcommands() { | |
| SVN_CMD="$1" | |
| "$SVN_CMD" help | | |
| # Find the relevant lines. | |
| sed -n -e '1,/^Available subcommands:$/d;/^$/q;p' | | |
| # Remove brackets and commas | |
| tr -d ' )' | tr '(,' ' ' | | |
| # Remove simple abbreviations | |
| ( while read SYNONYMS; do | |
| for CMD in $SYNONYMS; do | |
| if [ "$CMD" != "?" ]; then | |
| for SYNONYM in $SYNONYMS; do | |
| case $SYNONYM in | |
| $CMD) ;; | |
| $CMD*) CMD= ; break ;; | |
| esac | |
| done | |
| if [ $CMD ]; then | |
| echo $CMD | |
| fi | |
| fi | |
| done | |
| done | |
| ) | | |
| sort | |
| } | |
| # Print the valid option switches for "svn SUBCMD", one per line, sorted. | |
| # Usage: get_svn_options SVN-CMD SUBCMD | |
| # where SVN-CMD is "svn" or another program that outputs similar help. | |
| get_svn_options() { | |
| SVN_CMD="$1" | |
| SUBCMD="$2" | |
| { "$SVN_CMD" help "$SUBCMD" | | |
| # Remove deprecated options | |
| grep -v deprecated | | |
| # Find the relevant lines; remove "arg" and description. | |
| sed -n -e '1,/^\(Valid\|Global\) options:$/d;/^ -/!d' \ | |
| -e 's/\( ARG\)* * : .*//;p' | | |
| # Remove brackets; put each word on its own line. | |
| tr -d '] ' | tr '[' '\n' | |
| # The following options are always accepted but not listed in the help | |
| if [ "$SUBCMD" != "help" ] ; then | |
| echo "-h" | |
| echo "--help" | |
| fi | |
| } | sort | |
| } | |
| # The tests. | |
| set +e # Do not exit on error | |
| TESTS_FAILED= | |
| echo "Checking general completion" | |
| includes svn "he" "help" | |
| includes svn "" "help" | |
| includes svn "" "--version" | |
| for SVN_CMD in svn svnadmin svndumpfilter svnlook svnrdump svnsync; do | |
| echo "Checking list of subcommands: $SVN_CMD" | |
| HELP_SUBCMDS=`get_svn_subcommands "$SVN_CMD" | tr "\n" " "` | |
| COMPLETION_SUBCMDS=`get_completions "$SVN_CMD" | tr " " "\n" | grep -v "^-" | sort | tr "\n" " "` | |
| if [ "$HELP_SUBCMDS" != "$COMPLETION_SUBCMDS" ]; then | |
| fail "non-option completions for \"$SVN_CMD\" != subcommands accepted" \ | |
| " (non-o. cmpl.: $COMPLETION_SUBCMDS)" \ | |
| " (help says: $HELP_SUBCMDS)" | |
| fi | |
| echo "Checking list of options for each subcommand" | |
| for SUBCMD in $HELP_SUBCMDS; do | |
| HELP_OPTIONS=`get_svn_options $SVN_CMD $SUBCMD | tr "\n" " "` | |
| COMPLETION_OPTIONS=`get_completions $SVN_CMD $SUBCMD - | tr " " "\n" | sort | tr "\n" " "` | |
| if [ "$HELP_OPTIONS" != "$COMPLETION_OPTIONS" ]; then | |
| fail "completions for \"$SVN_CMD $SUBCMD -\" != options accepted" \ | |
| " (completions: $COMPLETION_OPTIONS)" \ | |
| " (help says: $HELP_OPTIONS)" | |
| fi | |
| done | |
| done | |
| echo "Checking rejection of synonyms" | |
| excludes svn "diff -x -u -" "-x" | |
| excludes svn "diff -x -u --e" "--extensions" | |
| excludes svn "diff --extensions -u -" "--extensions" | |
| excludes svn "diff --extensions -u -" "-x" | |
| excludes svn "diff --extensions=-u -" "-x" | |
| if [ $TESTS_FAILED ]; then | |
| echo "FAILURE: at least one bash_completion test failed." | |
| else | |
| echo "All bash_completion tests passed." | |
| fi |