| 1 | # testing.ysh
 | 
| 2 | #
 | 
| 3 | # Usage:
 | 
| 4 | #   source --builtin testing.sh
 | 
| 5 | #
 | 
| 6 | # func f(x) { return (x + 1) }
 | 
| 7 | #
 | 
| 8 | # describe foo {
 | 
| 9 | #   assert (43 === f(42))
 | 
| 10 | # }
 | 
| 11 | #
 | 
| 12 | # if is-main {
 | 
| 13 | #   run-tests @ARGV   # --filter
 | 
| 14 | # }
 | 
| 15 | 
 | 
| 16 | module stdlib/testing || return 0
 | 
| 17 | 
 | 
| 18 | source --builtin args.ysh
 | 
| 19 | 
 | 
| 20 | proc assert ( ; cond ; fail_message='default fail message') {
 | 
| 21 |   echo 'hi from assert'
 | 
| 22 | 
 | 
| 23 |   = cond
 | 
| 24 | 
 | 
| 25 |   # I think this might be ready now?
 | 
| 26 | 
 | 
| 27 |   var val = evalExpr(cond) 
 | 
| 28 | 
 | 
| 29 |   echo
 | 
| 30 |   echo 'value'
 | 
| 31 |   = val
 | 
| 32 |   pp line (val)
 | 
| 33 | 
 | 
| 34 |   = fail_message
 | 
| 35 | 
 | 
| 36 |   if (val) {
 | 
| 37 |     echo 'OK'
 | 
| 38 |   } else {
 | 
| 39 |     var m = evalExpr(fail_message) 
 | 
| 40 |     echo "FAIL - this is where we extract the string - $m"
 | 
| 41 |   }
 | 
| 42 | }
 | 
| 43 | 
 | 
| 44 | proc test-assert {
 | 
| 45 |   var x = 42
 | 
| 46 |   assert [42 === x]
 | 
| 47 | }
 | 
| 48 | 
 | 
| 49 | proc test-expr ( ; expr ) {
 | 
| 50 |   echo 'expr'
 | 
| 51 |   pp line (expr)
 | 
| 52 | }
 | 
| 53 | 
 | 
| 54 | proc test-named ( ; ; n=^[99] ) {
 | 
| 55 |   echo 'n'
 | 
| 56 |   pp line (n)
 | 
| 57 | }
 | 
| 58 | 
 | 
| 59 | # What happens when there are duplicate test IDs?
 | 
| 60 | #
 | 
| 61 | # Also I think filter by "$test_id/$case_id"
 | 
| 62 | 
 | 
| 63 | proc __it (case_id ; ; ; block) {
 | 
| 64 |   # This uses a clean directory
 | 
| 65 |   echo TODO
 | 
| 66 | }
 | 
| 67 | 
 | 
| 68 | # is this accessible to users?
 | 
| 69 | # It can contain a global list of things to run
 | 
| 70 | 
 | 
| 71 | # Naming convention: a proc named 'describe' mutates a global named _describe?
 | 
| 72 | # Or maybe _describe_list ?
 | 
| 73 | 
 | 
| 74 | var _describe_list = []
 | 
| 75 | 
 | 
| 76 | proc describe (test_id ; ; ; block) {
 | 
| 77 |   echo describe
 | 
| 78 |   #= desc
 | 
| 79 | 
 | 
| 80 |   # TODO:
 | 
| 81 |   # - need append
 | 
| 82 |   # - need ::
 | 
| 83 |   # _ _describe->append(cmd)
 | 
| 84 |   #
 | 
| 85 |   # Need to clean this up
 | 
| 86 |   # append (_describe, cmd)  # does NOT work!
 | 
| 87 | 
 | 
| 88 |   call _describe_list->append(block)
 | 
| 89 | }
 | 
| 90 | 
 | 
| 91 | proc Args {
 | 
| 92 |   echo TODO
 | 
| 93 | }
 | 
| 94 | 
 | 
| 95 | # Problem: this creates a global variable?
 | 
| 96 | Args (&spec) {
 | 
| 97 |   flag --filter 'Regex of test descriptions'
 | 
| 98 | }
 | 
| 99 | 
 | 
| 100 | proc run-tests {
 | 
| 101 |   var opt, i = parseArgs(spec, ARGV)
 | 
| 102 | 
 | 
| 103 |   # TODO:
 | 
| 104 |   # - parse --filter foo, which you can use eggex for!
 | 
| 105 | 
 | 
| 106 |   for cmd in (_describe) {
 | 
| 107 |     # TODO: print filename and 'describe' name?
 | 
| 108 |     try {
 | 
| 109 |       eval (cmd)
 | 
| 110 |     }
 | 
| 111 |     if (_status !== 0) {
 | 
| 112 |       echo 'failed'
 | 
| 113 |     }
 | 
| 114 |   }
 | 
| 115 | }
 |