Test: Final application of pre-commit

This commit is contained in:
Chris Hennes
2023-09-04 07:32:05 -05:00
committed by Chris Hennes
parent 217674de04
commit efd11e590d
14 changed files with 154 additions and 145 deletions

View File

@@ -113,7 +113,7 @@ Click 'start', and the test thus produced will be run.
Double click on an error in the tree view to see more information about it, including the stack trace.</source>
<translation>Introduïu el nom d'un objecte cridable que quan es cridi retorni un TestCase.
Feu clic a 'Comença' i s'executarà el test anteriorment produït.
Feu clic a 'Comença' i s'executarà el test anteriorment produït.
Feu doble clic a un error a la vista d'arbre per veure'n més informació, incloent-hi la traça de pila.</translation>
</message>

View File

@@ -127,7 +127,7 @@ Haga doble clic en un error en la vista de árbol para ver más información al
<source>Copyright (c) Werner Mayer
FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for ones own modules.</source>
<translation>Copyright (c) Werner Mayer
<translation>Copyright (c) Werner Mayer
Unidad de Prueba FreeCAD es parte de FreeCAD y soporta escribir pruebas unitarias para los propios módulos.</translation>
</message>

View File

@@ -127,7 +127,7 @@ Haga doble clic en un error en la vista de árbol para ver más información sob
<source>Copyright (c) Werner Mayer
FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for ones own modules.</source>
<translation>Copyright (c) Werner Mayer
<translation>Copyright (c) Werner Mayer
FreeCAD UnitTest es parte de FreeCAD y soporta escribir pruebas unitarias para los propios módulos.</translation>
</message>

View File

@@ -113,7 +113,7 @@ Click 'start', and the test thus produced will be run.
Double click on an error in the tree view to see more information about it, including the stack trace.</source>
<translation>Írja be a nevét a hívható objektumnak, amely hívásakor, visszatér egy Tesztre.
Nyomjon 'Indítás'-t, és az így készült vizsgálat futni fog.
Nyomjon 'Indítás'-t, és az így készült vizsgálat futni fog.
Dupla kattintással, a fa nézeten további információkat kap, beleértve a verem-nyomkövetést.</translation>
</message>
@@ -127,7 +127,7 @@ Dupla kattintással, a fa nézeten további információkat kap, beleértve a ve
<source>Copyright (c) Werner Mayer
FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for ones own modules.</source>
<translation>Copyright (c) Werner Mayer
<translation>Copyright (c) Werner Mayer
FreeCAD UnitTest része a FreeCAD programnak és támogatja a saját modulokra a Unit tesztek írását.</translation>
</message>

View File

@@ -126,7 +126,7 @@ Fare doppio clic su un errore nell'albero per visualizzare maggiori informazioni
<source>Copyright (c) Werner Mayer
FreeCAD UnitTest is part of FreeCAD and supports writing Unit Tests for ones own modules.</source>
<translation>Copyright (c) Werner Mayer
<translation>Copyright (c) Werner Mayer
FreeCAD UnitTest fa parte di FreeCAD e supporta la scrittura di Unit test per i propri moduli.</translation>
</message>

View File

@@ -113,7 +113,7 @@ Click 'start', and the test thus produced will be run.
Double click on an error in the tree view to see more information about it, including the stack trace.</source>
<translation>Nhập tên của một đi tượng thể gọi đưc khi đi tượng đó đưc gọi, trở lại thành một Trường hợp kiểm tra.
Nhấp chuột 'bắt đầu', sau đó bài kiểm tra đưc tạo sẽ hoạt đng.
Nhấp chuột 'bắt đầu', sau đó bài kiểm tra đưc tạo sẽ hoạt đng.
Nhấp đúp vào một lỗi trong chế đ xem hình cây đ xem thêm thông tin về , bao gồm cả ngăn xếp.</translation>
</message>

View File

