dejagnu
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PATCH: add support for verifying errors in internal unit tests [revi


From: Jacob Bachmeyer
Subject: Re: PATCH: add support for verifying errors in internal unit tests [revised patch]
Date: Fri, 07 Dec 2018 20:53:37 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.8.1.22) Gecko/20090807 MultiZilla/1.8.3.4e SeaMonkey/1.1.17 Mnenhy/0.7.6.0

Ben Elliston wrote:
On Fri, Dec 07, 2018 at 06:59:01PM -0600, Jacob Bachmeyer wrote:
+       if { [string match "$pattern" $result] } {
+           return 1
+       } else {
+           return 0
+     }

This can be simplified to:
     return [string match $pattern $result]

Done.

+       if { [regexp -- $regexp $result] } {
+           return 1
+       } else {
+           return 0
+       }

Likewise here for [regexp ...].

Done.

+       if { $result eq $val } {
+           return 1
+       } else {
+           return 0
+       }

This can be simplified to:
     return [string equal $result $val]

Done. In practice [expr { $result eq $val }] should also work, but the form of booleans expr returns is not documented. The [string equal] command is documented to return 0 or 1.

Those had been left as they were because I saw them as a very clear way to write that code, also illustrating what to expect from these functions. A form of self-documenting code, if you will.

+       if { $val } {
+           if { $result } { return 1 } else { return 0 }
+       } else {
+           if { $result } { return 0 } else { return 1 }
+       }

This could be simplified to:

     if {$val} {
        return [expr $result != 0]
     } else {
        return [expr $result == 0]
     }

That is not actually equivalent in Tcl; if it were, I would have used that when I wrote lib_bool_test. See Tcl_GetBoolean(3) for details; in short, Tcl booleans can be "0", "false", "no", "off" for a false value or "1", "true", "yes", "on" for a true value. The "if" command is a bit more lenient and will also accept any non-zero digit string as true. Strictly, there is no guarantee in Tcl that $result will contain a number for a procedure that returns a boolean value. The "==" operator is magic, but not that magic. :-)

That said, Tcl does have the ternary operator, which allows simplifying that to a single "return [expr {...}]" that is correct in all cases. Done. Revised patch follows:

----
ChangeLog entry:
        * testsuite/runtest.all/default_procs.tcl:
        (lib_errpat_test, lib_errregexp_test, lib_err_test): New.
        (lib_regexp_test): Fix copy-paste-edit error.
        (lib_pat_test, lib_regexp_test, lib_ret_test, lib_bool_test):
        Fix handling of errors raised by tested procedure.  Also ensure
        proper quoting of argument lists passed to eval and simplify
        the logic for producing return values.
----
patch:
----
diff --git a/testsuite/runtest.all/default_procs.tcl 
b/testsuite/runtest.all/default_procs.tcl
index ebb0daf..076c645 100644
--- a/testsuite/runtest.all/default_procs.tcl
+++ b/testsuite/runtest.all/default_procs.tcl
@@ -4,59 +4,117 @@ set errno ""

# this tests a proc for a returned pattern
proc lib_pat_test { cmd arglist pattern } {
-    catch { eval [list $cmd] $arglist } result
-    puts "CMD(lib_pat_test) was: $cmd $arglist"
-    puts "RESULT(lib_pat_test) was: \"${result}\" for pattern \"$pattern\"."
-
-    if { [regexp -- "with too many" $result] } {
+    puts "CMD(lib_pat_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 0 } {
+       puts "RESULT(lib_pat_test) was: \"${result}\"\
+               for pattern \"$pattern\"."
+       return [string match "$pattern" $result]
+    } else {
+       puts "RESULT(lib_pat_test) was error \"${result}\""
        return -1
    }
-    if { [string match "$pattern" $result] } {
-       return 1
+}
+
+# this tests a proc for a returned regexp
+proc lib_regexp_test { cmd arglist regexp } {
+    puts "CMD(lib_regexp_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 0 } {
+       puts "RESULT(lib_regexp_test) was: \"${result}\"\
+               for regexp \"$regexp\"."
+       return [regexp -- $regexp $result]
    } else {
-       return 0
+       puts "RESULT(lib_regexp_test) was error \"${result}\""
+       return -1
    }
}

