#!/usr/bin/env python3
"""
GUI framework and application for use with Python unit testing framework.
Execute tests written using the framework provided by the 'unittest' module.

Updated for unittest test discovery by Mark Roddy and Python 3
support by Brian Curtin.

Based on the original by Steve Purcell, from:

  http://pyunit.sourceforge.net/

Copyright (c) 1999, 2000, 2001 Steve Purcell
This module is free software, and you may redistribute it and/or modify
it under the same terms as Python itself, so long as this copyright message
and disclaimer are retained in their original form.

IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.

THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE.  THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS,
AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
"""

__author__ = "Steve Purcell (stephen_purcell@yahoo.com)"

import sys
import traceback
import unittest

import tkinter as tk
from tkinter import messagebox
from tkinter import filedialog
from tkinter import simpledialog




##############################################################################
# GUI framework classes
##############################################################################

class BaseGUITestRunner(object):
    """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
        self.__rollbackImporter = None
        self.__rollbackImporter = RollbackImporter()
        self.test_suite = None

        #test discovery variables
        self.directory_to_read = ''
        self.top_level_dir = ''
        self.test_file_glob_pattern = 'test*.py'

        self.initGUI(*args, **kwargs)

    def errorDialog(self, title, message):
        "Override to display an error arising from GUI usage"
        pass

    def getDirectoryToDiscover(self):
        "Override to prompt user for directory to perform test discovery"
        pass

    def runClicked(self):
        "To be called in response to user choosing to run a test"
        if self.running: return
        if not self.test_suite:
            self.errorDialog("Test Discovery", "You discover some tests first!")
            return
        self.currentResult = GUITestResult(self)
        self.totalTests = self.test_suite.countTestCases()
        self.running = 1
        self.notifyRunning()
        self.test_suite.run(self.currentResult)
        self.running = 0
        self.notifyStopped()

    def stopClicked(self):
        "To be called in response to user stopping the running of a test"
        if self.currentResult:
            self.currentResult.stop()

    def discoverClicked(self):
        self.__rollbackImporter.rollbackImports()
        directory = self.getDirectoryToDiscover()
        if not directory:
            return
        self.directory_to_read = directory
        try:
            # Explicitly use 'None' value if no top level directory is
            # specified (indicated by empty string) as discover() explicitly
            # checks for a 'None' to determine if no tld has been specified
            top_level_dir = self.top_level_dir or None
            tests = unittest.defaultTestLoader.discover(directory, self.test_file_glob_pattern, top_level_dir)
            self.test_suite = tests
        except:
            exc_type, exc_value, exc_tb = sys.exc_info()
            traceback.print_exception(*sys.exc_info())
            self.errorDialog("Unable to run test '%s'" % directory,
                             "Error loading specified test: %s, %s" % (exc_type, exc_value))
            return
        self.notifyTestsDiscovered(self.test_suite)

    # Required callbacks

    def notifyTestsDiscovered(self, test_suite):
        "Override to display information about the suite of discovered tests"
        pass

    def notifyRunning(self):
        "Override to set GUI in 'running' mode, enabling 'stop' button etc."
        pass

    def notifyStopped(self):
        "Override to set GUI in 'stopped' mode, enabling 'run' button etc."
        pass

    def notifyTestFailed(self, test, err):
        "Override to indicate that a test has just failed"
        pass

    def notifyTestErrored(self, test, err):
        "Override to indicate that a test has just errored"
        pass

    def notifyTestSkipped(self, test, reason):
        "Override to indicate that test was skipped"
        pass

    def notifyTestFailedExpectedly(self, test, err):
        "Override to indicate that test has just failed expectedly"
        pass

    def notifyTestStarted(self, test):
        "Override to indicate that a test is about to run"
        pass

    def notifyTestFinished(self, test):
        """Override to indicate that a test has finished (it may already have
           failed or errored)"""
        pass


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

    def addError(self, test, err):
        unittest.TestResult.addError(self, test, err)
        self.callback.notifyTestErrored(test, err)

    def addFailure(self, test, err):
        unittest.TestResult.addFailure(self, test, err)
        self.callback.notifyTestFailed(test, err)

    def addSkip(self, test, reason):
        super(GUITestResult,self).addSkip(test, reason)
        self.callback.notifyTestSkipped(test, reason)

    def addExpectedFailure(self, test, err):
        super(GUITestResult,self).addExpectedFailure(test, err)
        self.callback.notifyTestFailedExpectedly(test, err)

    def stopTest(self, test):
        unittest.TestResult.stopTest(self, test)
        self.callback.notifyTestFinished(test)

    def startTest(self, test):
        unittest.TestResult.startTest(self, test)
        self.callback.notifyTestStarted(test)


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.copy().keys():
            if not modname in self.previousModules:
                # Force reload when modname next imported
                del(sys.modules[modname])


##############################################################################
# Tkinter GUI
##############################################################################

class DiscoverSettingsDialog(simpledialog.Dialog):
    """
    Dialog box for prompting test discovery settings
    """

    def __init__(self, master, top_level_dir, test_file_glob_pattern, *args, **kwargs):
        self.top_level_dir = top_level_dir
        self.dirVar = tk.StringVar()
        self.dirVar.set(top_level_dir)

        self.test_file_glob_pattern = test_file_glob_pattern
        self.testPatternVar = tk.StringVar()
        self.testPatternVar.set(test_file_glob_pattern)

        simpledialog.Dialog.__init__(self, master, title="Discover Settings",
                                     *args, **kwargs)

    def body(self, master):
        tk.Label(master, text="Top Level Directory").grid(row=0)
        self.e1 = tk.Entry(master, textvariable=self.dirVar)
        self.e1.grid(row = 0, column=1)
        tk.Button(master, text="...",
                  command=lambda: self.selectDirClicked(master)).grid(row=0,column=3)

        tk.Label(master, text="Test File Pattern").grid(row=1)
        self.e2 = tk.Entry(master, textvariable = self.testPatternVar)
        self.e2.grid(row = 1, column=1)
        return None

    def selectDirClicked(self, master):
        dir_path = filedialog.askdirectory(parent=master)
        if dir_path:
            self.dirVar.set(dir_path)

    def apply(self):
        self.top_level_dir = self.dirVar.get()
        self.test_file_glob_pattern = self.testPatternVar.get()

class TkTestRunner(BaseGUITestRunner):
    """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.
        """
        self.root = root

        self.statusVar = tk.StringVar()
        self.statusVar.set("Idle")

        #tk vars for tracking counts of test result types
        self.runCountVar = tk.IntVar()
        self.failCountVar = tk.IntVar()
        self.errorCountVar = tk.IntVar()
        self.skipCountVar = tk.IntVar()
        self.expectFailCountVar = tk.IntVar()
        self.remainingCountVar = tk.IntVar()

        self.top = tk.Frame()
        self.top.pack(fill=tk.BOTH, expand=1)
        self.createWidgets()

    def getDirectoryToDiscover(self):
        return filedialog.askdirectory()

    def settingsClicked(self):
        d = DiscoverSettingsDialog(self.top, self.top_level_dir, self.test_file_glob_pattern)
        self.top_level_dir = d.top_level_dir
        self.test_file_glob_pattern = d.test_file_glob_pattern

    def notifyTestsDiscovered(self, test_suite):
        discovered = test_suite.countTestCases()
        self.runCountVar.set(0)
        self.failCountVar.set(0)
        self.errorCountVar.set(0)
        self.remainingCountVar.set(discovered)
        self.progressBar.setProgressFraction(0.0)
        self.errorListbox.delete(0, tk.END)
        self.statusVar.set("Discovering tests from %s. Found: %s" %
            (self.directory_to_read, discovered))
        self.stopGoButton['state'] = tk.NORMAL

    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.
        """
        # Status bar
        statusFrame = tk.Frame(self.top, relief=tk.SUNKEN, borderwidth=2)
        statusFrame.pack(anchor=tk.SW, fill=tk.X, side=tk.BOTTOM)
        tk.Label(statusFrame, width=1, textvariable=self.statusVar).pack(side=tk.TOP, fill=tk.X)

        # Area to enter name of test to run
        leftFrame = tk.Frame(self.top, borderwidth=3)
        leftFrame.pack(fill=tk.BOTH, side=tk.LEFT, anchor=tk.NW, expand=1)
        suiteNameFrame = tk.Frame(leftFrame, borderwidth=3)
        suiteNameFrame.pack(fill=tk.X)

        # 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.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)

        tk.Button(buttonFrame, text="Discover Tests",
                  command=self.discoverClicked).pack(fill=tk.X)


        self.stopGoButton = tk.Button(buttonFrame, text="Start",
                                      command=self.runClicked, state=tk.DISABLED)
        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="Settings",
                  command=self.settingsClicked).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),
                           ('Skipped:', self.skipCountVar),
                           ('Expected Failures:', self.expectFailCountVar),
                           ('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)

        # 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)
        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.configure(yscrollcommand=listScroll.set)

    def errorDialog(self, title, message):
        messagebox.showerror(parent=self.root, title=title,
                             message=message)

    def notifyRunning(self):
        self.runCountVar.set(0)
        self.failCountVar.set(0)
        self.errorCountVar.set(0)
        self.remainingCountVar.set(self.totalTests)
        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")
        self.stopGoButton.config(state=tk.DISABLED)
        self.progressBar.setProgressFraction(0.0)
        self.top.update_idletasks()

    def notifyStopped(self):
        self.stopGoButton.config(state=tk.DISABLED)
        #self.stopGoButton.config(command=self.runClicked, text="Start")
        self.statusVar.set("Idle")

    def notifyTestStarted(self, test):
        self.statusVar.set(str(test))
        self.top.update_idletasks()

    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))

    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))

    def notifyTestSkipped(self, test, reason):
        super(TkTestRunner, self).notifyTestSkipped(test, reason)
        self.skipCountVar.set(1 + self.skipCountVar.get())

    def notifyTestFailedExpectedly(self, test, err):
        super(TkTestRunner, self).notifyTestFailedExpectedly(test, err)
        self.expectFailCountVar.set(1 + self.expectFailCountVar.get())


    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)
        fillColor = len(self.errorInfo) and "red" or "green"
        self.progressBar.setProgressFraction(fractionDone, fillColor)

    def showSelectedError(self):
        selection = self.errorListbox.curselection()
        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)
        test, error = self.errorInfo[selected]
        tk.Label(window, text=str(test),
                 foreground="red", justify=tk.LEFT).pack(anchor=tk.W)
        tracebackLines =  traceback.format_exception(*error)
        tracebackText = "".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())
        window.mainloop()
        window.destroy()


class ProgressBar(tk.Frame):
    """A simple progress bar that shows a percentage progress in
    the given colour."""

    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.pack(fill=tk.X, expand=1)
        self.rect = self.text = None
        self.canvas.bind('<Configure>', self.paint)
        self.setProgressFraction(0.0)

    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)
        percentString = "%3.0f%%" % (100.0 * self.fraction)
        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.mainloop()


if __name__ == '__main__':
    if len(sys.argv) == 2:
        main(sys.argv[1])
    else:
        main()
