testutils.tcl

Go to the documentation of this file.
00001 /*  testutils.tcl --*/
00002 /* */
00003 /*      Auxilliary utilities for use with the tcltest package.*/
00004 /*      Author: Joe English <jenglish@flightlab.com>*/
00005 /*      Version: 1.1*/
00006 /* */
00007 /*  This file is hereby placed in the public domain.*/
00008 /* */
00009 /*  $Id: testutils.tcl,v 1.3 2004/02/20 09:15:53 balls Exp $*/
00010 
00011 variable tracing 0      ;/*  Set to '1' to enable the 'trace' command*/
00012 variable tracingErrors 0    ;/*  If set, 'expectError' prints error messages*/
00013 
00014 /*  ok --*/
00015 /*  Returns an empty string.*/
00016 /*  May be used as the last statement in test scripts */
00017 /*  that are only evaluated for side-effects or in cases*/
00018 /*  where you just want to make sure that an operation succeeds*/
00019 /* */
00020 ret  ok () { return {} }
00021 
00022 /*  result result --*/
00023 /*  Just returns $result*/
00024 /* */
00025 ret  result (type result) { return $result }
00026 
00027 /*  tracemsg msg --*/
00028 /*  Prints tracing message if $::tracing is nonzero.*/
00029 /* */
00030 ret  tracemsg (type string) {
00031     if {$::tracing} {
00032     puts $::tcltest::outputChannel $string
00033     }
00034 }
00035 
00036 /*  assert expr ?msg? --*/
00037 /*  Evaluates 'expr' and signals an error*/
00038 /*  if the condition is not true.*/
00039 /* */
00040 ret  assert (type expr , optional message ="") {
00041     if {![uplevel 1 [list expr $expr]]} {
00042     return -code error "Assertion {$expr} failed:\n$message"
00043     }
00044 }
00045 
00046 /*  expectError script  ? pattern ? --*/
00047 /*  Evaluate 'script', which is expected to fail*/
00048 /*  with an error message matching 'pattern'.*/
00049 /* */
00050 /*  Returns the error message if the script 'correctly' fails,*/
00051 /*  raises an error otherwise*/
00052 
00053 ret  expectError (type script , optional pattern ="*") {
00054     set rc [catch [list uplevel 1 $script] result]
00055     if {$::tracingErrors} {
00056     puts stderr "==> [string replace $result 70 end ...]"
00057     }
00058     set rmsg [string replace $result 40 end ...]
00059     if {$rc != 1} {
00060     return -code error \
00061         "Expected error, got '$rmsg' (rc=$rc)"
00062     }
00063     return $result
00064 }
00065 
00066 /*  sortedarray --*/
00067 /* */
00068 /*  Return the contents of an array, sorted by index*/
00069 
00070 ret  sortedarray arrName (
00071     type upvar 1 $, type arrName , type thearray
00072 
00073     , type set , type result , optional 
00074     , type foreach , type idx [, type lsort [, type array , type names , type thearray]] , optional 
00075     lappend =result $idx =$thearray($idx)
00076     
00077 
00078     , type return $, type result
00079 )
00080 
00081 # compareNodes
00082 #   Compares two nodes, taking implementations into account
00083 
00084 proc compareNodes {node1 node2} {
00085     if {[::tcltest::testConstraint dom_libxml2] || [::tcltest::testConstraint dom_tcl]} {
00086     ::dom::node isSameNode $node1 $node2
00087     } else {
00088     return [expr ![string compare $node1 $node2]]
00089     }
00090 }
00091 
00092 /*  compareNodeList list1 list2*/
00093 /*  Compares two lists of DOM nodes, in an ordered fashion.*/
00094 /*  NB. the node identities are compared, not their tokens.*/
00095 
00096 ret  compareNodeList (type list1 , type list2) {
00097     if {[llength $list1] != [llength $list2]} {
00098     return 0
00099     }
00100     foreach node1 $list1 node2 $list2 {
00101     if {![compareNodes $node1 $node2]} {
00102         return 0
00103     }
00104     }
00105     return 1
00106 }
00107 
00108 /*  compareNodeset set1 set2*/
00109 /*  Compares two sets of DOM nodes, in an unordered fashion.*/
00110 /*  NB. the node identities are compared, not their tokens.*/
00111 
00112 ret  compareNodeset (type set1 , type set2) {
00113     if {[llength $set1] != [llength $set2]} {
00114     return 0
00115     }
00116     foreach node1 [lsort $set1] node2 [lsort $set2] {
00117     if {![compareNodes $node1 $node2]} {
00118         return 0
00119     }
00120     }
00121     return 1
00122 }
00123 
00124 /*  checkTree doc list*/
00125 /*  Tests that a DOM tree has a structure specified as a Tcl list*/
00126 
00127 ret  checkTree (type node , type spec , optional checktype =1) {
00128     if {[dom::node cget $node -nodeType] == "document"} {
00129     if {$checktype} {
00130         if {[lindex [lindex $spec 0] 0] == "doctype"} {
00131         set doctype [dom::document cget $node -doctype]
00132         if {[dom::node cget $doctype -nodeType] != "documentType"} {
00133             return 0
00134         }
00135         if {[dom::documenttype cget $doctype -name] != [lindex [lindex $spec 0] 1]} {
00136             return 0
00137         }
00138         # Should also check external identifiers and internal subset
00139         set spec [lrange $spec 1 end]
00140         }
00141     }
00142     }
00143     foreach child [dom::node children $node] specchild $spec {
00144     switch [lindex $specchild 0] {
00145         element {
00146         if {[dom::node cget $child -nodeType] != "element"} {
00147             return 0
00148         }
00149         if {[dom::node cget $child -nodeName] != [lindex $specchild 1]} {
00150             return 0
00151         }
00152         foreach {name value} [lindex $specchild 2] {
00153             if {[dom::element getAttribute $child $name] != $value} {
00154             return 0
00155             }
00156         }
00157         set result [checkTree $child [lindex $specchild 3]]
00158         if {!$result} {
00159             return 0
00160         }
00161         }
00162         pi {
00163         if {[dom::node cget $child -nodeType] != "processingInstruction"} {
00164             return 0
00165         }
00166         if {[dom::node cget $child -nodeName] != [lindex $specchild 1]} {
00167             return 0
00168         }
00169         }
00170         dtd {
00171         if {[dom::node cget $child -nodeType] != "dtd"} {
00172             return 0
00173         }
00174         }
00175         text {
00176         if {[dom::node cget $child -nodeType] != "textNode"} {
00177             return 0
00178         }
00179         if {[dom::node cget $child -nodeValue] != [lindex $specchild 1]} {
00180             return 0
00181         }
00182         }
00183         default {
00184         }
00185     }
00186     }
00187 
00188     return 1
00189 }
00190 
00191 /*  testPackage package ?version?*/
00192 /*  Loads specified package with 'package require $package $version',*/
00193 /*  then prints message describing how the package was loaded.*/
00194 /* */
00195 /*  This is useful when you've got several versions of a*/
00196 /*  package to lying around and want to make sure you're */
00197 /*  testing the right one.*/
00198 /* */
00199 
00200 ret  testPackage (type package , optional version ="") {
00201     if {$package == "libxml2"} {
00202     # "libxml2" is shorthand for xml::libxml2
00203     set package xml::libxml2
00204     }
00205     if {![catch "package present $package $version"]} { return }
00206     set rc [catch "package require $package $version" result]
00207     if {$rc} { return -code $rc $result }
00208     set version $result
00209     set loadScript [package ifneeded $package $version]
00210     puts $::tcltest::outputChannel \
00211     "Loaded $package version $version via {$loadScript}"
00212     return;
00213 }
00214 
00215 /* *EOF**/
00216 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1