@@ -1,24 +1,24 @@
#***************************************************************************
#* Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU Lesser General Public License (LGPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* FreeCAD is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with FreeCAD; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#***************************************************************************/
# ***************************************************************************
# * Copyright (c) 2006 Werner Mayer <werner.wm.mayer@gmx.de> *
# * *
# * This file is part of the FreeCAD CAx development system. *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
# * GNU Library General Public License for more details. *
# * *
# * You should have received a copy of the GNU Library General Public *
# * License along with FreeCAD; if not, write to the Free Software *
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
# * USA *
# ***************************************************************************/
# Qt Unit test module
@@ -29,7 +29,7 @@ import traceback
# Cannot import this file in case Python is not prepared for Tk.
# Copy the needed classes instead.
#import unittestgui
# import unittestgui
import unittest
import sys
@@ -45,12 +45,14 @@ import string
# For more details see also http://pyunit.sourceforge.net.
##############################################################################
class BaseGUITestRunner:
"""Subclass this class to create a GUI TestRunner that uses a specific
windowing toolkit. The class takes care of running tests in the correct
manner, and making callbacks to the derived class to obtain information
or signal that events have occurred.
"""
def __init__(self, *args, **kwargs):
self.currentResult = None
self.running = 0
@@ -67,7 +69,8 @@ class BaseGUITestRunner:
def runClicked(self):
"To be called in response to user choosing to run a test"
if self.running: return
if self.running:
return
testName = self.getSelectedTestName()
if not testName:
self.errorDialog("Test name entry", "You must enter a test name")
@@ -79,11 +82,12 @@ class BaseGUITestRunner:
test = unittest.defaultTestLoader.loadTestsFromName(testName)
except Exception:
exc_type, exc_value, exc_tb = sys.exc_info()
#apply(traceback.print_exception,sys.exc_info())
# apply(traceback.print_exception,sys.exc_info())
traceback.print_exception(*sys.exc_info())
self.errorDialog("Unable to run test '%s'" % testName,
"Error loading specified test: %s, %s" % \
(exc_type, exc_value))
self.errorDialog(
"Unable to run test '%s'" % testName,
"Error loading specified test: %s, %s" % (exc_type, exc_value),
)
return
self.currentResult = GUITestResult(self)
self.totalTests = test.countTestCases()
@@ -98,15 +102,17 @@ class BaseGUITestRunner:
expectedFails = unexpectedSuccesses = skipped = 0
try:
results = map(len, (result.expectedFailures,
result.unexpectedSuccesses,
result.skipped))
results = map(
len, (result.expectedFailures, result.unexpectedSuccesses, result.skipped)
)
except AttributeError:
pass
else:
expectedFails, unexpectedSuccesses, skipped = results
self.stream.write("\n{}\nRan {} tests in {:.3}s\n\n".format("-" * 70, result.testsRun, timeTaken))
self.stream.write(
"\n{}\nRan {} tests in {:.3}s\n\n".format("-" * 70, result.testsRun, timeTaken)
)
infos = []
if not result.wasSuccessful():
failed, errored = len(result.failures), len(result.errors)
@@ -125,7 +131,6 @@ class BaseGUITestRunner:
else:
self.stream.write("OK\n")
def stopClicked(self):
"To be called in response to user stopping the running of a test"
if self.currentResult:
@@ -155,7 +160,7 @@ class BaseGUITestRunner:
def notifyTestFinished(self, test):
"""Override to indicate that a test has finished (it may already have
failed or errored)"""
failed or errored)"""
pass
@@ -163,6 +168,7 @@ class GUITestResult(unittest.TestResult):
"""A TestResult that makes callbacks to its associated GUI TestRunner.
Used by BaseGUITestRunner. Need not be created directly.
"""
def __init__(self, callback):
unittest.TestResult.__init__(self)
self.callback = callback
@@ -188,6 +194,7 @@ class RollbackImporter:
"""This tricky little class is used to make sure that modules under test
will be reloaded the next time they are imported.
"""
def __init__(self):
self.previousModules = sys.modules.copy()
@@ -195,18 +202,17 @@ class RollbackImporter:
for modname in sys.modules.keys():
if modname not in self.previousModules:
# Force reload when modname next imported
del(sys.modules[modname])
del sys.modules[modname]
#---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Subclass of BaseGUITestRunner using Qt dialog
#---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
class QtTestRunner(BaseGUITestRunner):
"""An implementation of BaseGUITestRunner using Qt.
"""
"""An implementation of BaseGUITestRunner using Qt."""
def initGUI(self, root, initialTestName):
"""Set up the GUI inside the given root window. The test name entry
field will be pre-filled with the given initialTestName.
@@ -214,7 +220,8 @@ class QtTestRunner(BaseGUITestRunner):
self.root = root
# Set up values that will be tied to widgets
import QtUnitGui
self.gui=QtUnitGui.UnitTest()
self.gui = QtUnitGui.UnitTest()
self.gui.setStatusText("Idle")
self.runCountVar = 0
self.failCountVar = 0
@@ -229,13 +236,13 @@ class QtTestRunner(BaseGUITestRunner):
return self.gui.errorDialog(title, message)
def notifyRunning(self):
self.runCountVar=0
self.runCountVar = 0
self.gui.setRunCount(0)
self.failCountVar=0
self.failCountVar = 0
self.gui.setFailCount(0)
self.errorCountVar=0
self.errorCountVar = 0
self.gui.setErrorCount(0)
self.remainingCountVar=self.totalTests
self.remainingCountVar = self.totalTests
self.gui.setRemainCount(self.totalTests)
self.errorInfo = []
self.gui.clearErrorList()
@@ -250,32 +257,32 @@ class QtTestRunner(BaseGUITestRunner):
self.gui.updateGUI()
def notifyTestFailed(self, test, err):
self.failCountVar=self.failCountVar+1
self.failCountVar = self.failCountVar + 1
self.gui.setFailCount(self.failCountVar)
#tracebackLines = apply(traceback.format_exception, err + (10,))
# tracebackLines = apply(traceback.format_exception, err + (10,))
tracebackLines = traceback.format_exception(*err + (10,))
#tracebackText = string.join(tracebackLines,'')
tracebackText = ''.join(tracebackLines)
self.gui.insertError("Failure: %s" % test,tracebackText)
self.errorInfo.append((test,err))
# tracebackText = string.join(tracebackLines,'')
tracebackText = "".join(tracebackLines)
self.gui.insertError("Failure: %s" % test, tracebackText)
self.errorInfo.append((test, err))
self.stream.write("FAILED: {}\n{}\n".format(test, tracebackText))
def notifyTestErrored(self, test, err):
self.errorCountVar=self.errorCountVar+1
self.errorCountVar = self.errorCountVar + 1
self.gui.setErrorCount(self.errorCountVar)
#tracebackLines = apply(traceback.format_exception, err + (10,))
# tracebackLines = apply(traceback.format_exception, err + (10,))
tracebackLines = traceback.format_exception(*err + (10,))
#tracebackText = string.join(tracebackLines,'')
tracebackText = ''.join(tracebackLines)
self.gui.insertError("Error: %s" % test,tracebackText)
self.errorInfo.append((test,err))
# tracebackText = string.join(tracebackLines,'')
tracebackText = "".join(tracebackLines)
self.gui.insertError("Error: %s" % test, tracebackText)
self.errorInfo.append((test, err))
self.stream.write("{}\nERROR: {}\n{}\n{}\n".format("=" * 70, test, "-" * 70, tracebackText))
def notifyTestFinished(self, test):
self.remainingCountVar=self.remainingCountVar-1
self.remainingCountVar = self.remainingCountVar - 1
self.gui.setRemainCount(self.remainingCountVar)
self.runCountVar=self.runCountVar+1
self.runCountVar = self.runCountVar + 1
self.gui.setRunCount(self.runCountVar)
fractionDone = float(self.runCountVar)/float(self.totalTests)
fractionDone = float(self.runCountVar) / float(self.totalTests)
fillColor = len(self.errorInfo) and "red" or "green"
self.gui.setProgressFraction(fractionDone, fillColor)

