shunit_m - posix & portable xunit for shell script
shunit_m [
-hHVvF] [
-A names]
 
~$ shunit_m > funcs.sh
--src.sh
#!/bin/sh
. ./funcs.sh
_eq 1 1
_neq 1 1 'write anymsg at last arg'
ls
_fail	#>> assert $? != 0
_res 	#>> output result + return rc
--run 
~$ sh src.sh	#>> ok,NG fail/all=10/20 etc. (bash needs --posix opt)
~$ echo $?  	#>> output fail num (all suc==0)
  - -h, -H, -V
- usage, version
  - -v level
- verbose level. 0/1/2 == quite/normal/verbose. output to stderr
  - -F
- fallthrough. stops running if detect assert error in default
  - -A names
- change assert alias names. set 5 fields
      
 eg) ~$ shunit_m -A '_eq _neq _suc _fail _res' #same as default  
 eg) ~$ shunit_m -A 'aa bb cc dd zz' #  _eq 1 2
      changes to aa 1 2
shunit_m outputs assert alias, support functions and assert count vars.
  core api is alias.
  - 
  
 _eq
- takes 2 args and test [ ag1 = ag2 ]
  - 
  
 _neq
- takes 2 args and test [ ag1 != ag2 ]
  - 
  
 _suc
- takes no arg. same as _eq $? 0
  - 
  
 _fail
- takes no arg. same as _neq $? 0
  - 
  
 _res
- this isnt assert. output the result and return. if 5 assert failed, $? ==
      5.
upper 5 takes additional 1 arg for memo/msg. eg) _suc this_is_f1_test
 
other functions and vars doesnt use directly. option -v,F,A will edit the output
  code and alias. be careful when using it in copy and paste style.
 
  ~$ shunit_m	#>> shunit_eq(){ abc...}
  ~$ shunit_m -F	#>> shunit_eq(){ xyz...}
 
---
 
dont eval in compound commands, (), {}, func()(), func(){} etc.
 
	--good             |  ---NG1               |  ---NG2
	#!/bin/sh          |  #!/bin/sh            |  #!/bin/sh         
	eval "$(shunit_m)" |  (                    |  testf(){
	(                  |    eval "$(shunit_m)" |    eval "$(shunit_m)"
	    _eq 1 1        |    _eq 1 1            |    _eq 1 1
	    _res           |    _res               |    _res
	)                  |  )                    |  }
	                   |                       |  testf
 
alias substitution should work as C-lang macros and the scope must be the same
  as local vars in posix-shell.
 
(https://pubs.opengroup.org/onlinepubs/9699919799/utilities/alias.html)
 
 
all sample(good, NG1, NG2) should work in posix-shell but any major shells
  (posix mode or not) doesnt compliant the standard. only bash is mentioned
  about this problem in the alias section of its man.
 
bash/dash/ksh/busybox raises error to the below code:
 
	sh -c '(alias abc='ls'; alias ; abc)'
	# sh == bash --posix / dash / ksh / busybox sh 
 
allmost all shells works fine if eval shunit_m in base process, tread as C-lang
  #define delective.
asserts returns 0/!0, _fail 1 2 >> $? == 0. ' _res' returns failed assert
  count.
#!/bin/sh
src_main(){
  f1 "$@"
  return 0
}
f1(){
  [ $# -eq 2 ] || return 1
  num=$(($1+$2))
}
## run main
# src_main "$@"
# exit $?
## run testcode
cmd="$(shunit_m)"
eval "$cmd"		#>> you can check with 'echo "$cmd"'
f1	;_fail
f1 1 2	;_eq 3 $num
_res
echo "--test suc"
--test_run 
~$ dash src.sh
 
 
---src.sh
#!/bin/sh
src_main(){
  f1 "$@"
  return 0
}
f1(){
  [ $# -eq 2 ] || return 1
  num=$(($1+$2))
}
src_main "$@"		# @marker@
--tests.sh
#!/bin/sh
eval "$(shunit_m -F)"
test_1(){ f1 10 20; _fail ;}
test_2(){ _eq 1 1 ;}
eval "$(cat src.sh|grep -v '@marker@')"
suite=$(sed -ne '/^test_[0-9]*[(]/{s/[(].*//p}'<$0)   #grep test_**
for fc in $suite;do $fc ;done
_res
--test_run
~$ bash --posix tests.sh
 
~$ shunit_m -F	#>> output code
--tests.sh
#!/bin/sh
#---
# copy&paste code
#---
test_1(){ _eq 1 1 ;}
eval "$(cat src.sh|grep -v '@marker@')"
suite=$(sed -ne '/^test_[0-9]*[(]/{s/[(].*//p}'<$0)
for fc in $suite;do $fc ;done
_res
--test_run--
~$ sh tests.sh
--concept
 - respect posix
 - small is beautiful
 - avoid original syntax
posix-shell
Copyright (C) 2021 Momi-g
 
License GPLv3+ <https://gnu.org/licenses/gpl.html>
2021-10-12 v1.0.3
shunit2(1), shellspec