-# this tests a proc for a returned regexp
-proc lib_regexp_test { cmd arglist pattern } {
-    catch { eval [list $cmd] $arglist } result
-    puts "CMD(lib_pat_test) was: $cmd $arglist"
-    puts "RESULT(lib_pat_test) was: \"${result}\" for pattern \"$pattern\"."
+# this tests a proc for a returned value
+proc lib_ret_test { cmd arglist val } {
+    puts "CMD(lib_ret_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 0 } {
+       puts "RESULT(lib_ret_test) was: $result"
+       return [string equal $result $val]
+    } else {
+       puts "RESULT(lib_ret_test) was error \"${result}\""
+       return -1
+    }
+}

-    if { [regexp -- "with too many" $result] } {
+# this tests a proc for an expected boolean result
+proc lib_bool_test { cmd arglist val } {
+    puts "CMD(lib_bool_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 0 } {
+       puts "RESULT(lib_bool_test) was: \"$result\" expecting $val."
+       # the "odd" spacing is used to help make the operator grouping clear
+       return [expr {  $val  ?   $result ? 1 : 0   :   $result ? 0 : 1   }]
+    } else {
+       puts "RESULT(lib_bool_test) was error \"${result}\""
        return -1
    }
-    if { [regexp -- "$pattern" $result] } {
-       return 1
+}
+
+# this tests that a proc raises an error matching a pattern
+proc lib_errpat_test { cmd arglist pattern } {
+    puts "CMD(lib_errpat_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 1 } {
+       # caught exception code 1 (TCL_ERROR) as expected
+       puts "RESULT(lib_errpat_test) was error\
+               \"${result}\" for pattern \"$pattern\"."
+       if { [string match $pattern $result] } {
+           # the expected error
+           return 1
+       } else {
+           # an unexpected error
+           return -1
+       }
    } else {
+       # no error -> fail
+       puts "RESULT(lib_errpat_test) was: \"${result}\"\
+               without error; failing."
        return 0
    }
}

-# this tests a proc for a returned value
-proc lib_ret_test { cmd arglist val } {
-    catch { eval [list $cmd] $arglist } result
-    puts "CMD(lib_ret_test) was: $cmd $arglist"
-    puts "RESULT(lib_ret_test) was: $result"
-
-    if { $result eq $val } {
-       return 1
+# this tests that a proc raises an error matching a regexp
+proc lib_errregexp_test { cmd arglist regexp } {
+    puts "CMD(lib_errregexp_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 1 } {
+       # caught exception code 1 (TCL_ERROR) as expected
+       puts "RESULT(lib_errregexp_test) was error\
+               \"${result}\" for regexp \"$regexp\"."
+       if { [regexp -- $regexp $result] } {
+           # the expected error
+           return 1
+       } else {
+           # an unexpected error
+           return -1
+       }
    } else {
+       # no error -> fail
+       puts "RESULT(lib_errregexp_test) was: \"${result}\"\
+               without error; failing."
        return 0
    }
}

-# this tests a proc for an expected boolean result
-proc lib_bool_test { cmd arglist val } {
-    catch { eval [list $cmd] $arglist } result
-    puts "CMD(lib_bool_test) was: $cmd $arglist"
-    puts "RESULT(lib_bool_test) was: \"$result\" expecting \"$val\"."
-
-    if { $val } {
-       if { $result } { return 1 } else { return 0 }
+# this tests that a proc raises an error matching an exact string
+proc lib_err_test { cmd arglist val } {
+    puts "CMD(lib_err_test) is: $cmd $arglist"
+    if { [catch { eval [list $cmd] [lrange $arglist 0 end] } result] == 1 } {
+       # caught exception code 1 (TCL_ERROR) as expected
+       puts "RESULT(lib_err_test) was error: $result"
+       if { $result eq $val } {
+           # the expected error
+           return 1
+       } else {
+           # an unexpected error
+           return -1
+       }
    } else {
-       if { $result } { return 0 } else { return 1 }
+       # no error -> fail
+       puts "RESULT(lib_err_test) was: \"${result}\"\
+               without error; failing."
+       return 0
    }
}

----


-- Jacob




reply via email to

[Prev in Thread] Current Thread [Next in Thread]