Index: trunk/tester/compare.tcl
===================================================================
--- trunk/tester/compare.tcl	(revision 2012)
+++ trunk/tester/compare.tcl	(revision 2013)
@@ -52,43 +52,2 @@
 }
 
-# ----------------------------------------------------------------------
-# USAGE: makeDriver <tool.xml> <test.xml>
-#
-# Builds and returns a driver library object to be used for running the 
-# test specified by testxml.  Copy current values from test xml into the
-# newly created driver.  If any inputs are present in the new tool.xml 
-# which do not exist in the test xml, use the default value.
-# ----------------------------------------------------------------------
-proc Rappture::Tester::makeDriver {toolxml testxml} {
-    # TODO: Test with various cases, especially with missing input elements
-    # TODO: Any way to copy an object rather than creating a duplicate?
-    # TODO: Sensible way of combining this proc with "merge" below?
-    set toolobj [Rappture::library $toolxml]
-    set golden [Rappture::library $testxml]
-    set driver [Rappture::library $toolxml]
-    return [Rappture::Tester::merge $toolobj $golden $driver]
-}
-
-# ----------------------------------------------------------------------
-# USAGE: merge <toolobj> <golden> <driver> ?path?
-#
-# Used to recursively build up a driver library object for running a
-# test.  Should not be called directly - see makeDriver.
-# ----------------------------------------------------------------------
-proc Rappture::Tester::merge {toolobj golden driver {path input}} {
-    foreach child [$toolobj children $path] {
-        set val [$golden get $path.$child.current]
-        if {$val != ""} {
-            $driver put $path.$child.current $val
-        } else {
-            set def [$toolobj get $path.$child.default]
-            if {$def != ""} {
-                $driver put $path.$child.current $def
-            }
-        }
-        Rappture::Tester::merge $toolobj $golden $driver $path.$child
-    }
-    return $driver
-}
-
-
Index: trunk/tester/tester.tcl
===================================================================
--- trunk/tester/tester.tcl	(revision 2012)
+++ trunk/tester/tester.tcl	(revision 2013)
@@ -71,27 +71,19 @@
     -command Rappture::Tester::runSelected \
     -selectcommand Rappture::Tester::selectionHandler]
-.pw add [Rappture::Tester::TestView .view $params(-tool)]
+.pw add [frame .right]
+Rappture::Tester::TestView .right.view $params(-tool)
+button .right.regoldenize -text "Regoldenize" -state disabled \
+    -command Rappture::Tester::regoldenize
+pack .right.regoldenize -side bottom -anchor e
+pack .right.view -side bottom -expand yes -fill both
 pack .pw -expand yes -fill both
+set curselection ""
+
 # TODO: Handle resizing better
 # TODO: Fix error that occurs only when you click and hold on a test
 #       while the right hand side is empty
 
-set curselection ""
-
-# ----------------------------------------------------------------------
-# USAGE: runAll ?-force?
-#
-# When this method is invoked, all tests contained in the TestTree will
-# be ran sequentially.
-# ----------------------------------------------------------------------
-proc Rappture::Tester::runAll {args} {
-    foreach id [.tree getTests] {
-        runTest $id $args
-    }
-    .view update [.tree getData focus] 
-}
-
-# ----------------------------------------------------------------------
-# USAGE: runSelected ?-force?
+# ----------------------------------------------------------------------
+# USAGE: runSelected
 #
 # When this method is invoked, all tests that are currently selected
@@ -100,53 +92,50 @@
 # TODO: Parallel exection
 # ----------------------------------------------------------------------
-proc Rappture::Tester::runSelected {args} {
+proc Rappture::Tester::runSelected {} {
     foreach id [.tree getSelected] {
-        runTest $id $args
-    }
-    .view update [.tree getData focus]
-}
-
-# ----------------------------------------------------------------------
-# USAGE: runTest <id> ?-ifneeded?
+        runTest $id
+    }
+    selectionHandler -forcerefresh
+}
+
+# ----------------------------------------------------------------------
+# USAGE: runTest <id>
 #
 # Called by runAll and runSelected to run a single test at the tree node
 # specified by the given id.  In most cases, this method should not be
