Ignore:
Timestamp:
Feb 1, 2011, 5:37:45 PM (14 years ago)
Author:
mmc
Message:

Some preliminary changes toward a new way of exploring test results.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tester/testview.tcl

    r2074 r2077  
    22#  COMPONENT: testview - display the results of a test
    33#
    4 #  Entire right hand side of the regression tester.  Displays the
    5 #  golden test results, and compares them to the new results if the test
    6 #  has been ran.  Also show tree representation of all inputs and
    7 #  outputs.  The -test configuration option is used to provide a Test
    8 #  object to display.
     4#  Top part of right hand side of the regression tester.  Displays an
     5#  overview of selected test cases, and offers a button for running
     6#  them.
    97# ======================================================================
    108#  AUTHOR:  Ben Rafferty, Purdue University
    11 #  Copyright (c) 2010  Purdue Research Foundation
     9#           Michael McLennan, Purdue University
     10#  Copyright (c) 2010-2011  Purdue Research Foundation
    1211#
    1312#  See the file "license.terms" for information on usage and
     
    1918namespace eval Rappture::Tester::TestView { #forward declaration }
    2019
    21 option add *TestView.font \
    22     -*-helvetica-medium-r-normal-*-12-* widgetDefault
    23 option add *TestView.codeFont \
    24     -*-courier-medium-r-normal-*-12-* widgetDefault
    25 option add *TestView.textFont \
    26     -*-helvetica-medium-r-normal-*-12-* widgetDefault
    27 option add *TestView.boldTextFont \
    28     -*-helvetica-bold-r-normal-*-12-* widgetDefault
     20option add *TestView.font {Arial -12} widgetDefault
     21option add *TestView.titleFont {Arial -18 bold} widgetDefault
     22option add *TestView.statusFont {Arial -12 italic} widgetDefault
     23option add *TestView.statusPassColor black widgetDefault
     24option add *TestView.statusFailColor red widgetDefault
     25option add *TestView*descScroller.width 3i widgetDefault
     26option add *TestView*descScroller.height 1i widgetDefault
    2927
    3028itcl::class Rappture::Tester::TestView {
    3129    inherit itk::Widget
    3230
    33     itk_option define -test test Test ""
     31    itk_option define -statuspasscolor statusPassColor StatusColor ""
     32    itk_option define -statusfailcolor statusFailColor StatusColor ""
     33    itk_option define -runcommand runCommand RunCommand ""
    3434
    3535    constructor {args} { #defined later }
    36 
    37     protected method reset
    38     protected method showDescription {text}
    39     protected method showStatus {text}
    40     protected method updateResults {}
    41     protected method updateInputs {}
    42     protected method updateOutputs {}
    43 
     36    public method show {args}
     37
     38    private method _doRun {}
     39    private method _plural {n}
     40
     41    private variable _testobjs ""  ;# objects being displayed
    4442}
    4543
     
    4947itcl::body Rappture::Tester::TestView::constructor {args} {
    5048
    51     itk_component add status {
    52         label $itk_interior.status
    53     }
    54     pack $itk_component(status) -expand no -fill none -side top -anchor w
    55 
     49    # run button to run selected tests
     50    itk_component add run {
     51        button $itk_interior.run -text "Run" -padx 12 -pady 12 \
     52            -command [itcl::code $this _doRun]
     53    }
     54    pack $itk_component(run) -side right -anchor n
     55
     56    # shows the big icon for test: pass/fail
     57    itk_component add statusicon {
     58        label $itk_interior.sicon
     59    }
     60    pack $itk_component(statusicon) -side left -anchor n
     61
     62    # shows the name of the test
     63    itk_component add title {
     64        label $itk_interior.title -anchor w
     65    } {
     66        usual
     67        rename -font -titlefont titleFont Font
     68    }
     69    pack $itk_component(title) -side top -anchor w
     70
     71    # shows the status of the test: pass/fail
     72    itk_component add statusmesg {
     73        label $itk_interior.smesg -anchor w
     74    } {
     75        usual
     76        rename -font -statusfont statusFont Font
     77        ignore -foreground
     78    }
     79    pack $itk_component(statusmesg) -side top -anchor w
     80
     81    # for the longer text describing the test
    5682    itk_component add descScroller {
    5783        Rappture::Scroller $itk_interior.descScroller \
    5884            -xscrollmode auto -yscrollmode auto
    5985    }
     86    pack $itk_component(descScroller) -expand yes -fill both
    6087
    6188    itk_component add description {
    62         text $itk_interior.descScroller.description -height 0 -wrap word \
    63             -relief flat
     89        text $itk_component(descScroller).desc -height 1 \
     90            -wrap word -relief flat
    6491    }
    6592    $itk_component(descScroller) contents $itk_component(description)
    66     pack $itk_component(descScroller) -expand no -fill x -side top
    67 
    68     itk_component add tabs {
    69         blt::tabset $itk_interior.tabs -borderwidth 0 -relief flat \
    70             -side left -tearoff 0 -highlightthickness 0 \
    71             -selectbackground $itk_option(-background)
    72     } {
    73     }
    74     $itk_component(tabs) insert end "Results" -ipady 25 -fill both
    75     $itk_component(tabs) insert end "Inputs" -ipady 25 -fill both \
    76         -state disabled
    77     $itk_component(tabs) insert end "Outputs" -ipady 25 -fill both \
    78         -state disabled
    79 
    80     itk_component add results {
    81         Rappture::ResultsPage $itk_component(tabs).results
    82     }
    83     $itk_component(tabs) tab configure "Results" \
    84         -window $itk_component(tabs).results
    85 
    86     itk_component add inputScroller {
    87         Rappture::Scroller $itk_component(tabs).inputScroller \
    88             -xscrollmode auto -yscrollmode auto
    89     }
    90 
    91     itk_component add inputs {
    92         blt::treeview $itk_component(inputScroller).inputs -separator . \
    93             -autocreate true
    94     } {
    95         keep -foreground -font -cursor
    96     }
    97     $itk_component(inputs) column insert end "Value"
    98     $itk_component(inputScroller) contents $itk_component(inputs)
    99     $itk_component(tabs) tab configure "Inputs" \
    100         -window $itk_component(inputScroller)
    101 
    102     itk_component add outputScroller {
    103         Rappture::Scroller $itk_component(tabs).outputScroller \
    104             -xscrollmode auto -yscrollmode auto
    105     }
    106 
    107     itk_component add outputs {
    108         blt::treeview $itk_component(outputScroller).outputs -separator . \
    109             -autocreate true
    110     } {
    111         keep -foreground -font -cursor
    112     }
    113     $itk_component(outputs) column insert end "Status"
    114     $itk_component(outputScroller) contents $itk_component(outputs)
    115     $itk_component(tabs) tab configure "Outputs" \
    116         -window $itk_component(outputScroller)
    117 
    118     pack $itk_component(tabs) -expand yes -fill both -side top
    11993
    12094    eval itk_initialize $args
    121 
    122 }
    123 
    124 # ----------------------------------------------------------------------
    125 # CONFIGURATION OPTION: -test
    126 #
    127 # When the -test configuration option is modified, update the display
    128 # accordingly.  The data passed in should be a Test object, or an empty
    129 # string to clear the display.
    130 # ----------------------------------------------------------------------
    131 itcl::configbody Rappture::Tester::TestView::test {
    132     set test $itk_option(-test)
    133     # If an empty string is passed in then clear everything
    134     if {$test == ""} {
    135         reset
     95}
     96
     97itk::usual TestView {
     98    keep -background -foreground -cursor
     99    keep -font -titlefont -statusfont
     100}
     101
     102# ----------------------------------------------------------------------
     103# USAGE: show <testObj> <testObj> ...
     104#
     105# Loads one or more Test objects into the display.  When a single
     106# object is shown, we can display more detail.  When several objects
     107# are shown, we provide overview info.
     108# ----------------------------------------------------------------------
     109itcl::body Rappture::Tester::TestView::show {args} {
     110    foreach obj $args {
     111        if {[catch {$obj isa Test} valid] || !$valid} {
     112            error "bad value \"$obj\": should be Test object"
     113        }
     114    }
     115    set _testobjs $args
     116
     117    switch -- [llength $_testobjs] {
     118        0 {
     119            # If an empty string is passed in then clear everything
     120            $itk_component(title) configure -text ""
     121            $itk_component(statusicon) configure -image ""
     122            $itk_component(statusmesg) configure -text ""
     123            $itk_component(description) configure -state normal
     124            $itk_component(description) delete 1.0 end
     125            $itk_component(description) configure -state disabled
     126            $itk_component(run) configure -state disabled
     127        }
     128        1 {
     129            set obj [lindex $_testobjs 0]
     130            switch [$obj getResult] {
     131                ? {
     132                    set smesg "Ready to run"
     133                    set sicon [Rappture::icon test64]
     134                    set color $itk_option(-statuspasscolor)
     135                }
     136                Pass {
     137                    set smesg "Test passed"
     138                    set sicon [Rappture::icon pass64]
     139                    set color $itk_option(-statuspasscolor)
     140                }
     141                Fail {
     142                    set smesg "Test failed"
     143                    set sicon [Rappture::icon fail64]
     144                    set color $itk_option(-statusfailcolor)
     145                }
     146                default { error "unknown test state \"[$obj getResult]\"" }
     147            }
     148            set name [lindex [split [$obj getTestInfo test.label] |] end]
     149            $itk_component(title) configure -text "Test: $name"
     150            $itk_component(statusicon) configure -image $sicon
     151            $itk_component(statusmesg) configure -text $smesg -foreground $color
     152            $itk_component(description) configure -state normal
     153            $itk_component(description) delete 1.0 end
     154            set desc [string trim [$obj getTestInfo test.description]]
     155            if {$desc eq ""} {
     156                set desc "--"
     157            }
     158            $itk_component(description) insert 1.0 $desc
     159            $itk_component(description) configure -state disabled
     160            $itk_component(run) configure -state normal
     161        }
     162        default {
     163            array set states { ? 0  Pass 0  Fail 0  total 0 }
     164            foreach obj $_testobjs {
     165                incr states(total)
     166                incr states([$obj getResult])
     167            }
     168            if {$states(total) == 1} {
     169                set thistest "This test"
     170            } else {
     171                set thistest "These tests"
     172            }
     173
     174            $itk_component(title) configure \
     175                -text [string totitle [_plural $states(total)]]
     176
     177            switch -glob -- $states(Pass)/$states(Fail)/$states(?) {
     178                0/0/* {
     179                    set smesg "Ready to run"
     180                    set sicon [Rappture::icon test64]
     181                    set color $itk_option(-statuspasscolor)
     182                    set desc ""
     183                }
     184                */0/0 {
     185                    set smesg "$thistest passed"
     186                    set sicon [Rappture::icon pass64]
     187                    set color $itk_option(-statuspasscolor)
     188                    set desc ""
     189                }
     190                0/*/0 {
     191                    set smesg "$thistest failed"
     192                    set sicon [Rappture::icon fail64]
     193                    set color $itk_option(-statusfailcolor)
     194                    set desc ""
     195                }
     196                0/*/* {
     197                    if {$states(Fail) == 1} {
     198                        set smesg "One of these tests failed"
     199                    } else {
     200                        set smesg "Some of these tests failed"
     201                    }
     202                    set sicon [Rappture::icon fail64]
     203                    set color $itk_option(-statusfailcolor)
     204                    set desc "[_plural $states(Fail)] failed\n[_plural $states(?)] need to run"
     205                }
     206                */*/0 {
     207                    if {$states(Pass) == 1} {
     208                        set smesg "One of these tests passed"
     209                    } else {
     210                        set smesg "Some of these tests passed"
     211                    }
     212                    set sicon [Rappture::icon test64]
     213                    set color $itk_option(-statuspasscolor)
     214                    set desc "[_plural $states(Fail)] failed\n[_plural $states(Pass)] passed"
     215                }
     216                default {
     217                    set smesg "Some tests passed, some failed"
     218                    set sicon [Rappture::icon fail64]
     219                    set color $itk_option(-statusfailcolor)
     220                    set desc "[_plural $states(Fail)] failed\n[_plural $states(Pass)] passed\n[_plural $states(?)] need to run"
     221                }
     222            }
     223            $itk_component(statusicon) configure -image $sicon
     224            $itk_component(statusmesg) configure -text $smesg -foreground $color
     225            $itk_component(description) configure -state normal
     226            $itk_component(description) delete 1.0 end
     227            $itk_component(description) insert end $desc
     228            $itk_component(description) configure -state disabled
     229            $itk_component(run) configure -state normal
     230        }
     231    }
     232}
     233
     234# ----------------------------------------------------------------------
     235# USAGE: _doRun
     236#
     237# Invoked when the user presses the "Run" button to invoke the
     238# -runcommand script for this widget.  Invokes the command with
     239# the current test objects appended as arguments.
     240# ----------------------------------------------------------------------
     241itcl::body Rappture::Tester::TestView::_doRun {} {
     242    if {[string length $itk_option(-runcommand)] > 0} {
     243        uplevel #0 $itk_option(-runcommand) $_testobjs
     244    }
     245}
     246
     247# ----------------------------------------------------------------------
     248# USAGE: _plural <num>
     249#
     250# Handy way of generating a plural string.  If <num> is 1, it returns
     251# "1 test".  Otherwise it returns "<num> tests".
     252# ----------------------------------------------------------------------
     253itcl::body Rappture::Tester::TestView::_plural {num} {
     254    if {$num == 1} {
     255        return "1 test"
    136256    } else {
    137         if {![$test isa Test]} {
    138             error "-test option must be a Test object.  $test was given."
    139         }
    140         if {[$test hasRan]} {
    141             switch [$test getResult] {
    142                 Pass {showStatus "Test passed."}
    143                 Fail {showStatus "Test failed."}
    144                 Error {showStatus "Error while running test."}
    145             }
    146         } else {
    147             showStatus "Test has not yet run."
    148         }
    149         updateResults
    150         updateInputs
    151         updateOutputs
    152         set descr [[$test getTestobj] get test.description]
    153         if {$descr == ""} {
    154             set descr "No description."
    155         }
    156         showDescription $descr
    157     }
    158 }
    159 
    160 itk::usual TestView {
    161     keep -background -foreground -font
    162 }
    163 
    164 # ----------------------------------------------------------------------
    165 # USAGE: reset
    166 #
    167 # Resets the entire TestView widget back to the default state.
    168 # ----------------------------------------------------------------------
    169 itcl::body Rappture::Tester::TestView::reset {} {
    170     updateResults
    171     updateInputs
    172     updateOutputs
    173     showStatus ""
    174     showDescription ""
    175 }
    176 
    177 # ----------------------------------------------------------------------
    178 # USAGE: showDescription <text>
    179 #
    180 # Displays a string in the description text space near the top of the
    181 # widget.  If given an empty string, disable the sunken relief effect
    182 # to partially hide the text box.
    183 # ----------------------------------------------------------------------
    184 itcl::body Rappture::Tester::TestView::showDescription {text} {
    185     $itk_component(description) configure -state normal
    186     $itk_component(description) delete 0.0 end
    187     $itk_component(description) insert end "$text"
    188     $itk_component(description) configure -state disabled
    189     if {$text == ""} {
    190         $itk_component(description) configure -relief flat
    191     } else {
    192         $itk_component(description) configure -relief sunken
    193     }
    194 }
    195 
    196 # ----------------------------------------------------------------------
    197 # USAGE: showStatus <text>
    198 #
    199 # Displays a string in the status info space at the top of the widget.
    200 # ----------------------------------------------------------------------
    201 itcl::body Rappture::Tester::TestView::showStatus {text} {
    202     $itk_component(status) configure -text "$text"
    203 }
    204 
    205 # ----------------------------------------------------------------------
    206 # USAGE: updateResults
    207 
    208 # Used internally to update the results tab according to the test
    209 # currently specified by the -test configuration option.  Show the
    210 # golden results contained in the test xml, and if the the test has been
    211 # ran, show the new results as well.
    212 # ----------------------------------------------------------------------
    213 itcl::body Rappture::Tester::TestView::updateResults {} {
    214     $itk_component(results) clear -nodelete
    215     set test $itk_option(-test)
    216     if {$test == ""} {
    217         # Already cleared, do nothing.
    218         # TODO: Eventually display some kinds of message here.
    219     } else {
    220         set test $itk_option(-test)
    221         $itk_component(results) load [$test getTestobj]
    222         if {[$test hasRan]  && [Rappture::library isvalid [$test getRunobj]]} {
    223             $itk_component(results) load [$test getRunobj]
    224         }
    225     }
    226 }
    227 
    228 # ----------------------------------------------------------------------
    229 # USAGE: updateInputs
    230 #
    231 # Used internally to update the inputs tab according to the test
    232 # currently specified by the -test configuration option.  Shows a tree
    233 # representation of all inputs given in the test xml and their given
    234 # values.
    235 # ----------------------------------------------------------------------
    236 itcl::body Rappture::Tester::TestView::updateInputs {} {
    237     $itk_component(inputs) delete 0
    238     set test $itk_option(-test)
    239     if {$test != ""} {
    240         $itk_component(tabs) tab configure "Inputs" -state normal
    241         foreach pair [$test getInputs] {
    242             set path [lindex $pair 0]
    243             set val [lindex $pair 1]
    244             $itk_component(inputs) insert end $path -data [list Value $val]
    245         }
    246         $itk_component(inputs) open -recurse root
    247     }
    248 }
    249 
    250 # ----------------------------------------------------------------------
    251 # USAGE: updateOutputs
    252 #
    253 # Used internally to update the outputs tab according to the test
    254 # currently specified by the -test configuration option.  Shows a tree
    255 # representation of all outputs in the runfile generated by the last run
    256 # of the test, along with their status (ok, diff, added, or missing).
    257 # Disable the outputs tab if test has not been ran, or resulted in an
    258 # error.
    259 # ----------------------------------------------------------------------
    260 itcl::body Rappture::Tester::TestView::updateOutputs {} {
    261     $itk_component(outputs) delete 0
    262     set test $itk_option(-test)
    263     if {$test != "" && [$test hasRan] && [$test getResult] != "Error"} {
    264         $itk_component(tabs) tab configure "Outputs" -state normal
    265         foreach pair [$test getOutputs] {
    266             set path [lindex $pair 0]
    267             set status [lindex $pair 1]
    268             $itk_component(outputs) insert end $path -data [list Status $status]
    269         }
    270         $itk_component(outputs) open -recurse root
    271     } else {
    272         $itk_component(tabs) tab configure "Outputs" -state disabled
    273         # Switch back to results tab if the outputs tab is open and the
    274         # selected test has not been ran.
    275         if {[$itk_component(tabs) index select] == \
    276             [$itk_component(tabs) index -name "Outputs"]} {
    277             set index [$itk_component(tabs) index -name "Results"]
    278             $itk_component(tabs) select $index
    279             $itk_component(tabs) focus $index
    280         }
    281     }
    282 }
    283        
    284        
    285 
     257        return "$num tests"
     258    }
     259}
Note: See TracChangeset for help on using the changeset viewer.