#!/bin/bash # RAC test-suite - needs bash version 2 or higher # Aurelio Marinho Jargas & Thobias Salazar Trevisan DEBUG=0 ; [ "$1" = '-v' ] && DEBUG=1 && shift ############################################################ # # USER CONFIG HERE # # paths RAC="${1:-./rac}" # current dir or $1 RACTMP="${TMP:-/tmp}/rac-tests" # # enable or disable tests here do_cols_test=1 do_rows_test=1 do_str_rows_test=1 do_rgx_rows_test=1 do_opts_test=1 do_error_test=1 do_emu_test=1 # ############################################################ # sanity [ -x "$RAC" ] || { echo "Erro: Executável '$RAC' não encontrado." echo 'Passe o caminho completo do RAC como parâmetro ($1).' echo 'Exemplo: ractest /usr/bin/rac' exit } touch $RACTMP >&- 2>&- || { echo "Erro: Não consigo gravar o arquivo temporário '$RACTMP'" exit } # string comparisons - en_EN RAC_EMPTY="Try \`rac --help' for more information." RAC_VERSION='rac version 1.3' RAC_HELP='Usage: rac [OPTIONS] ADDRESS [FILE]...' # string comparisons - pt_BR RAC_EMPTY="Tente \`rac --help' para mais informações." RAC_VERSION='rac versão 1.3' RAC_HELP='Uso: rac [OPÇÕES] ENDEREÇO [ARQUIVO]' # known errors ZERO_STEP='Erro: STEP_LINE can not be zero' # 1~0 ZERO_STEPSTART='Erro: line start can not be zero' # 0~1 INVALID_RANGE='Erro: Invalid Range.' # 1:foo INVALID_OPT='Erro: Opção -z inválida' INVALID_LONG_OPT='Erro: Opção --foo inválida' INVALID_ADDR='Erro: Invalid addressing.' STEP_NO_COUNT='Erro: A ocorrência inicial deve ser especificada.' REGEX_OPEN_BRACKET='Erro: brackets ([ ]) not balanced' REGEX_OPEN_PARENT='Erro: parentheses not balanced' ##### skipping some tests # ### COL NUMBER # the +number mapping is still a plan for the future col_num_skip="|+1|+1;+1|+1:+5|+1~+2|+0|+0:+0|-0:+0|+0:-0|" # +N mapping # ### ROW NUMBER row_num_skip="|+1|+1;+1|+1:+5|+1~+2|+0|+0:+0|-0:+0|+0:-0|" # +N mapping # ### ROW STRING row_str_skip="|+1|+1;+1|+1:+5|+1~+2|+0|+0:+0|-0:+0|+0:-0|" # +N mapping # in numbers range overflow is ok, in strings it is invalid row_str_skip="${row_str_skip}999:|:999|1:999|-1:999|999:1|999:-1|-999:-1|-999:1|" # handy functions sample_text(){ sed '/^###TXT$/,/^###$/!d;/^###/d;s/^# //' $0; } emu_result() { sed '/^###EMU$/,/^###$/!d;/^###/d;s/^# //' $0; } must_skip() { local address="$1" skipme="$2" echo "$skipme" | grep -qs -- "|${address// /}|" local exitcode=$? [ "$exitcode" -eq 0 -a "$DEBUG" = 1 ] && echo "+ ignoring $address" return $exitcode } tester() { local address="$1" resultok="$2" kind="${3:-row}" [ "$DEBUG" = 1 ] && echo "+ executing $address" if [ "$kind" = row ]; then result=$(sample_text | sed 10d | $RAC "$address" | sed 's/_.*//' | tr -d '\n') else result=$(echo 123456789 | $RAC "$address") fi [ "$result" != "$resultok" ] && echo "ERROR: < $address > expected '$resultok', got '$result'" } all_tests=( ' 1 % 1' ' -1 % 9' ' : % 123456789' ' : 1 % 1' ' :-3 % 1234567' ' 1: % 123456789' '-3: % 789' ' 1: 1 % 1' ' 1: 5 % 12345' ' 1:-3 % 1234567' ' 1:-1 % 123456789' ' 5: 1 % 54321' ' 5: 5 % 5' ' 5:-3 % 567' ' 5:-1 % 56789' '-3: 1 % 7654321' '-3: 5 % 765' '-3:-3 % 7' '-3:-1 % 789' '-1: 1 % 987654321' '-1: 5 % 98765' '-1:-3 % 987' '-1:-1 % 9' '1;3;5 % 135' '1;1;1 % 111' '-1;-1 % 99' '3; -1 % 39' '1; 7: % 1789' '-1;:3 % 9123' '7;-3: % 7789' ' 5~ 1 % 56789' ' 1~ 5 % 16' ' 5~ 2 % 579' '-5~ 2 % 579' ' 5~-2 % 531' '-5~-2 % 531' ' 999 % ' ' -999 % ' ' 999: % 9' '-999: % 123456789' ' : 999 % 123456789' ' :-999 % 1' ' 1: 999 % 123456789' ' 1:-999 % 1' '-1: 999 % 9' '-1:-999 % 987654321' ' 999: 1 % 987654321' ' 999:-1 % 9' '-999: 1 % 1' '-999:-1 % 123456789' ' 999~ 1 % ' ' 999~-1 % ' '-999~ 1 % ' '-999~-1 % ' ' 1~ 999 % 1' ' 1~-999 % 1' '-1~ 999 % 9' '-1~-999 % 9' ' 0 % ' ' -0 % ' ' +0 % ' ' 0:0 % ' ' -0:+0 % ' ' +0:-0 % ' ' -0:-0 % ' ' +0:+0 % ' ' 0;0 % ' ' 0:3 % 123' ' 0:-3 % 1234567' ' 3:0 % 321' ' -3:0 % 7654321' '+1 % 1' '+1;+1 % 11' '+1:+5 % 12345' '+1~+2 % 13579' ' 1;5~2 % 1579' '-1;-3:;5~-2 % 9789531' ) str_tests=( ' % 123456789' ' *1 % 1' ' *3 % 3' '*-3 % 7' ' *1~3 % 147' ' *3~1 % 3456789' ' *3~-1 % 321' '*-3~1 % 789' '*-3~-1 % 7654321' '*-3~-3 % 741' ' *3+2 % 5' ' *3-2 % 1' '*-3+2 % 9' '*-3-2 % 5' ' +3 % 456789' ' *0 % ' ' +0 % 123456789' ' -0 % 123456789' ' *3+0 % 3' ' *3-0 % 3' ' *999 % ' '*-999 % ' ' +999 % ' ' -999 % ' '*1~999 % 1' '*1~-999 % 1' #'=foo=:0 % ' #'=foo=:5 % ' #' 0:=foo= % ' #' 5:=foo= % ' #'=foo=:=bar= % ' '=foo=+0 % ' '=foo=-0 % ' '=foo=*0 % ' '=foo=*0+0 % ' '=foo=*0+1 % ' '=foo=+1 % ' '=foo=-1 % ' '=foo=*1 % ' '=foo=*-1 % ' '=foo=*1+0 % ' '=foo=*1+1 % ' '=foo=*1-1 % ' '[1:10] % 123456789' ) all_opts=( '' "$RAC_EMPTY" '-V' "$RAC_VERSION" '--version' "$RAC_VERSION" '-h' "$RAC_HELP" '--help' "$RAC_HELP" ) # test string: FOO opt_tests=( '-i "=foo="' '--ignore-case "=foo="' '-i "/(foo)/"' '-b "/\(FOO\)/"' '--bre "/\(FOO\)/"' '-i -b "/\(foo\)/"' '-b -i "/\(foo\)/"' '-bi "/\(foo\)/"' ) # test string: FOO rgx_tests=( '^FOO$' 'F.O' 'FOO*' 'FOO+' 'FOO?' 'FOO{1,}' '[F]OO' '[^O]OO' '[A-Z]OO' '(FOO)' 'F(O)\1' 'FOO\/?' # / escaping ) error_tests=( "-z % $INVALID_OPT" "--foo % $INVALID_LONG_OPT" "1:foo % $INVALID_RANGE" "1~0 % $ZERO_STEP" "0~1 % $ZERO_STEPSTART" "foo % $INVALID_RANGE" "[3 % $INVALID_ADDR" "3] % $INVALID_RANGE" "3[ % $INVALID_ADDR" "]3 % $INVALID_RANGE" "]3[ % $INVALID_ADDR" "[3]] % $INVALID_RANGE" "[[3] % $INVALID_RANGE" "+3 % $INVALID_RANGE" "1~+3 % $INVALID_RANGE" "=z=*+3 % $INVALID_ADDR" "=z=~3 % $STEP_NO_COUNT" "/z/~3 % $STEP_NO_COUNT" # "/[/ % $REGEX_OPEN_BRACKET" # different libs, different msgs # "/(/ % $REGEX_OPEN_PARENT" ) total_tests=${#all_tests[*]} total_opts=${#all_opts[*]} total_str_tests=$((${#all_tests[*]}+${#str_tests[*]})) #--------------------------------------------------------------- ### COLUMNS TEST #--------------------------------------------------------------- if [ "$do_cols_test" = 1 ]; then i=0 echo 'testing NUM/COL' while [ $i -lt $total_tests ]; do test_data=${all_tests[$i]} ; i=$((i+1)) address="${test_data% %*}" must_skip "$address" "$col_num_skip" && continue address="${address//;/,}" # change ; to , address="[$address]" # add braces resultok="${test_data#*% }" tester "$address" "$resultok" col done fi #--------------------------------------------------------------- ### NUMBER ROW TESTS #--------------------------------------------------------------- if [ "$do_rows_test" = 1 ]; then i=0 echo 'testing NUM/LIN' while [ $i -lt $total_tests ]; do test_data=${all_tests[$i]} ; i=$((i+1)) address="${test_data% %*}" resultok="${test_data#*% }" must_skip "$address" "$row_num_skip" && continue tester "$address" "$resultok" row done fi #--------------------------------------------------------------- ### STRING ROW TESTS #--------------------------------------------------------------- if [ "$do_str_rows_test" = 1 ]; then i=0 echo 'testing STR/LIN' while [ $i -lt $total_str_tests ]; do if [ $i -ge $total_tests ]; then test_data=${str_tests[$((i-total_tests))]} else test_data=${all_tests[$i]} fi i=$((i+1)) address="${test_data% %*}" resultok="${test_data#*% }" #echo -e "\t\t\t\t\t\t["$address" -> $resultok]" must_skip "$address" "$row_str_skip" && continue if [ $i -gt $total_tests ]; then # string address without pattern [ "${address/=/}" = "$address" ] && address="=_=$address" else # composed from numbered addresses ### 1 -> =1_= # 1 -> =_=*1 # -1 -> =_=*-1 # +1 -> =_=*+1 address=$(echo $address | sed ' s/ *//g; s/\(^\|[:;]\)\([-+]\?[0-9]\)/\1=_=*\2/g; #s/\(^\|[:;]\)\([-+][0-9]\)/\1=_=*\2/g; #s/\(^\|[:;]\)\([0-9]\{1,\}\)/\1=\2_=/g;') fi tester "$address" "$resultok" row done fi #--------------------------------------------------------------- ### REGEX ROW TESTS #--------------------------------------------------------------- if [ "$do_rgx_rows_test" = 1 ]; then i=0 echo 'testing RGX/LIN' while [ $i -lt $total_str_tests ]; do if [ $i -ge $total_tests ]; then test_data=${str_tests[$((i-total_tests))]} else test_data=${all_tests[$i]} fi i=$((i+1)) address="${test_data% %*}" resultok="${test_data#*% }" #echo -e "\t\t\t\t\t\t["$address" -> $resultok]" must_skip "$address" "$row_str_skip" && continue if [ $i -gt $total_tests ]; then # string address without pattern if [ "${address/=/}" = "$address" ]; then address="/^[0-9][_]/$address" else address=$(echo $address | tr = /) fi else # composed from numbered addresses (see string) address=$(echo $address | sed ' s| *||g; s@\(^\|[:;]\)\([-+]\?[0-9]\)@\1/_[0-9]/*\2@g') fi tester "$address" "$resultok" row done # regex specific tests i=0 while [ $i -lt ${#rgx_tests[*]} ]; do patt="/${rgx_tests[$i]}/" i=$((i+1)) [ "$DEBUG" = 1 ] && echo "+ executing $patt" result=$(echo FOO | $RAC "$patt") [ "$result" != FOO ] && echo "ERROR: < $patt > expected 'FOO', got '$result'" done fi #--------------------------------------------------------------- ### CMDLINE OPTIONS TESTS #--------------------------------------------------------------- if [ "$do_opts_test" = 1 ]; then echo 'testing OPT' # --help, --version, ... i=0 while [ $i -lt $total_opts ]; do option="${all_opts[$i]}" ; i=$((i+1)) resultok="${all_opts[$i]}" ; i=$((i+1)) [ "$DEBUG" = 1 ] && echo "+ executing $option" result=$($RAC $option 2>&1 | head -1) [ "$result" != "$resultok" ] && echo "ERROR: <$option> expected '$resultok', got '$result'" done # -i, -b, ... i=0 while [ $i -lt ${#opt_tests[*]} ]; do test_data=${opt_tests[$i]} i=$((i+1)) [ "$DEBUG" = 1 ] && echo "+ executing $test_data" result=$(eval "echo FOO | $RAC $test_data 2>&1") [ "$result" != FOO ] && echo "ERROR: < $test_data > expected 'FOO', got '$result'" done # --bre specific tests i=0 while [ $i -lt ${#rgx_tests[*]} ]; do # ere -> bre patt=$(echo "${rgx_tests[$i]}" | sed 's/[(){}+?]/\\&/g') patt="/$patt/" i=$((i+1)) [ "$DEBUG" = 1 ] && echo "+ executing --bre $patt" result=$(echo FOO | $RAC -b "$patt") [ "$result" != FOO ] && echo "ERROR: < -b $patt > expected 'FOO', got '$result'" done fi #--------------------------------------------------------------- ### ERROR HANDLING TESTS #--------------------------------------------------------------- if [ "$do_error_test" = 1 ]; then echo 'testing ERR' i=0 while [ $i -lt ${#error_tests[*]} ]; do test_data=${error_tests[$i]} patt="${test_data% %*}" resultok="${test_data#*% }" i=$((i+1)) [ "$DEBUG" = 1 ] && echo "+ executing $patt" result=$(echo | $RAC "$patt" 2>&1) [ "$result" != "$resultok" ] && echo "ERROR: < $patt > expected '$resultok', got '$result'" done fi #--------------------------------------------------------------- ### EMULATION TESTS #--------------------------------------------------------------- if [ "$do_emu_test" = 1 ]; then echo 'testing EMU' for cmd in \ 'head' '1:10' \ 'head -5' '1:5' \ 'head -1' '1' \ 'tail' '-10:-1' \ 'tail -5' '-5:-1' \ 'tail -1' '-1' \ 'tac' '-1:1' \ 'rev' '[-1:1]' \ 'sed -n 5p' '5' \ 'sed -n 3,5p' '3:5' \ 'sed 25q' '1:25' \ 'cut -c1,3,5' '[1,3,5]' \ 'cut -c5-' '[5:-1]' \ 'cut -c1,3,5-' '[1,3,5:-1]' \ 'rev|cut -c1' '[-1]' \ 'cut -c1-5|rev' '[5:1]' \ 'tail -5|tac' '-1:-5' \ 'tail -1|rev|cut -c1' '-1[-1]' \ #'sed -n 3,7p|cut -c10-20' '3:7 | [10:20]' \ do [ "$emulated" ] || { emulated=$cmd ; continue ; } echo "------( $emulated )-------( $cmd )-------" sample_text | $RAC $cmd emulated='' done > $RACTMP emu_result | diff -u - $RACTMP rm -f ${RACTMP:-/tmp/aaaaa} fi ###TXT # 1_345678901234567890 # 2_345678901234567890 # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # 6_345678901234567890 # 7_345678901234567890 # 8_345678901234567890 # 9_345678901234567890 # 0_345678901234567890 ### ###EMU # ------( head )-------( 1:10 )------- # 1_345678901234567890 # 2_345678901234567890 # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # 6_345678901234567890 # 7_345678901234567890 # 8_345678901234567890 # 9_345678901234567890 # 0_345678901234567890 # ------( head -5 )-------( 1:5 )------- # 1_345678901234567890 # 2_345678901234567890 # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # ------( head -1 )-------( 1 )------- # 1_345678901234567890 # ------( tail )-------( -10:-1 )------- # 1_345678901234567890 # 2_345678901234567890 # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # 6_345678901234567890 # 7_345678901234567890 # 8_345678901234567890 # 9_345678901234567890 # 0_345678901234567890 # ------( tail -5 )-------( -5:-1 )------- # 6_345678901234567890 # 7_345678901234567890 # 8_345678901234567890 # 9_345678901234567890 # 0_345678901234567890 # ------( tail -1 )-------( -1 )------- # 0_345678901234567890 # ------( tac )-------( -1:1 )------- # 0_345678901234567890 # 9_345678901234567890 # 8_345678901234567890 # 7_345678901234567890 # 6_345678901234567890 # 5_345678901234567890 # 4_345678901234567890 # 3_345678901234567890 # 2_345678901234567890 # 1_345678901234567890 # ------( rev )-------( [-1:1] )------- # 098765432109876543_1 # 098765432109876543_2 # 098765432109876543_3 # 098765432109876543_4 # 098765432109876543_5 # 098765432109876543_6 # 098765432109876543_7 # 098765432109876543_8 # 098765432109876543_9 # 098765432109876543_0 # ------( sed -n 5p )-------( 5 )------- # 5_345678901234567890 # ------( sed -n 3,5p )-------( 3:5 )------- # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # ------( sed 25q )-------( 1:25 )------- # 1_345678901234567890 # 2_345678901234567890 # 3_345678901234567890 # 4_345678901234567890 # 5_345678901234567890 # 6_345678901234567890 # 7_345678901234567890 # 8_345678901234567890 # 9_345678901234567890 # 0_345678901234567890 # ------( cut -c1,3,5 )-------( [1,3,5] )------- # 135 # 235 # 335 # 435 # 535 # 635 # 735 # 835 # 935 # 035 # ------( cut -c5- )-------( [5:-1] )------- # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # 5678901234567890 # ------( cut -c1,3,5- )-------( [1,3,5:-1] )------- # 135678901234567890 # 235678901234567890 # 335678901234567890 # 435678901234567890 # 535678901234567890 # 635678901234567890 # 735678901234567890 # 835678901234567890 # 935678901234567890 # 035678901234567890 # ------( rev|cut -c1 )-------( [-1] )------- # 0 # 0 # 0 # 0 # 0 # 0 # 0 # 0 # 0 # 0 # ------( cut -c1-5|rev )-------( [5:1] )------- # 543_1 # 543_2 # 543_3 # 543_4 # 543_5 # 543_6 # 543_7 # 543_8 # 543_9 # 543_0 # ------( tail -5|tac )-------( -1:-5 )------- # 0_345678901234567890 # 9_345678901234567890 # 8_345678901234567890 # 7_345678901234567890 # 6_345678901234567890 # ------( tail -1|rev|cut -c1 )-------( -1[-1] )------- # 0 ###