-# called directly.  A driver object is generated by the makeDriver
-# procedure in compare.tcl, and the results given by the new version are
-# compared to the golden result by the compare procedure in compare.tcl
-# ----------------------------------------------------------------------
-proc Rappture::Tester::runTest {id args} {
-    array set data [.tree getData $id]
+# called directly.  A driver object appropriate for running the test is 
+# generated by the makeDriver procedure, and the results given by the 
+# new version are compared to the golden result by the compare
+# procedure.
+# ----------------------------------------------------------------------
+proc Rappture::Tester::runTest {id} {
+    array set darray [.tree getData $id]
     global params
-    if {$data(ran) && [lsearch -exact $args "-ifneeded"] != -1} {
-        # Already ran. Skip.
-        return
-    }
-    set data(result) "Running"
-    .tree setData $id [array get data]
-
-    set driver [Rappture::Tester::makeDriver $params(-tool) $data(testxml)]
+    set darray(result) "Running"
+    .tree setData $id [array get darray]
+
+    set driver [Rappture::Tester::makeDriver $params(-tool) $darray(testxml)]
     set tool [Rappture::Tool ::#auto $driver [file dirname $params(-tool)]]
     foreach {status result} [eval $tool run] break
-    set data(ran) yes
+    set darray(ran) yes
     if {$status == 0 && [Rappture::library isvalid $result]} {
-        set golden [Rappture::library $data(testxml)]
+        set golden [Rappture::library $darray(testxml)]
         set diffs [Rappture::Tester::compare $golden $result output]
         if {$diffs == ""} {
-            set data(result) Pass
+            set darray(result) Pass
         } else {
-            set data(result) Fail
+            set darray(result) Fail
         }
-        set data(diffs) $diffs
-        set data(runfile) [$tool getRunFile]
+        set darray(diffs) $diffs
+        set darray(runfile) [$tool getRunFile]
     } else {
-        set data(result) Error
-        set data(runfile) ""
-    }
-    .tree setData $id [array get data]
-}
-
-# ----------------------------------------------------------------------
-# USAGE: selectionHandler
+        set darray(result) Error
+        set darray(runfile) ""
+    }
+    .tree setData $id [array get darray]
+}
+
+# ----------------------------------------------------------------------
+# USAGE: selectionHandler ?-forcerefresh?
 #
 # Used internally to communicate between the test tree and the right
@@ -154,11 +143,86 @@
 # node's data to the right hand side.
 # ----------------------------------------------------------------------
