core-test.sh (6653B)
1 # -*- mode: sh; mode: sh-bash -*- 2 3 #------------------------------------------------------------------------------ 4 # test directory management 5 6 function ble/test/getdir { 7 dir=$_ble_base_run/$$.test 8 [[ -d $dir ]] || ble/bin/mkdir -p "$dir" 9 } 10 11 _ble_test_dir= 12 function ble/test/chdir { 13 local dir 14 ble/test/getdir 15 ble/util/getpid 16 _ble_test_dir=$dir/$BASHPID.d 17 [[ -d $_ble_test_dir ]] || 18 ble/bin/mkdir -p "$_ble_test_dir" 19 cd -L "$_ble_test_dir" 20 } 21 function ble/test/rmdir { 22 [[ -d $_ble_test_dir ]] && 23 ble/bin/rm -rf "$_ble_test_dir" 24 return 0 25 } 26 27 #------------------------------------------------------------------------------ 28 # logging / diff 29 30 _ble_test_logfile_fd= 31 function ble/test/log { 32 if [[ $_ble_test_logfile_fd ]]; then 33 ble/util/print "$1" >&"$_ble_test_logfile_fd" 34 fi 35 ble/util/print "$1" 36 } 37 function ble/test/log#open { 38 local file=$1 39 if ble/fd#alloc _ble_test_logfile_fd '>>$file'; then 40 local h10=---------- 41 [[ -s $file ]] && 42 ble/util/print "$h10$h10$h10$h10$h10$h10$h10" >&"$_ble_test_logfile_fd" 43 ble/util/print "[$(date +'%F %T %Z')] test: start logging" >&"$_ble_test_logfile_fd" 44 fi 45 } 46 function ble/test/log#close { 47 if [[ $_ble_test_logfile_fd ]]; then 48 ble/util/print "[$(date +'%F %T %Z')] test: end logging" >&"$_ble_test_logfile_fd" 49 ble/fd#close _ble_test_logfile_fd 50 _ble_test_logfile_fd= 51 fi 52 } 53 54 if ble/bin#freeze-utility-path colored; then 55 function ble/test/diff.impl { 56 ble/bin/colored diff -u "$@" 57 } 58 else 59 function ble/test/diff.impl { 60 diff -u "$@" 61 } 62 fi 63 function ble/test/diff { 64 local dir 65 ble/test/getdir 66 ble/util/getpid 67 local f1=$BASHPID.$1.expect 68 local f2=$BASHPID.$1.result 69 ( 70 cd "$dir" 71 ble/util/print "$2" >| "$f1" 72 ble/util/print "$3" >| "$f2" 73 ble/util/assign ret 'ble/test/diff.impl "$f1" "$f2"' 74 ble/test/log "$ret" 75 >| "$f1" >| "$f2" 76 ) 77 } 78 79 #------------------------------------------------------------------------------ 80 81 _ble_test_section_fd= 82 _ble_test_section_file= 83 _ble_test_section_title=section 84 _ble_test_section_count=0 85 function ble/test/start-section { 86 [[ $_ble_test_section_fd ]] && ble/test/end-section 87 _ble_test_section_title=$1 88 _ble_test_section_count=$2 89 local dir 90 ble/test/getdir 91 ble/util/getpid 92 _ble_test_section_file=$dir/$BASHPID 93 ble/fd#alloc _ble_test_section_fd '> "$_ble_test_section_file"' 94 } 95 function ble/test/end-section { 96 [[ $_ble_test_section_fd ]] || return 1 97 ble/fd#close _ble_test_section_fd 98 _ble_test_section_fd= 99 100 local ntest npass count=$_ble_test_section_count 101 102 local ntest nfail npass 103 builtin eval -- $( 104 ble/bin/awk ' 105 BEGIN{test=0;fail=0;pass=0;} 106 /^test /{test++} 107 /^fail /{fail++} 108 /^pass /{pass++} 109 END{print "ntest="test" nfail="fail" npass="pass;} 110 ' "$_ble_test_section_file") 111 112 local sgr=$'\e[32m' sgr0=$'\e[m' 113 ((npass==ntest)) || sgr=$'\e[31m' 114 115 local ncrash=$((ntest-nfail-npass)) 116 local nskip=$((count-ntest)) 117 if ((ntest)); then 118 local percentage=$((npass*1000/ntest)) # Note: 切り捨て 119 ble/util/sprintf percentage '%6s' "$((percentage/10)).$((percentage%10))%" # "XXX.X%" 120 else 121 local percentage=---.-% 122 fi 123 ble/test/log "$sgr$percentage$sgr0 [section] $_ble_test_section_title: $sgr$npass/$ntest$sgr0 ($nfail fail, $ncrash crash, $nskip skip)" 124 ((npass==ntest)) 125 } 126 function ble/test/section#incr { 127 local title=$1 128 [[ $_ble_test_section_fd ]] || return 1 129 ble/util/print "test $title" >&"$_ble_test_section_fd" 130 } 131 function ble/test/section#report { 132 local ext=$? title=$1 133 [[ $_ble_test_section_fd ]] || return 1 134 local code=fail; ((ext==0)) && code=pass 135 ble/util/print "$code $title" >&"$_ble_test_section_fd" 136 } 137 138 function ble/test/.read-arguments { 139 local xstdout xstderr xexit xret 140 local qstdout qstderr qexit qret 141 local -a buff=() 142 while (($#)); do 143 local arg=$1; shift 144 case $arg in 145 ('#'*) 146 local ret; ble/string#trim "${arg#'#'}" 147 _ble_test_title=$ret ;; 148 (stdout[:=]*) 149 [[ $qstdout ]] && xstdout=$xstdout$'\n' 150 qstdout=1 151 xstdout=$xstdout${arg#*[:=]} ;; 152 (stderr[:=]*) 153 [[ $qstderr ]] && xstderr=$xstderr$'\n' 154 qstderr=1 155 xstderr=$xstderr${arg#*[:=]} ;; 156 (ret[:=]*) 157 qret=1 158 xret=${arg#*[:=]} ;; 159 (exit[:=]*) 160 qexit=1 161 xexit=${arg#*[:=]} ;; 162 (code[:=]*) 163 ((${#buff[@]})) && ble/array#push buff $'\n' 164 ble/array#push buff "${arg#*[:=]}" ;; 165 (--depth=*) 166 _ble_test_caller_depth=${arg#*=} ;; 167 (--display-code=*) 168 _ble_test_display_code=${arg#*=} ;; 169 (*) 170 ((${#buff[@]})) && ble/array#push buff ' ' 171 ble/array#push buff "$arg" ;; 172 esac 173 done 174 175 [[ $qstdout ]] && _ble_test_item_expect[0]=$xstdout 176 [[ $qstderr ]] && _ble_test_item_expect[1]=$xstderr 177 [[ $qexit ]] && _ble_test_item_expect[2]=$xexit 178 [[ $qret ]] && _ble_test_item_expect[3]=$xret 179 180 # 何もチェックが指定されなかった時は終了ステータスをチェックする 181 ((${#_ble_test_item_expect[@]})) || _ble_test_item_expect[2]=0 182 183 IFS= builtin eval '_ble_test_code="${buff[*]}"' 184 } 185 186 _ble_test_item_name=(stdout stderr exit ret) 187 ## @fn ble/test [--depth=NUM|--display-code=CODE] CODE [[code|stdout|stderr|exit|ret]=VALUE]... '# title' 188 ## @var[out] stdout stderr exit ret 189 function ble/test { 190 local _ble_test_code 191 local _ble_test_title 192 local _ble_test_caller_depth=0 193 local _ble_test_display_code= 194 local -a _ble_test_item_expect=() 195 ble/test/.read-arguments "$@" 196 197 local caller_lineno=${BASH_LINENO[_ble_test_caller_depth+0]} 198 local caller_source=${BASH_SOURCE[_ble_test_caller_depth+1]} 199 _ble_test_title="$caller_source:$caller_lineno${_ble_test_title+ ($_ble_test_title)}" 200 ble/test/section#incr "$_ble_test_title" 201 202 # run 203 ble/util/assign stderr ' 204 ble/util/assign stdout "$_ble_test_code" 2>&1'; exit=$? 205 local -a item_result=() 206 item_result[0]=$stdout 207 item_result[1]=$stderr 208 item_result[2]=$exit 209 item_result[3]=$ret 210 211 local i flag_error= 212 for i in "${!_ble_test_item_expect[@]}"; do 213 [[ ${item_result[i]} == "${_ble_test_item_expect[i]}" ]] && continue 214 215 if [[ ! $flag_error ]]; then 216 flag_error=1 217 ble/test/log $'\e[1m'"$_ble_test_title"$'\e[m: \e[91m'"${_ble_test_display_code:-$_ble_test_code}"$'\e[m' 218 fi 219 220 ble/test/diff "${_ble_test_item_name[i]}" "${_ble_test_item_expect[i]}" "${item_result[i]}" 221 done 222 if [[ $flag_error ]]; then 223 if [[ ! ${_ble_test_item_expect[1]+set} && $stderr ]]; then 224 ble/test/log "<STDERR>" 225 ble/test/log "$stderr" 226 ble/test/log "</STDERR>" 227 fi 228 ble/test/log 229 fi 230 231 [[ ! $flag_error ]] 232 ble/test/section#report "$_ble_test_title" 233 return 0 234 }