View File

@@ -3,4 +3,4 @@
<name>Bad root node</name>
<description>The root node is not called "package".</description>
<version>1.0.0</version>
</notpackage>
</notpackage>

View File

@@ -3,4 +3,4 @@
<name>Bad format</name>
<description>There is no such thing as format version 2 (yet).</description>
<version>1.0.0</version>
</package>
</package>

View File

@@ -2,4 +2,4 @@
<package format="1" xmlns="https://wiki.freecad.org/Package_Metadata">
<name>Bad XML</notname>
<description>The name tag is not closed properly.</description>
</package>
</package>

View File

@@ -18,4 +18,4 @@
<icon>Resources/icons/PackageIcon.svg</icon>
<tag>Tag0</tag>
<tag>Tag1</tag>
</package>
</package>

View File

@@ -60,5 +60,5 @@
<name>Doesn't Really Matter</name>
</other_content_item>
</content>
</package>
</package>

View File

@@ -5,4 +5,3 @@
See \ref src/Mod/Draft/draft.dox for example on how to populate a .dox file.
*/

View File

@@ -40,12 +40,14 @@ import string
# GUI framework classes
##############################################################################
class BaseGUITestRunner:
"""Subclass this class to create a GUI TestRunner that uses a specific
windowing toolkit. The class takes care of running tests in the correct
manner, and making callbacks to the derived class to obtain information
or signal that events have occurred.
"""
def __init__(self, *args, **kwargs):
self.currentResult = None
self.running = 0
@@ -62,7 +64,8 @@ class BaseGUITestRunner:
def runClicked(self):
"To be called in response to user choosing to run a test"
if self.running: return
if self.running:
return
testName = self.getSelectedTestName()
if not testName:
self.errorDialog("Test name entry", "You must enter a test name")
@@ -75,9 +78,10 @@ class BaseGUITestRunner:
except Exception:
exc_type, exc_value, exc_tb = sys.exc_info()
traceback.print_exception(*sys.exc_info())
self.errorDialog("Unable to run test '%s'" % testName,
"Error loading specified test: %s, %s" % \
(exc_type, exc_value))
self.errorDialog(
"Unable to run test '%s'" % testName,
"Error loading specified test: %s, %s" % (exc_type, exc_value),
)
return
self.currentResult = GUITestResult(self)
self.totalTests = test.countTestCases()
@@ -116,7 +120,7 @@ class BaseGUITestRunner:
def notifyTestFinished(self, test):
"""Override to indicate that a test has finished (it may already have
failed or errored)"""
failed or errored)"""
pass
@@ -124,6 +128,7 @@ class GUITestResult(unittest.TestResult):
"""A TestResult that makes callbacks to its associated GUI TestRunner.
Used by BaseGUITestRunner. Need not be created directly.
"""
def __init__(self, callback):
unittest.TestResult.__init__(self)
self.callback = callback
@@ -149,21 +154,22 @@ class RollbackImporter:
"""This tricky little class is used to make sure that modules under test
will be reloaded the next time they are imported.
"""
def __init__(self):
self.previousModules = sys.modules.copy()
def rollbackImports(self):
for modname in sys.modules.keys():
if modname not in self.previousModules:
# Force reload when modname next imported
del(sys.modules[modname])
del sys.modules[modname]
##############################################################################
# Tkinter GUI
##############################################################################
_ABOUT_TEXT="""\
_ABOUT_TEXT = """\
PyUnit unit testing framework.
For more information, visit
@@ -172,7 +178,7 @@ http://pyunit.sourceforge.net/
Copyright (c) 2000 Steve Purcell
<stephen_purcell@yahoo.com>
"""
_HELP_TEXT="""\
_HELP_TEXT = """\
Enter the name of a callable object which, when called, will return a \
TestCase or TestSuite. Click 'start', and the test thus produced will be run.
@@ -184,9 +190,10 @@ http://pyunit.sourceforge.net/
or see the bundled documentation
"""
class TkTestRunner(BaseGUITestRunner):
"""An implementation of BaseGUITestRunner using Tkinter.
"""
"""An implementation of BaseGUITestRunner using Tkinter."""
def initGUI(self, root, initialTestName):
"""Set up the GUI inside the given root window. The test name entry
field will be pre-filled with the given initialTestName.
@@ -207,7 +214,7 @@ class TkTestRunner(BaseGUITestRunner):
def createWidgets(self):
"""Creates and packs the various widgets.
Why is it that GUI code always ends up looking a mess, despite all the
best intentions to keep it tidy? Answers on a postcard, please.
"""
@@ -225,61 +232,58 @@ class TkTestRunner(BaseGUITestRunner):
e = tk.Entry(suiteNameFrame, textvariable=self.suiteNameVar, width=25)
e.pack(side=tk.LEFT, fill=tk.X, expand=1)
e.focus_set()
e.bind('<Key-Return>', lambda e, self=self: self.runClicked())
e.bind("<Key-Return>", lambda e, self=self: self.runClicked())
# Progress bar
progressFrame = tk.Frame(leftFrame, relief=tk.GROOVE, borderwidth=2)
progressFrame.pack(fill=tk.X, expand=0, anchor=tk.NW)
tk.Label(progressFrame, text="Progress:").pack(anchor=tk.W)
self.progressBar = ProgressBar(progressFrame, relief=tk.SUNKEN,
borderwidth=2)
self.progressBar = ProgressBar(progressFrame, relief=tk.SUNKEN, borderwidth=2)
self.progressBar.pack(fill=tk.X, expand=1)
# Area with buttons to start/stop tests and quit
buttonFrame = tk.Frame(self.top, borderwidth=3)
buttonFrame.pack(side=tk.LEFT, anchor=tk.NW, fill=tk.Y)
self.stopGoButton = tk.Button(buttonFrame, text="Start",
command=self.runClicked)
self.stopGoButton = tk.Button(buttonFrame, text="Start", command=self.runClicked)
self.stopGoButton.pack(fill=tk.X)
tk.Button(buttonFrame, text="Close",
command=self.top.quit).pack(side=tk.BOTTOM, fill=tk.X)
tk.Button(buttonFrame, text="About",
command=self.showAboutDialog).pack(side=tk.BOTTOM, fill=tk.X)
tk.Button(buttonFrame, text="Help",
command=self.showHelpDialog).pack(side=tk.BOTTOM, fill=tk.X)
tk.Button(buttonFrame, text="Close", command=self.top.quit).pack(side=tk.BOTTOM, fill=tk.X)
tk.Button(buttonFrame, text="About", command=self.showAboutDialog).pack(
side=tk.BOTTOM, fill=tk.X
)
tk.Button(buttonFrame, text="Help", command=self.showHelpDialog).pack(
side=tk.BOTTOM, fill=tk.X
)
# Area with labels reporting results
for label, var in (('Run:', self.runCountVar),
('Failures:', self.failCountVar),
('Errors:', self.errorCountVar),
('Remaining:', self.remainingCountVar)):
for label, var in (
("Run:", self.runCountVar),
("Failures:", self.failCountVar),
("Errors:", self.errorCountVar),
("Remaining:", self.remainingCountVar),
):
tk.Label(progressFrame, text=label).pack(side=tk.LEFT)
tk.Label(progressFrame, textvariable=var,
foreground="blue").pack(side=tk.LEFT, fill=tk.X,
expand=1, anchor=tk.W)
tk.Label(progressFrame, textvariable=var, foreground="blue").pack(
side=tk.LEFT, fill=tk.X, expand=1, anchor=tk.W
)
# List box showing errors and failures
tk.Label(leftFrame, text="Failures and errors:").pack(anchor=tk.W)
listFrame = tk.Frame(leftFrame, relief=tk.SUNKEN, borderwidth=2)
listFrame.pack(fill=tk.BOTH, anchor=tk.NW, expand=1)
self.errorListbox = tk.Listbox(listFrame, foreground='red',
selectmode=tk.SINGLE,
selectborderwidth=0)
self.errorListbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=1,
anchor=tk.NW)
self.errorListbox = tk.Listbox(
listFrame, foreground="red", selectmode=tk.SINGLE, selectborderwidth=0
)
self.errorListbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=1, anchor=tk.NW)
listScroll = tk.Scrollbar(listFrame, command=self.errorListbox.yview)
listScroll.pack(side=tk.LEFT, fill=tk.Y, anchor=tk.N)
self.errorListbox.bind("<Double-1>",
lambda e, self=self: self.showSelectedError())
self.errorListbox.bind("<Double-1>", lambda e, self=self: self.showSelectedError())
self.errorListbox.configure(yscrollcommand=listScroll.set)
def getSelectedTestName(self):
return self.suiteNameVar.get()
def errorDialog(self, title, message):
tkMessageBox.showerror(parent=self.root, title=title,
message=message)
tkMessageBox.showerror(parent=self.root, title=title, message=message)
def notifyRunning(self):
self.runCountVar.set(0)
@@ -289,15 +293,15 @@ class TkTestRunner(BaseGUITestRunner):
self.errorInfo = []
while self.errorListbox.size():
self.errorListbox.delete(0)
#Stopping seems not to work, so simply disable the start button
#self.stopGoButton.config(command=self.stopClicked, text="Stop")
# Stopping seems not to work, so simply disable the start button
# self.stopGoButton.config(command=self.stopClicked, text="Stop")
self.stopGoButton.config(state=tk.DISABLED)
self.progressBar.setProgressFraction(0.0)
self.top.update_idletasks()
def notifyStopped(self):
self.stopGoButton.config(state=tk.ACTIVE)
#self.stopGoButton.config(command=self.runClicked, text="Start")
# self.stopGoButton.config(command=self.runClicked, text="Start")
self.statusVar.set("Idle")
def notifyTestStarted(self, test):
@@ -307,45 +311,42 @@ class TkTestRunner(BaseGUITestRunner):
def notifyTestFailed(self, test, err):
self.failCountVar.set(1 + self.failCountVar.get())
self.errorListbox.insert(tk.END, "Failure: %s" % test)
self.errorInfo.append((test,err))
self.errorInfo.append((test, err))
def notifyTestErrored(self, test, err):
self.errorCountVar.set(1 + self.errorCountVar.get())
self.errorListbox.insert(tk.END, "Error: %s" % test)
self.errorInfo.append((test,err))
self.errorInfo.append((test, err))
def notifyTestFinished(self, test):
self.remainingCountVar.set(self.remainingCountVar.get() - 1)
self.runCountVar.set(1 + self.runCountVar.get())
fractionDone = float(self.runCountVar.get())/float(self.totalTests)
fractionDone = float(self.runCountVar.get()) / float(self.totalTests)
fillColor = len(self.errorInfo) and "red" or "green"
self.progressBar.setProgressFraction(fractionDone, fillColor)
def showAboutDialog(self):
tkMessageBox.showinfo(parent=self.root, title="About PyUnit",
message=_ABOUT_TEXT)
tkMessageBox.showinfo(parent=self.root, title="About PyUnit", message=_ABOUT_TEXT)
def showHelpDialog(self):
tkMessageBox.showinfo(parent=self.root, title="PyUnit help",
message=_HELP_TEXT)
tkMessageBox.showinfo(parent=self.root, title="PyUnit help", message=_HELP_TEXT)
def showSelectedError(self):
selection = self.errorListbox.curselection()
if not selection: return
if not selection:
return
selected = int(selection[0])
txt = self.errorListbox.get(selected)
window = tk.Toplevel(self.root)
window.title(txt)
window.protocol('WM_DELETE_WINDOW', window.quit)
window.protocol("WM_DELETE_WINDOW", window.quit)
test, error = self.errorInfo[selected]
tk.Label(window, text=str(test),
foreground="red", justify=tk.LEFT).pack(anchor=tk.W)
tk.Label(window, text=str(test), foreground="red", justify=tk.LEFT).pack(anchor=tk.W)
tracebackLines = traceback.format_exception(*error + (10,))
tracebackText = string.join(tracebackLines,'')
tracebackText = string.join(tracebackLines, "")
tk.Label(window, text=tracebackText, justify=tk.LEFT).pack()
tk.Button(window, text="Close",
command=window.quit).pack(side=tk.BOTTOM)
window.bind('<Key-Return>', lambda e, w=window: w.quit())
tk.Button(window, text="Close", command=window.quit).pack(side=tk.BOTTOM)
window.bind("<Key-Return>", lambda e, w=window: w.quit())
window.mainloop()
window.destroy()
@@ -356,42 +357,44 @@ class ProgressBar(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(*(self,) + args, **kwargs)
self.canvas = tk.Canvas(self, height='20', width='60',
background='white', borderwidth=3)
self.canvas = tk.Canvas(self, height="20", width="60", background="white", borderwidth=3)
self.canvas.pack(fill=tk.X, expand=1)
self.rect = self.text = None
self.canvas.bind('<Configure>', self.paint)
self.canvas.bind("<Configure>", self.paint)
self.setProgressFraction(0.0)
def setProgressFraction(self, fraction, color='blue'):
def setProgressFraction(self, fraction, color="blue"):
self.fraction = fraction
self.color = color
self.paint()
self.canvas.update_idletasks()
def paint(self, *args):
totalWidth = self.canvas.winfo_width()
width = int(self.fraction * float(totalWidth))
height = self.canvas.winfo_height()
if self.rect is not None: self.canvas.delete(self.rect)
if self.text is not None: self.canvas.delete(self.text)
self.rect = self.canvas.create_rectangle(0, 0, width, height,
fill=self.color)
if self.rect is not None:
self.canvas.delete(self.rect)
if self.text is not None:
self.canvas.delete(self.text)
self.rect = self.canvas.create_rectangle(0, 0, width, height, fill=self.color)
percentString = "%3.0f%%" % (100.0 * self.fraction)
self.text = self.canvas.create_text(totalWidth/2, height/2,
anchor=tk.CENTER,
text=percentString)
self.text = self.canvas.create_text(
totalWidth / 2, height / 2, anchor=tk.CENTER, text=percentString
)
def main(initialTestName=""):
root = tk.Tk()
root.title("PyUnit")
runner = TkTestRunner(root, initialTestName)
root.protocol('WM_DELETE_WINDOW', root.quit)
root.protocol("WM_DELETE_WINDOW", root.quit)
root.mainloop()
if __name__ == '__main__':
if __name__ == "__main__":
import sys
if len(sys.argv) == 2:
main(sys.argv[1])
else: