1#!/usr/local/bin/bash 2# Licensed to the Apache Software Foundation (ASF) under one 3# or more contributor license agreements. See the NOTICE file 4# distributed with this work for additional information 5# regarding copyright ownership. The ASF licenses this file 6# to you under the Apache License, Version 2.0 (the 7# "License"); you may not use this file except in compliance 8# with the License. You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, 13# software distributed under the License is distributed on an 14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15# KIND, either express or implied. See the License for the 16# specific language governing permissions and limitations 17# under the License. 18 19# Checks that the "_svn" function defined in the specified "bash_completion" 20# script produces appropriate lists of completions for various incomplete svn 21# command lines. 22 23THIS_DIR=`dirname "$0"` 24SCRIPT="$1" 25if [ -z "$SCRIPT" ]; then 26 SCRIPT="$THIS_DIR/bash_completion" 27fi 28 29if [ ! -r "$SCRIPT" ] || [ "$2" ]; then 30 echo "Usage: bash_completion_test [BASH_COMPLETION_PATHNAME]" 31 echo "Tests the specified \"bash_completion\" script," 32 echo "defaulting to the one in the same directory as this test," 33 echo "including checking it against the \"svn\" program found in the current PATH." 34 exit 1 35fi 36 37set -e # Exit on error 38shopt -s extglob 39export LC_ALL=C 40 41# Execute the script which is to be tested. 42. "$SCRIPT" 43 44# From the given incomplete command, print a space-separated list of 45# possible completions of the last argument (or of an empty first argument 46# if no subcommand is given). 47# 48# Usage: get_completions SVN-CMD [SVN-SUBCOMMAND [SVN-OPTION...]] 49# where SVN-CMD is "svn", "svnadmin", etc.; such that when a leading 50# underscore is added, it must name one of the completion functions in 51# "bash_completion". 52get_completions() { 53 SVN_CMD="$1" 54 COMP_WORDS=("$@") 55 if [ $# == 1 ]; then 56 COMP_CWORD=1 57 else 58 COMP_CWORD=$(($#-1)) 59 fi 60 # Call the appropriate completion function (e.g. "_svn") with no arguments. 61 "_$SVN_CMD" 62 echo -n "${COMPREPLY[*]}" 63} 64 65# Print a failure message, record the failure, and return "false". 66# Usage: fail MESSAGE 67fail() { 68 PREFIX="FAIL: " 69 for LINE in "$@"; do 70 echo "$PREFIX$LINE" 71 PREFIX=" " 72 done 73 TESTS_FAILED=1 74 false 75} 76 77# Check that EXPECTED-WORD is among the completions of the last word in 78# SVN-ARGS. SVN-ARGS is a single argument to this function, split 79# into multiple arguments when passed to "get_completions()". 80# Usage: includes SVN-CMD SVN-ARGS EXPECTED-WORD 81includes() { 82 SVN_CMD="$1" 83 SVN_ARGS="$2" 84 EXPECTED_WORD="$3" 85 COMPLETIONS=`get_completions "$SVN_CMD" $SVN_ARGS` 86 if [[ "$EXPECTED_WORD" != @(${COMPLETIONS// /|}) ]]; then 87 fail "completions of \"$SVN_CMD $SVN_ARGS\" should include \"$EXPECTED_WORD\"" \ 88 "(completions: $COMPLETIONS)" 89 fi 90} 91 92excludes() { 93 SVN_CMD="$1" 94 SVN_ARGS="$2" 95 EXPECTED_WORD="$3" 96 COMPLETIONS=`get_completions "$SVN_CMD" $SVN_ARGS` 97 if [[ "$EXPECTED_WORD" == @(${COMPLETIONS// /|}) ]]; then 98 fail "completions of \"$SVN_CMD $SVN_ARGS\" should exclude \"$EXPECTED_WORD\"" \ 99 "(completions: $COMPLETIONS)" 100 fi 101} 102 103# Print the valid subcommands for an "svn"-like program, one per line, sorted. 104# Exclude any synonym that is just a truncation of its full name. 105# Usage: get_svn_subcommands SVN-CMD 106# where SVN-CMD is "svn" or another program that outputs similar help. 107get_svn_subcommands() { 108 SVN_CMD="$1" 109 "$SVN_CMD" help | 110 # Find the relevant lines. 111 sed -n -e '1,/^Available subcommands:$/d;/^$/q;p' | 112 # Remove brackets and commas 113 tr -d ' )' | tr '(,' ' ' | 114 # Remove simple abbreviations 115 ( while read SYNONYMS; do 116 for CMD in $SYNONYMS; do 117 if [ "$CMD" != "?" ]; then 118 for SYNONYM in $SYNONYMS; do 119 case $SYNONYM in 120 $CMD) ;; 121 $CMD*) CMD= ; break ;; 122 esac 123 done 124 if [ $CMD ]; then 125 echo $CMD 126 fi 127 fi 128 done 129 done 130 ) | 131 sort 132} 133 134# Print the valid option switches for "svn SUBCMD", one per line, sorted. 135# Usage: get_svn_options SVN-CMD SUBCMD 136# where SVN-CMD is "svn" or another program that outputs similar help. 137get_svn_options() { 138 SVN_CMD="$1" 139 SUBCMD="$2" 140 { "$SVN_CMD" help "$SUBCMD" | 141 # Remove deprecated options 142 grep -v deprecated | 143 # Find the relevant lines; remove "arg" and description. 144 sed -n -e '1,/^\(Valid\|Global\) options:$/d;/^ -/!d' \ 145 -e 's/\( ARG\)* * : .*//;p' | 146 # Remove brackets; put each word on its own line. 147 tr -d '] ' | tr '[' '\n' 148 # The following options are always accepted but not listed in the help 149 if [ "$SUBCMD" != "help" ] ; then 150 echo "-h" 151 echo "--help" 152 fi 153 } | sort 154 155} 156 157 158# The tests. 159set +e # Do not exit on error 160TESTS_FAILED= 161 162echo "Checking general completion" 163includes svn "he" "help" 164includes svn "" "help" 165includes svn "" "--version" 166 167for SVN_CMD in svn svnadmin svndumpfilter svnlook svnrdump svnsync; do 168 echo "Checking list of subcommands: $SVN_CMD" 169 HELP_SUBCMDS=`get_svn_subcommands "$SVN_CMD" | tr "\n" " "` 170 COMPLETION_SUBCMDS=`get_completions "$SVN_CMD" | tr " " "\n" | grep -v "^-" | sort | tr "\n" " "` 171 if [ "$HELP_SUBCMDS" != "$COMPLETION_SUBCMDS" ]; then 172 fail "non-option completions for \"$SVN_CMD\" != subcommands accepted" \ 173 " (non-o. cmpl.: $COMPLETION_SUBCMDS)" \ 174 " (help says: $HELP_SUBCMDS)" 175 fi 176 177 echo "Checking list of options for each subcommand" 178 for SUBCMD in $HELP_SUBCMDS; do 179 HELP_OPTIONS=`get_svn_options $SVN_CMD $SUBCMD | tr "\n" " "` 180 COMPLETION_OPTIONS=`get_completions $SVN_CMD $SUBCMD - | tr " " "\n" | sort | tr "\n" " "` 181 if [ "$HELP_OPTIONS" != "$COMPLETION_OPTIONS" ]; then 182 fail "completions for \"$SVN_CMD $SUBCMD -\" != options accepted" \ 183 " (completions: $COMPLETION_OPTIONS)" \ 184 " (help says: $HELP_OPTIONS)" 185 fi 186 done 187done 188 189echo "Checking rejection of synonyms" 190excludes svn "diff -x -u -" "-x" 191excludes svn "diff -x -u --e" "--extensions" 192excludes svn "diff --extensions -u -" "--extensions" 193excludes svn "diff --extensions -u -" "-x" 194excludes svn "diff --extensions=-u -" "-x" 195 196if [ $TESTS_FAILED ]; then 197 echo "FAILURE: at least one bash_completion test failed." 198else 199 echo "All bash_completion tests passed." 200fi 201