-proc Rappture::Tester::selectionHandler {} {
+proc Rappture::Tester::selectionHandler {args} {
+    if {[llength $args] > 1} {
+        error "wrong # args: should be \"selectionHandler ?-forcerefresh?\""
+    }
     global curselection
-    set sel [.tree getSelected]
-    if {$sel != $curselection} {
-        .view update [.tree getData focus]
+    set sel [.tree getFocus]
+    if {$sel != $curselection || [lindex $args 0] == "-forcerefresh"} {
+        set data [.tree getData focus]
+        .right.view configure -data $data 
+        array set darray $data
+        if {[array names darray] != "" && $darray(ran)} {
+            .right.regoldenize configure -state normal
+        } else {
+            .right.regoldenize configure -state disabled
+        }
         set curselection $sel
     }
 }
 
+# ----------------------------------------------------------------------
+# USAGE: makeDriver <tool.xml> <test.xml>
+#
+# Builds and returns a driver library object to be used for running the 
+# test specified by testxml.  Copy current values from test xml into the
+# newly created driver.  If any inputs are present in the new tool.xml 
+# which do not exist in the test xml, use the default value.
+# ----------------------------------------------------------------------
+proc Rappture::Tester::makeDriver {toolxml testxml} {
+    # TODO: Test with various cases, especially with missing input elements
+    # TODO: Any way to copy an object rather than creating a duplicate?
+    # TODO: Sensible way of combining this proc with "merge" below?
+    set toolobj [Rappture::library $toolxml]
+    set golden [Rappture::library $testxml]
+    set driver [Rappture::library $toolxml]
+    return [Rappture::Tester::merge $toolobj $golden $driver]
+}
+
+# ----------------------------------------------------------------------
+# USAGE: merge <toolobj> <golden> <driver> ?path?
+#
+# Used to recursively build up a driver library object for running a
+# test.  Should not be called directly - see makeDriver.
+# ----------------------------------------------------------------------
+proc Rappture::Tester::merge {toolobj golden driver {path input}} {
+    foreach child [$toolobj children $path] {
+        set val [$golden get $path.$child.current]
+        if {$val != ""} {
+            $driver put $path.$child.current $val
+        } else {
+            set def [$toolobj get $path.$child.default]
+            if {$def != ""} {
+                $driver put $path.$child.current $def
+            }
+        }
+        Rappture::Tester::merge $toolobj $golden $driver $path.$child
+    }
+    return $driver
+}
+
+# ----------------------------------------------------------------------
+# TODO
+# ----------------------------------------------------------------------
+proc Rappture::Tester::regoldenize {} {
+    set data [.tree getData focus]
+    array set darray $data
+    if {[tk_messageBox -type yesno -icon warning -message "Are you sure you want to regoldenize?\n$darray(testxml) will be overwritten."]} {
+        # Copy test info from existing test xml
+        set newlib [Rappture::library $darray(runfile)]
+        set oldlib [Rappture::library $darray(testxml)]
+        $newlib put test.label [$oldlib get test.label]
+        $newlib put test.description [$oldlib get test.description]
+        # Overwrite test xml
+        set fid [open $darray(testxml) w]
+        puts $fid "<?xml version=\"1.0\"?>" 
+        puts $fid [$newlib xml]
+        close $fid
+        # Update tree data accordingly
+        set darray(result) "Pass"
+        .tree setData focus [array get darray]
+        # Refresh right hand side view
+        selectionHandler -forcerefresh
+    }
+}
+
Index: trunk/tester/testtree.tcl
===================================================================
--- trunk/tester/testtree.tcl	(revision 2012)
+++ trunk/tester/testtree.tcl	(revision 2013)
@@ -41,4 +41,5 @@
     public method getTests {{id 0}}
     public method getSelected {}
+    public method getFocus {}
     public method getData {id}
     public method setData {id data}
@@ -195,4 +196,13 @@
 
 # ----------------------------------------------------------------------
+# USAGE: getFocus
+#
+# Returns index of the focused node in the treeview.
+# ----------------------------------------------------------------------
+itcl::body Rappture::Tester::TestTree::getFocus {} {
+    return [$itk_component(treeview) index focus]
+}
+
+# ----------------------------------------------------------------------
 # USAGE: getData <id>
 #
Index: trunk/tester/testview.tcl
===================================================================
--- trunk/tester/testview.tcl	(revision 2012)
+++ trunk/tester/testview.tcl	(revision 2013)
@@ -35,6 +35,7 @@
     protected method showDescription {text}
     public method update {datapairs}
-    public method clear
-
+    public method reset 
+
+    public variable data
     protected variable _toolobj
 
@@ -76,5 +77,4 @@
     $itk_component(tabs) insert end "Result" -ipady 25 -fill both \
         -state disabled
-    pack $itk_component(tabs) -expand yes -fill both -side top
 
     itk_component add analyzer {
@@ -88,6 +88,53 @@
     }
     $itk_component(tabs) tab configure "Result" -window $itk_component(result)
+    pack $itk_component(tabs) -expand yes -fill both -side top
 
     eval itk_initialize $args
+}
+
+# ----------------------------------------------------------------------
+# When the -data configuration option is modified, update the display
+# accordingly.  The data passed in should be a list of key value pairs
+# from the TestTree widget.
+# ----------------------------------------------------------------------
+itcl::configbody Rappture::Tester::TestView::data {
+    array set darray $data
+    # Data array is empty for branch nodes.
+    if {[array names darray] != ""} {
+        if {$darray(ran)} {
+            switch $darray(result) {
+                Pass {showStatus "Test passed."}
+                Fail {showStatus "Test failed."}
+                Error {showStatus "Error while running test."}
+            }
+            if {$darray(runfile) != ""} {
+                # HACK: Add a new input to differentiate between golden and
+                # test result.  Otherwise, the slider at the bottom won't
+                # be enabled.
+                set golden [Rappture::library $darray(testxml)]
+                $golden put input.run.current "Golden"
+                set result [Rappture::library $darray(runfile)]
+                $result put input.run.current "Test"
+                updateAnalyzer $golden $result
+                updateResult $data
+            } else {
+                updateResult
+            }
+        } else {
+            showStatus "Test has not yet ran."
+            updateResult
+            if {$darray(testxml) != ""} {
+                updateAnalyzer [Rappture::library $darray(testxml)]
+            }
+        }
+        set descr [[Rappture::library $darray(testxml)] get test.description]
+        if {$descr == ""} {
+            set descr "No description."
+        }
+        showDescription $descr
+    } else {
+       # Clear everything if branch node selected
+       reset 
+    }
 }
 
@@ -97,14 +144,11 @@
 
 # ----------------------------------------------------------------------
-# USAGE: clear
+# USAGE: reset 
 #
 # Resets the entire TestView widget back to the default state.
 # ----------------------------------------------------------------------
-itcl::body Rappture::Tester::TestView::clear {} {
+itcl::body Rappture::Tester::TestView::reset {} {
     updateAnalyzer
     updateResult
-    # TODO: Switch back to analyzer tab when disabling result tab
-    $itk_component(tabs) focus [$itk_component(tabs) index -name "Analyzer"]
-    $itk_component(tabs) tab configure "Result" -state disabled 
     showStatus ""
     showDescription ""
@@ -117,5 +161,5 @@
 # both the golden result as well as the test result.  Clears the
 # analyzer space if no arguments are given.
-# Destroys the existing analyzer widget and creates a new one.  
+# HACK: Destroys the existing analyzer widget and creates a new one.  
 # Eventually this should be able to keep the same widget and swap in
 # and out different result sets.
@@ -138,5 +182,5 @@
 
 # ----------------------------------------------------------------------
-# USAGE: updateResult ?datapairs?
+# USAGE: updateResult ?data?
 #
 # Given a set of key value pairs from the test tree, update the result
@@ -146,19 +190,21 @@
 itcl::body Rappture::Tester::TestView::updateResult {args} {
     if {[llength $args] == 0} {
-        $itk_component(result) delete 0.0 end 
-        $itk_component(tabs) focus [$itk_component(tabs) index -name "Result"]
+        $itk_component(result) delete 0.0 end
+        # TODO: Switch back to analyzer tab.  Why doesn't this work?
+        $itk_component(tabs) invoke \
+            [$itk_component(tabs) index -name "Analyzer"]
         $itk_component(tabs) tab configure "Result" -state disabled
         return
     } elseif {[llength $args] == 1} {
-        array set data [lindex $args 0]
+        array set darray [lindex $args 0]
         $itk_component(tabs) tab configure "Result" -state normal
         $itk_component(result) delete 0.0 end
-        $itk_component(result) insert end "Test xml: $data(testxml)\n"
-        $itk_component(result) insert end "Runfile: $data(runfile)\n"
-        if {$data(result) == "Fail"} {
-            $itk_component(result) insert end "Diffs: $data(diffs)\n" 
+        $itk_component(result) insert end "Test xml: $darray(testxml)\n"
+        $itk_component(result) insert end "Runfile: $darray(runfile)\n"
+        if {$darray(result) == "Fail"} {
+            $itk_component(result) insert end "Diffs: $darray(diffs)\n" 
         }
     } else {
-        error "wrong # args: should be \"updateResult ?datapairs?\""
+        error "wrong # args: should be \"updateResult ?data?\""
     }
 }
@@ -192,49 +238,2 @@
 }
 
-# ----------------------------------------------------------------------
-# USAGE: update <datapairs>
-#
-# Given a list of key value pairs from the test tree, update both the
-# analyzer and the result tab.
-# ----------------------------------------------------------------------
-itcl::body Rappture::Tester::TestView::update {datapairs} {
-    array set data $datapairs
-    # Data array is empty for branch nodes.
-    if {[array names data] != ""} {
-        if {$data(ran)} {
-            switch $data(result) {
-                Pass {showStatus "Test passed."}
-                Fail {showStatus "Test failed."}
-                Error {showStatus "Error while running test."}
-            }
-            if {$data(runfile) != ""} {
-                # HACK: Add a new input to differentiate between golden and
-                # test result.  Otherwise, the slider at the bottom won't
-                # be enabled.
-                set golden [Rappture::library $data(testxml)] 
-                $golden put input.run.current "Golden"
-                set result [Rappture::library $data(runfile)] 
-                $result put input.run.current "Test"
-                updateAnalyzer $golden $result 
-                updateResult $datapairs 
-            } else {
-                updateResult 
-            }
-        } else {
-            showStatus "Test has not yet ran."
-            updateResult
-            if {$data(testxml) != ""} {
-                updateAnalyzer [Rappture::library $data(testxml)] 
-            }
-        }
-        set descr [[Rappture::library $data(testxml)] get test.description]
-        if {$descr == ""} {
-            set descr "No description."
-        }
-        showDescription $descr 
-    } else {
-       # clear everything if branch node selected
-       clear
-    }
-}
-
