diff --git a/gooey/_tmp/__init__.py b/gooey/_tmp/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/_tmp/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/_tmp/mockapp.py b/gooey/_tmp/mockapp.py new file mode 100644 index 0000000..61a7bd2 --- /dev/null +++ b/gooey/_tmp/mockapp.py @@ -0,0 +1,69 @@ +''' +Created on Dec 21, 2013 + +@author: Chris +''' +import sys +import hashlib +from time import time as _time +from time import sleep as _sleep +# from argparse import ArgumentParser +# import argparse +import argparse as ap +from argparse import ArgumentParser as AP + + +a = globals() + + +def main(): + ''' + does stuff with parser.parse_args() + ''' + desc = "Mock application to test Gooey's functionality" + file_help_msg = "Name of the file you want to process" + my_cool_parser = ap.ArgumentParser(description=desc) + my_cool_parser.add_argument("filename", help=file_help_msg, metavar='asdf') # positional + my_cool_parser.add_argument("outfile", help="Name of the file where you'll save the output") # positional + my_cool_parser.add_argument('-c', '--countdown', default=10, type=int, help='sets the time to count down from you see its quite simple!') + my_cool_parser.add_argument("-s", "--showtime", action="store_true", help="display the countdown timer") + my_cool_parser.add_argument("-d", "--delay", action="store_true", help="Delay execution for a bit") + my_cool_parser.add_argument('-v', '--verbose', action='count') + my_cool_parser.add_argument("-o", "--obfuscate", action="store_true", help="obfuscate the countdown timer!") + my_cool_parser.add_argument('-r', '--recursive', choices=['yes', 'no'], help='Recurse into subfolders') + my_cool_parser.add_argument("-w", "--writelog", default="No, NOT whatevs", help="write log to some file or something") + my_cool_parser.add_argument("-e", "--expandAll", action="store_true", help="expand all processes") + verbosity = my_cool_parser.add_mutually_exclusive_group() + verbosity.add_argument('-t', '--verbozze', dest='verbose', action="store_true", help="Show more details") + verbosity.add_argument('-q', '--quiet', dest='quiet', action="store_true", help="Only output on error") + + print 'inside of main(), my_cool_parser =', my_cool_parser + args = my_cool_parser.parse_args() + + print sys.argv + print args.countdown + print args.showtime + + start_time = _time() + print 'Counting down from %s' % args.countdown + while _time() - start_time < args.countdown: + if args.showtime: + print 'printing message at: %s' % _time() + else: + print 'printing message at: %s' % hashlib.md5(str(_time())).hexdigest() + _sleep(.5) + print 'Finished running the program. Byeeeeesss!' + +# raise ValueError("Something has gone wrong! AHHHHHHHHHHH") + +if __name__ == '__main__': + print sys.argv + main() + # import inspect + # import dis + # # print dir(main.__code__) + # # for i in dir(main.__code__): + # # print i, getattr(main.__code__, i) + # print dis.dis(main.__code__) + # # for i in inspect.getmembers(main): + # # print i diff --git a/gooey/gui/componenets2_runner.py b/gooey/gui/componenets2_runner.py deleted file mode 100644 index 73f0434..0000000 --- a/gooey/gui/componenets2_runner.py +++ /dev/null @@ -1,77 +0,0 @@ -__author__ = 'Chris' - -import wx -from wx.lib.scrolledpanel import ScrolledPanel - - -class TestPanel(ScrolledPanel): - def __init__(self, parent): - ScrolledPanel.__init__(self, parent) - self.SetupScrolling(scroll_x=False) - - self.textctrls = [wx.TextCtrl(self) for _ in range(1)] - - sizer = wx.BoxSizer(wx.VERTICAL) - hsizer = wx.BoxSizer(wx.HORIZONTAL) - for textctrl in self.textctrls: - hsizer.Add(textctrl, 1, wx.EXPAND) - textctrl.SetMinSize((10,23)) - - sizer.Add(hsizer, 0, wx.EXPAND) - self.SetSizer(sizer) - -class MyFrame(wx.Frame): - def __init__(self, parent): - wx.Frame.__init__(self, parent, title="test", size=(320, 240)) - self.SetBackgroundColour('#ffffff') - self.panel = TestPanel(self) - self.Show() - -if __name__ == '__main__': - app = wx.App(False) - MyFrame(None) - app.MainLoop() - - - - - # a = { - # 'required' : [ - # { - # 'component': 'TextField', - # 'data': { - # 'display_name': 'filename', - # 'help_text': 'path to file you want to process', - # 'command_args': ['-f', '--infile'] - # } - # }, - # { - # 'component': 'FileChooser', - # 'data': { - # 'display_name': 'Output Location', - # 'help_text': 'Where to save the file', - # 'command_args': ['-o', '--outfile'] - # } - # } - # ], - # 'optional' : [ - # { - # 'component': 'RadioGroup', - # 'data': [ - # { - # 'display_name': 'Output Location', - # 'help_text': 'Where to save the file', - # 'command_args': ['-o', '--outfile'] - # }, { - # 'display_name': 'Output Location', - # 'help_text': 'Where to save the file', - # 'command_args': ['-o', '--outfile'] - # } - # ] - # } - # ] - # } - # - # ] - # } - diff --git a/gooey/gui/controller.py b/gooey/gui/controller.py index f01cebc..2f4388a 100644 --- a/gooey/gui/controller.py +++ b/gooey/gui/controller.py @@ -4,13 +4,13 @@ Created on Dec 22, 2013 @author: Chris ''' import subprocess +import sys +from multiprocessing.dummy import Pool, Process import wx -import sys -import traceback -from gooey import i18n -from multiprocessing.dummy import Pool, Process +from gooey.gui.lang import i18n + YES = 5103 NO = 5104 @@ -32,9 +32,9 @@ class Controller(object): translator = instance of the I18N class ''' - def __init__(self, base_frame): + def __init__(self, base_frame, build_spec): self.core_gui = base_frame - # self._payload_runner = Process(target=self.RunClientCode) + self.build_spec = build_spec def OnCancelButton(self, widget, event): msg = i18n.translate('sure_you_want_to_exit') diff --git a/gooey/image_repository.py b/gooey/gui/image_repository.py similarity index 90% rename from gooey/image_repository.py rename to gooey/gui/image_repository.py index 535ec8e..33f25e9 100644 --- a/gooey/image_repository.py +++ b/gooey/gui/image_repository.py @@ -1,9 +1,10 @@ import os + __author__ = 'Chris' base_path = os.path.dirname(__file__) -image_dir = os.path.join(base_path, 'images') +image_dir = os.path.join(base_path, '../images') alessandro_rei_checkmark = os.path.join(image_dir, "alessandro_rei_checkmark.png") computer = os.path.join(image_dir, "computer.png") diff --git a/gooey/i18n.py b/gooey/gui/lang/i18n.py similarity index 85% rename from gooey/i18n.py rename to gooey/gui/lang/i18n.py index 52ddbba..4ff4a79 100644 --- a/gooey/i18n.py +++ b/gooey/gui/lang/i18n.py @@ -9,12 +9,14 @@ Provides Internationalization for all text within the program. import os import json -import i18n_config + +from gooey.gui.lang import i18n_config + __all__ = ['translate'] _LANG = i18n_config.LANG -_DEFAULT_DIR = os.path.join(os.path.dirname(__file__), 'languages') +_DEFAULT_DIR = os.path.join(os.path.dirname(__file__), '../../languages') _DICTIONARY = None diff --git a/gooey/i18n_config.py b/gooey/gui/lang/i18n_config.py similarity index 100% rename from gooey/i18n_config.py rename to gooey/gui/lang/i18n_config.py diff --git a/gooey/gui/widgets/components2.py b/gooey/gui/widgets/components2.py index f47b3ca..272e03d 100644 --- a/gooey/gui/widgets/components2.py +++ b/gooey/gui/widgets/components2.py @@ -101,10 +101,11 @@ class BaseGuiComponent(object): evt.Skip() def GetValue(self): - if self.widget_pack.getValue() and self.data['commands']: - return '{} {}'.format(self.data['commands'][0], self.widget_pack.getValue()) - else: - return self.widget_pack.getValue() + return self.widget_pack.getValue() + + def _GetWidget(self): + # used only for unittesting + return self.widget_pack.widget class CheckBox(BaseGuiComponent): @@ -153,7 +154,10 @@ class CheckBox(BaseGuiComponent): evt.Skip() def GetValue(self): - return self.option_strings[0] if self.widget.GetValue() else '' + return self.option_strings if self.widget.GetValue() else '' + + def _GetWidget(self): + return self.widget class RadioGroup(object): @@ -221,6 +225,11 @@ class RadioGroup(object): except: return '' + def _GetWidget(self): + return self.radio_buttons + + + FileChooser = lambda data: BaseGuiComponent(data=data, widget_pack=widget_pack.FileChooserPayload()) diff --git a/gooey/gui/widgets/widget_pack.py b/gooey/gui/widgets/widget_pack.py index c4eb9cf..7f63e98 100644 --- a/gooey/gui/widgets/widget_pack.py +++ b/gooey/gui/widgets/widget_pack.py @@ -32,13 +32,15 @@ class WidgetPack(object): class BaseChooser(WidgetPack): def __init__(self, button_text='Browse'): self.button_text = button_text - + self.option_string = None self.parent = None self.text_box = None self.button = None def build(self, parent, data=None): + self.parent = parent + self.option_string = data['commands'][0] if data['commands'] else '' self.text_box = wx.TextCtrl(self.parent) self.text_box.SetMinSize((0, -1)) self.button = wx.Button(self.parent, label=self.button_text, size=(73, 23)) @@ -100,15 +102,25 @@ class DateChooserPayload(BaseChooser): class TextInputPayload(WidgetPack): def __init__(self): self.widget = None + self.option_string = None def build(self, parent, data): + self.option_string = data['commands'][0] if data['commands'] else '' self.widget = wx.TextCtrl(parent) self.widget.SetMinSize((0, -1)) self.widget.SetDoubleBuffered(True) return self.widget def getValue(self): - return self.widget.GetValue() + if self.widget.GetValue() and self.option_string: + return '{} {}'.format(self.option_string, self.widget.GetValue()) + else: + return self.widget.GetValue() + + def _SetValue(self, text): + # used for testing + self.widget.SetLabelText(text) + class DropdownPayload(WidgetPack): @@ -130,8 +142,15 @@ class DropdownPayload(WidgetPack): def getValue(self): if self.widget.GetValue() == self.default_value: - return None - return ' '.join([self.option_string, self.widget.GetValue()]) + return '' + elif self.widget.GetValue() and self.option_string: + return '{} {}'.format(self.option_string, self.widget.GetValue()) + else: + self.widget.GetValue() + + def _SetValue(self, text): + # used for testing + self.widget.SetLabelText(text) class CounterPayload(WidgetPack): @@ -159,7 +178,7 @@ class CounterPayload(WidgetPack): ''' dropdown_value = self.widget.GetValue() if not str(dropdown_value).isdigit(): - return None + return '' arg = str(self.option_string).replace('-', '') repeated_args = arg * int(dropdown_value) return '-' + repeated_args diff --git a/gooey/gui/windows/advanced_config.py b/gooey/gui/windows/advanced_config.py index 4d3e472..6485675 100644 --- a/gooey/gui/windows/advanced_config.py +++ b/gooey/gui/windows/advanced_config.py @@ -8,8 +8,8 @@ from itertools import chain import wx from wx.lib.scrolledpanel import ScrolledPanel -from gooey import i18n from gooey.gui import component_builder +from gooey.gui.lang import i18n from gooey.gui.option_reader import OptionReader from gooey.gui import styling diff --git a/gooey/gui/windows/base_window.py b/gooey/gui/windows/base_window.py index 359f2d1..c99c792 100644 --- a/gooey/gui/windows/base_window.py +++ b/gooey/gui/windows/base_window.py @@ -5,18 +5,13 @@ Created on Jan 19, 2014 import os import sys -import time -from collections import deque import wx -from gooey.gui.message_event import MessageEvent -from gooey import i18n -from gooey import image_repository from gooey.gui.controller import Controller -from gooey.gui.message_router import MessageRouter +from gooey.gui.lang import i18n from gooey.gui.windows.runtime_display_panel import RuntimeDisplay -from gooey.gui import styling +from gooey.gui import styling, image_repository from gooey.gui.windows import footer, header @@ -79,7 +74,7 @@ class BaseWindow(wx.Frame): self.SetSizer(sizer) def _init_controller(self): - self._controller = Controller(base_frame=self) + self._controller = Controller(base_frame=self, build_spec=self.build_spec) def registerControllers(self): for panel in self.panels: @@ -111,7 +106,6 @@ class BaseWindow(wx.Frame): def onResize(self, evt): evt.Skip() - def PublishConsoleMsg(self, text): self.runtime_display.cmd_textbox.AppendText(text) # evt = MessageEvent(message=text) diff --git a/gooey/gui/windows/basic_config_panel.py b/gooey/gui/windows/basic_config_panel.py index 25ee09e..488afd2 100644 --- a/gooey/gui/windows/basic_config_panel.py +++ b/gooey/gui/windows/basic_config_panel.py @@ -4,11 +4,11 @@ Created on Dec 9, 2013 @author: Chris ''' - import wx +from gooey.gui.lang import i18n from gooey.gui.option_reader import OptionReader -from gooey import i18n + class BasicConfigPanel(wx.Panel, OptionReader): def __init__(self, parent, **kwargs): @@ -49,4 +49,4 @@ class BasicConfigPanel(wx.Panel, OptionReader): return self.cmd_textbox.GetValue() def RegisterController(self, controller): - pass \ No newline at end of file + pass diff --git a/gooey/gui/windows/footer.py b/gooey/gui/windows/footer.py index 17b40e6..fd4e1e0 100644 --- a/gooey/gui/windows/footer.py +++ b/gooey/gui/windows/footer.py @@ -6,9 +6,9 @@ Created on Dec 23, 2013 import wx import wx.animate -from gooey import i18n -from gooey.gui import imageutil -from gooey import image_repository + +from gooey.gui import imageutil, image_repository +from gooey.gui.lang import i18n class AbstractFooter(wx.Panel): diff --git a/gooey/gui/windows/header.py b/gooey/gui/windows/header.py index 5ef4849..4b9da09 100644 --- a/gooey/gui/windows/header.py +++ b/gooey/gui/windows/header.py @@ -4,13 +4,12 @@ Created on Dec 23, 2013 @author: Chris ''' -import itertools - import wx -from gooey import i18n -from gooey.gui import imageutil -from gooey import image_repository + +from gooey.gui import imageutil, image_repository from gooey.gui import styling +from gooey.gui.lang import i18n + PAD_SIZE = 10 diff --git a/gooey/gui/windows/runtime_display_panel.py b/gooey/gui/windows/runtime_display_panel.py index 43f8831..c956b37 100644 --- a/gooey/gui/windows/runtime_display_panel.py +++ b/gooey/gui/windows/runtime_display_panel.py @@ -5,9 +5,10 @@ Created on Dec 23, 2013 ''' import sys + import wx -from gooey import i18n +from gooey.gui.lang import i18n from gooey.gui.message_event import EVT_MSG diff --git a/gooey/mockapplications/mockapp.py b/gooey/mockapplications/mockapp.py index 5373f88..e378469 100644 --- a/gooey/mockapplications/mockapp.py +++ b/gooey/mockapplications/mockapp.py @@ -7,17 +7,25 @@ import sys import hashlib from time import time as _time from time import sleep as _sleep -from argparse import ArgumentParser +# from argparse import ArgumentParser +# import argparse +import argparse as ap +from argparse import ArgumentParser as AP from gooey import Gooey +a = globals() + @Gooey def main(): + ''' + does stuff with parser.parse_args() + ''' desc = "Mock application to test Gooey's functionality" file_help_msg = "Name of the file you want to process" - my_cool_parser = ArgumentParser(description=desc) - my_cool_parser.add_argument("filename", help=file_help_msg) # positional + my_cool_parser = ap.ArgumentParser(description=desc) + my_cool_parser.add_argument("filename", help=file_help_msg, metavar='asdf') # positional my_cool_parser.add_argument("outfile", help="Name of the file where you'll save the output") # positional my_cool_parser.add_argument('-c', '--countdown', default=10, type=int, help='sets the time to count down from you see its quite simple!') my_cool_parser.add_argument("-s", "--showtime", action="store_true", help="display the countdown timer") @@ -25,11 +33,11 @@ def main(): my_cool_parser.add_argument('-v', '--verbose', action='count') my_cool_parser.add_argument("-o", "--obfuscate", action="store_true", help="obfuscate the countdown timer!") my_cool_parser.add_argument('-r', '--recursive', choices=['yes', 'no'], help='Recurse into subfolders') - # my_cool_parser.add_argument("-w", "--writelog", default="No, NOT whatevs", help="write log to some file or something") - # my_cool_parser.add_argument("-e", "--expandAll", action="store_true", help="expand all processes") - # verbosity = my_cool_parser.add_mutually_exclusive_group() - # verbosity.add_argument('-t', '--verbozze', dest='verbose', action="store_true", help="Show more details") - # verbosity.add_argument('-q', '--quiet', dest='quiet', action="store_true", help="Only output on error") + my_cool_parser.add_argument("-w", "--writelog", default="No, NOT whatevs", help="write log to some file or something") + my_cool_parser.add_argument("-e", "--expandAll", action="store_true", help="expand all processes") + verbosity = my_cool_parser.add_mutually_exclusive_group() + verbosity.add_argument('-t', '--verbozze', dest='verbose', action="store_true", help="Show more details") + verbosity.add_argument('-q', '--quiet', dest='quiet', action="store_true", help="Only output on error") print 'inside of main(), my_cool_parser =', my_cool_parser args = my_cool_parser.parse_args() diff --git a/gooey/python_bindings/argparse_to_json.py b/gooey/python_bindings/argparse_to_json.py index 5ee5407..3c33d97 100644 --- a/gooey/python_bindings/argparse_to_json.py +++ b/gooey/python_bindings/argparse_to_json.py @@ -199,4 +199,3 @@ def widget_type(option_string): - diff --git a/gooey/python_bindings/gooey_decorator.py b/gooey/python_bindings/gooey_decorator.py index 3359994..49ec3dc 100644 --- a/gooey/python_bindings/gooey_decorator.py +++ b/gooey/python_bindings/gooey_decorator.py @@ -41,15 +41,23 @@ to us. No more complicated ast stuff. Just a little bit of string parsing and we done. ''' +from argparse import ArgumentParser from functools import partial +import os +import sys import wx +from gooey.gui.lang import i18n from gooey.python_bindings import argparse_to_json -from gooey import i18n import source_parser + +ROOT_DIR = os.path.dirname(__import__(__name__.split('.')[0]).__file__) +TMP_DIR = os.path.join(ROOT_DIR, '_tmp') + + def Gooey(f=None, advanced=True, language='english', show_config=True, program_name=None, program_description=None): @@ -64,11 +72,17 @@ def Gooey(f=None, advanced=True, params = locals() - - def build(payload): def inner(): - module_path = get_caller_path() + main_module_path = get_caller_path() + _, filename = os.path.split(main_module_path) + cleaned_source = clean_source(main_module_path) + + filepath = os.path.join(TMP_DIR, filename) + with open(filepath, 'w') as f: + f.write(cleaned_source) + + run_cmd = 'python {}'.format(filepath) # Must be called before anything else app = wx.App(False) @@ -83,10 +97,10 @@ def Gooey(f=None, advanced=True, from gooey.gui.windows.basic_config_panel import BasicConfigPanel if show_config: - parser = get_parser(module_path) + parser = get_parser(main_module_path) meta = { - 'target': get_caller_path(), + 'target': run_cmd, 'program_name': program_name, 'program_description': program_description or parser.description, 'show_config': show_config, @@ -124,17 +138,23 @@ def Gooey(f=None, advanced=True, return build +def clean_source(module_path): + with open(module_path, 'r') as f: + return ''.join( + line for line in f.readlines() + if '@gooey' not in line.lower() + and 'import gooey' not in line.lower()) + + +def run(): + parser = source_parser.extract_parser(module_path) + client_module = create_cleaned_backup() + + def get_parser(module_path): - # try: return source_parser.extract_parser(module_path) - # except source_parser.ParserError: - # raise source_parser.ParserError( - # 'Could not locate ArgumentParser statements in Main().' - # '\nThis is probably my fault :( Please checkout github.com/chriskiehl/gooey to file a bug!') def get_caller_path(): - # utility func for decorator - # gets the name of the calling script tmp_sys = __import__('sys') return tmp_sys.argv[0] diff --git a/gooey/python_bindings/source_parser.py b/gooey/python_bindings/source_parser.py index ece7787..a29b1ff 100644 --- a/gooey/python_bindings/source_parser.py +++ b/gooey/python_bindings/source_parser.py @@ -48,7 +48,7 @@ def parse_source_file(file_name): argparse_assignments = get_nodes_by_containing_attr(assignment_objs, 'ArgumentParser') add_arg_assignments = get_nodes_by_containing_attr(call_objects, 'add_argument') - # parse_args_assignment = get_nodes_by_containing_attr(call_objects, 'parse_args') + parse_args_assignment = get_nodes_by_containing_attr(call_objects, 'parse_args') ast_argparse_source = chain( module_imports, @@ -115,31 +115,36 @@ def get_indent(line): indent = re.compile("(\t|\s)") return ''.join(takewhile(lambda char: indent.match(char) is not None, line)) -def format_source_to_return_parser(source): - varname = get_assignment_name(source) - - client_source = [line for line in source - if '@gooey' not in line.lower() - and 'import gooey' not in line.lower()] - - top = takewhile(not_at_parse_args, client_source) - middle = dropwhile(not_at_parse_args, client_source) - # need this so the return statement is indented the - # same amount as the rest of the source - indent_width = get_indent(next(middle)) - - # chew off everything until you get to the end of the - # current block - bottom = dropwhile(lines_indented, middle) - # inject a return - return_statement = ['{}return {}\n\n'.format(indent_width, varname)] - # stitch it all back together - new_source = chain(top, return_statement, bottom) +def format_source_to_return_parser(source, cutoff_line, restart_line, col_offset, parser_name): + top = source[:cutoff_line - 1] + bottom = source[restart_line:] + + return_statement = ['{}return {}\n\n'.format(' ' * col_offset, parser_name)] + + # stitch it all back together excluding the Gooey decorator + new_source = (line for line in chain(top, return_statement, bottom) + if '@gooey' not in line.lower() + and 'import gooey' not in line.lower()) + return ''.join(new_source) def extract_parser(modulepath): source = read_client_module(modulepath) - module_source = format_source_to_return_parser(source) + + nodes = ast.parse(''.join(source)) + funcs = get_nodes_by_instance_type(nodes, _ast.FunctionDef) + assignment_objs = get_nodes_by_instance_type(nodes, _ast.Assign) + + main_func = get_nodes_by_containing_attr(funcs, 'main')[0] + parse_args_assignment = get_nodes_by_containing_attr(main_func.body, 'parse_args')[0] + + module_source = format_source_to_return_parser( + source, + cutoff_line=parse_args_assignment.lineno, + restart_line=main_func.body[-1].lineno, + col_offset=parse_args_assignment.col_offset, + parser_name=parse_args_assignment.value.func.value.id + ) client_module = modules.load(module_source) return client_module.main() diff --git a/gooey/tests/gui/__init__.py b/gooey/tests/gui/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/tests/gui/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/tests/gui/widgets/__init__.py b/gooey/tests/gui/widgets/__init__.py new file mode 100644 index 0000000..6bca6f6 --- /dev/null +++ b/gooey/tests/gui/widgets/__init__.py @@ -0,0 +1 @@ +__author__ = 'Chris' diff --git a/gooey/tests/gui/widgets/componenets2_runner.py b/gooey/tests/gui/widgets/componenets2_runner.py new file mode 100644 index 0000000..d9e5c70 --- /dev/null +++ b/gooey/tests/gui/widgets/componenets2_runner.py @@ -0,0 +1,194 @@ +from gooey.gui.widgets import components2 + +__author__ = 'Chris' + +import unittest +import wx +from wx.lib.scrolledpanel import ScrolledPanel + +TEXT_FIELD = components2.TextField({ + 'display_name': 'cool title', + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-f', '--fudge'], + 'choices': [] +}) + +DROPDOWN = components2.Dropdown({ + 'display_name': 'cool title', + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-f', '--fudge'], + 'choices': ['one', 'two', 'three'] +}) + +COUNTER = components2.Counter({ + 'display_name': 'cool title', + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-f', '--fudge'], + 'choices': [] +}) + +CHECKBOX = components2.CheckBox({ + 'display_name': 'cool title', + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-f', '--fudge'], + 'choices': [] +}) + +RADIOGROUP = components2.RadioGroup({ + 'display_name': 'mutux options', + 'data': [{ + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-f', '--fudge'], + 'choices': [] + }, { + 'help_msg': 'a help message', + 'nargs': '+', + 'commands': ['-g', '--gudge'], + 'choices': [] + }] +}) + + +class TestPanel(ScrolledPanel): + def __init__(self, parent, widget): + ScrolledPanel.__init__(self, parent) + self.SetupScrolling(scroll_x=False) + + sizer = wx.BoxSizer(wx.VERTICAL) + self.widget = widget + + sizer.Add(self.widget.build(self), 0, wx.EXPAND) + self.SetSizer(sizer) + + +class MyFrame(wx.Frame): + def __init__(self, parent, widget): + wx.Frame.__init__(self, parent, title="test", size=(320, 240)) + self.SetBackgroundColour('#ffffff') + self.panel = TestPanel(self, widget) + self.Show() + + def get_widget(self): + return self.panel.widget + + def close(self): + self.Destroy() + + + +class TestComponents(unittest.TestCase): + + def setUp(self): + self.app = wx.App(False) + self.frame = None + + def tearDown(self): + # self.app = wx.App(False) + self.frame.Destroy() + self.frame = None + + def test_textfield_returns_option_and_value_else_none(self): + self.build_test_frame(TEXT_FIELD) + self.assertTrue(self.get_value() == '') + self.get_widget().SetLabelText('value') + self.assertEqual('-f value', self.get_value()) + + + def test_dropdown_returns_option_and_value_else_none(self): + self.build_test_frame(DROPDOWN) + self.assertTrue(self.get_value() == '') + # grab first item from the combo box + self.frame.get_widget()._GetWidget().SetSelection(0) + self.assertEqual('-f one', self.get_value()) + + + def test_counter_returns_option_and_value_else_none(self): + self.build_test_frame(COUNTER) + self.assertTrue(self.get_value() == '') + # counter objects stack, + # so + # 1 = -f, + # 4 = -ffff + self.frame.get_widget()._GetWidget().SetSelection(0) + self.assertEqual('-f', self.get_value()) + self.frame.get_widget()._GetWidget().SetSelection(4) + self.assertEqual('-fffff', self.get_value()) + + + def test_checkbox_returns_option_if_checked_else_none(self): + self.build_test_frame(CHECKBOX) + self.assertTrue(self.get_value() == '') + self.frame.get_widget()._GetWidget().SetValue(1) + self.assertEqual('-f', self.get_value()) + + + def test_radiogroup_returns_option_if_checked_else_none(self): + self.build_test_frame(RADIOGROUP) + self.assertTrue(self.get_value() == '') + # self.frame.get_widget()._GetWidget()[0].SetValue(1) + # self.assertEqual('-f', self.get_value()) + + + def build_test_frame(self, widget): + # self.app = wx.App(False) + self.frame = MyFrame(None, widget) + + def get_widget(self): + return self.frame.get_widget()._GetWidget() + + def get_value(self): + return self.frame.get_widget().GetValue() + + + +if __name__ == '__main__': + unittest.main() + + + + + # a = { + # 'required' : [ + # { + # 'component': 'TextField', + # 'data': { + # 'display_name': 'filename', + # 'help_text': 'path to file you want to process', + # 'command_args': ['-f', '--infile'] + # } + # }, + # { + # 'component': 'FileChooser', + # 'data': { + # 'display_name': 'Output Location', + # 'help_text': 'Where to save the file', + # 'command_args': ['-o', '--outfile'] + # } + # } + # ], + # 'optional' : [ + # { + # 'component': 'RadioGroup', + # 'data': [ + # { + # 'display_name': 'Output Location', + # 'help_text': 'Where to save the file', + # 'command_args': ['-o', '--outfile'] + # }, { + # 'display_name': 'Output Location', + # 'help_text': 'Where to save the file', + # 'command_args': ['-o', '--outfile'] + # } + # ] + # } + # ] + # } + # + # ] + # } + diff --git a/gooey/tests/i18n_unittest.py b/gooey/tests/i18n_unittest.py index 8f7c2f2..a0d9e33 100644 --- a/gooey/tests/i18n_unittest.py +++ b/gooey/tests/i18n_unittest.py @@ -5,8 +5,9 @@ Created on Jan 25, 2014 ''' import unittest + import i18n -import i18n_config + # from i18n import I18N diff --git a/gooey/tests/source_parser_unittest.py b/gooey/tests/source_parser_unittest.py index eb89873..b593ed8 100644 --- a/gooey/tests/source_parser_unittest.py +++ b/gooey/tests/source_parser_unittest.py @@ -14,8 +14,7 @@ TODO: import os import ast import unittest - -import source_parser +from gooey.python_bindings import source_parser basic_pyfile = '''