mirror of https://github.com/chriskiehl/Gooey.git
14 changed files with 1242 additions and 174 deletions
Split View
Diff Options
-
1gooey/tests/integration/README.md
-
7gooey/tests/integration/__init__.py
-
68gooey/tests/integration/integ_autostart.py
-
62gooey/tests/integration/integ_subparser_demo.py
-
48gooey/tests/integration/integ_validations.py
-
64gooey/tests/integration/integ_widget_demo.py
-
0gooey/tests/integration/programs/__init__.py
-
94gooey/tests/integration/programs/all_widgets.py
-
147gooey/tests/integration/programs/all_widgets_subparser.py
-
27gooey/tests/integration/programs/auto_start.py
-
645gooey/tests/integration/programs/gooey_config.json
-
33gooey/tests/integration/programs/validations.py
-
46gooey/tests/integration/runner.py
-
174gooey/tests/test_integration.py
@ -0,0 +1 @@ |
|||
These integration tests must be run one at a time. I can't figure out how to clear the wx context between runs and Unittest doesn't allow process isolation.. |
@ -0,0 +1,7 @@ |
|||
""" |
|||
Integration tests that exercise Gooey's various run modes |
|||
|
|||
WX Python needs to control the main thread. So, in order to simulate a user |
|||
running through the system, we have to execute the actual assertions in a |
|||
different thread |
|||
""" |
@ -0,0 +1,68 @@ |
|||
import time |
|||
import unittest |
|||
|
|||
from gooey.gui.lang.i18n import _ |
|||
from tests.integration.programs import auto_start as auto_start_module |
|||
|
|||
|
|||
class TestGooeyIntegration(unittest.TestCase): |
|||
|
|||
def test__gooeyAutoStart(self): |
|||
"""Verifies that issue #201 doesn't regress and auto_start skips the config |
|||
screen and hops right into the client's program""" |
|||
from gooey.tests.integration import runner |
|||
runner.run_integration(auto_start_module, self.verifyAutoStart, auto_start=True) |
|||
|
|||
def verifyAutoStart(self, app, buildSpec): |
|||
""" |
|||
When the auto_start flag == True Gooey should skip the |
|||
configuration screen |
|||
""" |
|||
time.sleep(1) |
|||
try: |
|||
# Gooey should NOT be showing the name/description headers |
|||
# present on the config page |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertNotEqual(title, buildSpec['program_name']) |
|||
self.assertNotEqual(subtitle, buildSpec['program_description']) |
|||
|
|||
# Gooey should be showing the console messages straight away |
|||
# without manually starting the program |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title,_("running_title")) |
|||
self.assertEqual(subtitle, _('running_msg')) |
|||
|
|||
# Wait for Gooey to swap the header to the final screen |
|||
while app.TopWindow.header._header.GetLabel() == _("running_title"): |
|||
time.sleep(.1) |
|||
|
|||
# verify that we've landed on the success screen |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, _("finished_title")) |
|||
self.assertEqual(subtitle, _('finished_msg')) |
|||
|
|||
|
|||
# and that output was actually written to the console |
|||
self.assertIn("Success", app.TopWindow.console.textbox.GetValue()) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
import wx |
|||
wx.CallAfter(app.TopWindow.Destroy) |
|||
return None |
|||
|
|||
|
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,62 @@ |
|||
import wx |
|||
import time |
|||
import unittest |
|||
|
|||
from gooey.gui.lang.i18n import _ |
|||
from tests.integration.programs import \ |
|||
all_widgets_subparser as all_widgets_subparser_module |
|||
|
|||
|
|||
class TestGooeyIntegration11(unittest.TestCase): |
|||
|
|||
def test_gooeySubparserMode(self): |
|||
""" Tests the happy path through the subparser run mode of Gooey """ |
|||
from gooey.tests.integration import runner |
|||
runner.run_integration(all_widgets_subparser_module, self.gooeySanityTest) |
|||
|
|||
def gooeySanityTest(self, app, buildSpec): |
|||
try: |
|||
# Check out header is present and showing data |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, buildSpec['program_name']) |
|||
self.assertEqual(subtitle, buildSpec['program_description']) |
|||
|
|||
# switch to the run screen |
|||
app.TopWindow.onStart() |
|||
|
|||
# Should find the expected test in the header |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title,_("running_title")) |
|||
self.assertEqual(subtitle, _('running_msg')) |
|||
|
|||
# Wait for Gooey to swap the header to the final screen |
|||
while app.TopWindow.header._header.GetLabel() == _("running_title"): |
|||
time.sleep(.1) |
|||
|
|||
# verify that we've landed on the success screen |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, _("finished_title")) |
|||
self.assertEqual(subtitle, _('finished_msg')) |
|||
|
|||
# and that output was actually written to the console |
|||
self.assertIn("Success", app.TopWindow.console.textbox.GetValue()) |
|||
time.sleep(1) |
|||
except: |
|||
wx.CallAfter(app.TopWindow.Destroy) |
|||
raise |
|||
else: |
|||
wx.CallAfter(app.TopWindow.Destroy) |
|||
return None |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,48 @@ |
|||
import time |
|||
import unittest |
|||
|
|||
from tests.integration.programs import validations as validations_module |
|||
|
|||
|
|||
class TestGooeyIntegration(unittest.TestCase): |
|||
""" |
|||
A few quick integration tests that exercise Gooey's various run modes |
|||
|
|||
WX Python needs to control the main thread. So, in order to simulate a user |
|||
running through the system, we have to execute the actual assertions in a |
|||
different thread |
|||
""" |
|||
|
|||
def test__gooeyValidation(self): |
|||
"""Verifies that custom validation routines supplied via gooey_options prevents |
|||
the user from advancing past the configuration page when they fail""" |
|||
from gooey.tests.integration import runner |
|||
runner.run_integration(validations_module, self.verifyValidators) |
|||
|
|||
|
|||
def verifyValidators(self, app, buildSpec): |
|||
time.sleep(1) |
|||
try: |
|||
app.TopWindow.onStart() |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertNotEqual(title, buildSpec['program_name']) |
|||
self.assertNotEqual(subtitle, buildSpec['program_description']) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
import wx |
|||
wx.CallAfter(app.TopWindow.Destroy) |
|||
return None |
|||
|
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,64 @@ |
|||
import time |
|||
import unittest |
|||
|
|||
import wx |
|||
from gooey.gui.lang.i18n import _ |
|||
from tests.integration.programs import all_widgets as all_widgets_module |
|||
|
|||
|
|||
class TestGooeyIntegration99(unittest.TestCase): |
|||
|
|||
|
|||
def test_gooeyNormalRun(self): |
|||
""" Tests the happy path through the default run mode of Gooey """ |
|||
from gooey.tests.integration import runner |
|||
runner.run_integration(all_widgets_module, self.gooeySanityTest) |
|||
|
|||
|
|||
def gooeySanityTest(self, app, buildSpec): |
|||
time.sleep(1) |
|||
try: |
|||
# Check out header is present and showing data |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, buildSpec['program_name']) |
|||
self.assertEqual(subtitle, buildSpec['program_description']) |
|||
|
|||
# switch to the run screen |
|||
app.TopWindow.onStart() |
|||
|
|||
# Should find the expected test in the header |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title,_("running_title")) |
|||
self.assertEqual(subtitle, _('running_msg')) |
|||
|
|||
# Wait for Gooey to swap the header to the final screen |
|||
while app.TopWindow.header._header.GetLabel() == _("running_title"): |
|||
time.sleep(.1) |
|||
|
|||
# verify that we've landed on the success screen |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, _("finished_title")) |
|||
self.assertEqual(subtitle, _('finished_msg')) |
|||
|
|||
# and that output was actually written to the console |
|||
self.assertIn("Success", app.TopWindow.console.textbox.GetValue()) |
|||
time.sleep(1) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
wx.CallAfter(app.TopWindow.Destroy) |
|||
return None |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
@ -0,0 +1,94 @@ |
|||
from gooey import Gooey |
|||
from gooey import GooeyParser |
|||
|
|||
|
|||
@Gooey( |
|||
sidebar_title="Your Custom Title", |
|||
show_sidebar=True, |
|||
dump_build_config=True, |
|||
show_success_modal=False, |
|||
force_stop_is_error=False, |
|||
language='chinese' |
|||
) |
|||
def main(): |
|||
dest_vars = [ |
|||
'textfield', |
|||
'textarea', |
|||
'password', |
|||
'commandfield', |
|||
'dropdown', |
|||
'listboxie', |
|||
'counter', |
|||
'overwrite', |
|||
'mutextwo', |
|||
'filechooser', |
|||
'filesaver', |
|||
'dirchooser', |
|||
'datechooser' |
|||
|
|||
] |
|||
|
|||
parser = get_parser() |
|||
args = parser.parse_args() |
|||
import time |
|||
for i in dest_vars: |
|||
assert getattr(args, i) is not None |
|||
print("Success") |
|||
|
|||
|
|||
|
|||
def get_parser(): |
|||
desc = "Example application to show Gooey's various widgets" |
|||
parser = GooeyParser(description=desc, add_help=False) |
|||
|
|||
parser.add_argument('--textfield', default=2, widget="TextField") |
|||
parser.add_argument('--textarea', default="oneline twoline", widget='Textarea') |
|||
parser.add_argument('--password', default="hunter42", widget='PasswordField') |
|||
parser.add_argument('--commandfield', default="cmdr", widget='CommandField') |
|||
parser.add_argument('--dropdown', choices=["one", "two"], default="two", widget='Dropdown') |
|||
parser.add_argument('--listboxie', |
|||
nargs='+', |
|||
default=['Option three', 'Option four'], |
|||
choices=['Option one', 'Option two', 'Option three', |
|||
'Option four'], |
|||
widget='Listbox', |
|||
gooey_options={ |
|||
'height': 300, |
|||
'validate': '', |
|||
'heading_color': '', |
|||
'text_color': '', |
|||
'hide_heading': True, |
|||
'hide_text': True, |
|||
}) |
|||
parser.add_argument('-c', '--counter', default=3, action='count', widget='Counter') |
|||
parser.add_argument("-o", "--overwrite", action="store_true", default=True, widget='CheckBox') |
|||
parser.add_argument("-bo", "--blockcheckbox", action="store_true", default=True, widget='BlockCheckbox') |
|||
|
|||
### Mutex Group ### |
|||
verbosity = parser.add_mutually_exclusive_group( |
|||
required=True, |
|||
gooey_options={ |
|||
'initial_selection': 1 |
|||
} |
|||
) |
|||
verbosity.add_argument( |
|||
'--mutexone', |
|||
default=True, |
|||
action='store_true', |
|||
help="Show more details") |
|||
|
|||
verbosity.add_argument( |
|||
'--mutextwo', |
|||
default='mut-2', |
|||
widget='TextField') |
|||
|
|||
parser.add_argument("--filechooser", default="fc-value", widget='FileChooser') |
|||
parser.add_argument("--filesaver", default="fs-value", widget='FileSaver') |
|||
parser.add_argument("--dirchooser", default="dc-value", widget='DirChooser') |
|||
parser.add_argument("--datechooser", default="2015-01-01", widget='DateChooser') |
|||
parser.add_argument("--multidirchooser", default="2015-01-01", widget='MultiDirChooser') |
|||
|
|||
return parser |
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -0,0 +1,147 @@ |
|||
""" |
|||
Example program to demonstrate Gooey's presentation of subparsers |
|||
""" |
|||
|
|||
from gooey import Gooey, GooeyParser |
|||
|
|||
@Gooey( |
|||
optional_cols=2, |
|||
program_name="Subparser Demo", |
|||
dump_build_config=True, |
|||
show_success_modal=False) |
|||
def main(): |
|||
dest_vars = [ |
|||
'textfield', |
|||
'textarea', |
|||
'password', |
|||
'commandfield', |
|||
'dropdown', |
|||
'listboxie', |
|||
'counter', |
|||
'overwrite', |
|||
'mutextwo', |
|||
'filechooser', |
|||
'filesaver', |
|||
'dirchooser', |
|||
'datechooser' |
|||
] |
|||
parser = get_parser() |
|||
args = parser.parse_args() |
|||
import time |
|||
time.sleep(.6) |
|||
for i in dest_vars: |
|||
assert getattr(args, i) is not None |
|||
print("Success") |
|||
|
|||
|
|||
def get_parser(): |
|||
parser = GooeyParser() |
|||
subs = parser.add_subparsers(help='commands', dest='command') |
|||
|
|||
parser_one = subs.add_parser('parser1', prog="Parser 1") |
|||
parser_one.add_argument('--textfield', default=2, widget="TextField") |
|||
parser_one.add_argument('--textarea', default="oneline twoline", |
|||
widget='Textarea') |
|||
parser_one.add_argument('--password', default="hunter42", |
|||
widget='PasswordField') |
|||
parser_one.add_argument('--commandfield', default="cmdr", |
|||
widget='CommandField') |
|||
parser_one.add_argument('--dropdown', |
|||
choices=["one", "two"], default="two", |
|||
widget='Dropdown') |
|||
parser_one.add_argument('--listboxie', |
|||
nargs='+', |
|||
default=['Option three', 'Option four'], |
|||
choices=['Option one', 'Option two', 'Option three', |
|||
'Option four'], |
|||
widget='Listbox', |
|||
gooey_options={ |
|||
'height': 300, |
|||
'validate': '', |
|||
'heading_color': '', |
|||
'text_color': '', |
|||
'hide_heading': True, |
|||
'hide_text': True, |
|||
} |
|||
) |
|||
parser_one.add_argument('-c', '--counter', default=3, action='count', |
|||
widget='Counter') |
|||
# |
|||
parser_one.add_argument("-o", "--overwrite", action="store_true", |
|||
default=True, |
|||
widget='CheckBox') |
|||
|
|||
### Mutex Group ### |
|||
verbosity = parser_one.add_mutually_exclusive_group( |
|||
required=True, |
|||
gooey_options={ |
|||
'initial_selection': 1 |
|||
} |
|||
) |
|||
verbosity.add_argument( |
|||
'--mutexone', |
|||
default=True, |
|||
action='store_true', |
|||
help="Show more details") |
|||
|
|||
verbosity.add_argument( |
|||
'--mutextwo', |
|||
default='mut-2', |
|||
widget='TextField') |
|||
|
|||
parser_one.add_argument("--filechooser", default="fc-value", widget='FileChooser') |
|||
parser_one.add_argument("--filesaver", default="fs-value", widget='FileSaver') |
|||
parser_one.add_argument("--dirchooser", default="dc-value", widget='DirChooser') |
|||
parser_one.add_argument("--datechooser", default="2015-01-01", widget='DateChooser') |
|||
|
|||
parser_two = subs.add_parser('parser2', prog="parser 2") |
|||
parser_two.add_argument('--textfield', default=2, widget="TextField") |
|||
parser_two.add_argument('--textarea', default="oneline twoline", widget='Textarea') |
|||
parser_two.add_argument('--password', default="hunter42", widget='PasswordField') |
|||
parser_two.add_argument('--commandfield', default="cmdr", widget='CommandField') |
|||
parser_two.add_argument('--dropdown', choices=["one", "two"], default="two", widget='Dropdown') |
|||
parser_two.add_argument('--listboxie', |
|||
nargs='+', |
|||
default=['Option three', 'Option four'], |
|||
choices=['Option one', 'Option two', 'Option three', |
|||
'Option four'], |
|||
widget='Listbox', |
|||
gooey_options={ |
|||
'height': 300, |
|||
'validate': '', |
|||
'heading_color': '', |
|||
'text_color': '', |
|||
'hide_heading': True, |
|||
'hide_text': True, |
|||
} |
|||
) |
|||
parser_two.add_argument('-c', '--counter', default=3, action='count', widget='Counter') |
|||
parser_two.add_argument("-o", "--overwrite", action="store_true", default=True, widget='CheckBox') |
|||
|
|||
### Mutex Group ### |
|||
verbosity = parser_two.add_mutually_exclusive_group( |
|||
required=True, |
|||
gooey_options={ |
|||
'initial_selection': 1 |
|||
} |
|||
) |
|||
verbosity.add_argument( |
|||
'--mutexone', |
|||
default=True, |
|||
action='store_true', |
|||
help="Show more details") |
|||
|
|||
verbosity.add_argument( |
|||
'--mutextwo', |
|||
default='mut-2', |
|||
widget='TextField') |
|||
|
|||
parser_two.add_argument("--filechooser", default="fc-value", widget='FileChooser') |
|||
parser_two.add_argument("--filesaver", default="fs-value", widget='FileSaver') |
|||
parser_two.add_argument("--dirchooser", default="dc-value", widget='DirChooser') |
|||
parser_two.add_argument("--datechooser", default="2015-01-01", widget='DateChooser') |
|||
|
|||
return parser |
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -0,0 +1,27 @@ |
|||
import sys |
|||
|
|||
from gooey import Gooey |
|||
from gooey import GooeyParser |
|||
from argparse import ArgumentParser |
|||
|
|||
@Gooey( |
|||
progress_regex=r"^progress: (-?\d+)%$", |
|||
disable_progress_bar_animation=True, |
|||
dump_build_config=True, |
|||
show_success_modal=False, |
|||
auto_start=True |
|||
) |
|||
def main(): |
|||
parser = get_parser() |
|||
_ = parser.parse_args(sys.argv[1:]) |
|||
import time |
|||
time.sleep(2) |
|||
print('Success') |
|||
|
|||
|
|||
|
|||
def get_parser(): |
|||
return GooeyParser(prog="example_progress_bar_1") |
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -0,0 +1,645 @@ |
|||
{ |
|||
"language": "chinese", |
|||
"target": "\"C:\\Users\\Chris\\Dropbox\\pretty_gui\\Gooey\\venv3\\Scripts\\python.exe\" -u \"C:/Users/Chris/Dropbox/pretty_gui/Gooey/gooey/tests/integration/programs/all_widgets.py\"", |
|||
"program_name": "all_widgets", |
|||
"program_description": "Example application to show Gooey's various widgets", |
|||
"sidebar_title": "Your Custom Title", |
|||
"default_size": [ |
|||
610, |
|||
530 |
|||
], |
|||
"auto_start": false, |
|||
"show_advanced": true, |
|||
"run_validators": true, |
|||
"encoding": "utf-8", |
|||
"show_stop_warning": true, |
|||
"show_success_modal": false, |
|||
"force_stop_is_error": false, |
|||
"poll_external_updates": false, |
|||
"return_to_config": false, |
|||
"show_restart_button": true, |
|||
"requires_shell": true, |
|||
"menu": [], |
|||
"clear_before_run": false, |
|||
"use_legacy_titles": true, |
|||
"num_required_cols": 2, |
|||
"num_optional_cols": 2, |
|||
"manual_start": false, |
|||
"monospace_display": false, |
|||
"image_dir": "::gooey/default", |
|||
"language_dir": "C:\\Users\\Chris\\Dropbox\\pretty_gui\\Gooey\\gooey\\languages", |
|||
"progress_regex": null, |
|||
"progress_expr": null, |
|||
"hide_progress_msg": false, |
|||
"disable_progress_bar_animation": false, |
|||
"disable_stop_button": false, |
|||
"navigation": "SIDEBAR", |
|||
"show_sidebar": true, |
|||
"tabbed_groups": false, |
|||
"group_by_type": true, |
|||
"body_bg_color": "#f0f0f0", |
|||
"header_bg_color": "#ffffff", |
|||
"header_height": 80, |
|||
"header_show_title": true, |
|||
"header_show_subtitle": true, |
|||
"header_image_center": false, |
|||
"footer_bg_color": "#f0f0f0", |
|||
"sidebar_bg_color": "#f2f2f2", |
|||
"terminal_panel_color": "#F0F0F0", |
|||
"terminal_font_color": "#000000", |
|||
"terminal_font_family": null, |
|||
"terminal_font_weight": null, |
|||
"terminal_font_size": null, |
|||
"richtext_controls": false, |
|||
"error_color": "#ea7878", |
|||
"layout": "standard", |
|||
"widgets": { |
|||
"all_widgets.py": { |
|||
"command": "::gooey/default", |
|||
"name": "all_widgets.py", |
|||
"help": null, |
|||
"description": "", |
|||
"contents": [ |
|||
{ |
|||
"name": "Optional Arguments", |
|||
"items": [ |
|||
{ |
|||
"id": "--textfield", |
|||
"type": "TextField", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "textfield", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--textfield" |
|||
], |
|||
"choices": [], |
|||
"default": 2, |
|||
"dest": "textfield" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--textarea", |
|||
"type": "Textarea", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "textarea", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--textarea" |
|||
], |
|||
"choices": [], |
|||
"default": "oneline twoline", |
|||
"dest": "textarea" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--password", |
|||
"type": "PasswordField", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "password", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--password" |
|||
], |
|||
"choices": [], |
|||
"default": "hunter42", |
|||
"dest": "password" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--commandfield", |
|||
"type": "CommandField", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "commandfield", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--commandfield" |
|||
], |
|||
"choices": [], |
|||
"default": "cmdr", |
|||
"dest": "commandfield" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--dropdown", |
|||
"type": "Dropdown", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "dropdown", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--dropdown" |
|||
], |
|||
"choices": [ |
|||
"one", |
|||
"two" |
|||
], |
|||
"default": "two", |
|||
"dest": "dropdown" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--listboxie", |
|||
"type": "Listbox", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "listboxie", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "+", |
|||
"commands": [ |
|||
"--listboxie" |
|||
], |
|||
"choices": [ |
|||
"Option one", |
|||
"Option two", |
|||
"Option three", |
|||
"Option four" |
|||
], |
|||
"default": [ |
|||
"Option three", |
|||
"Option four" |
|||
], |
|||
"dest": "listboxie" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
}, |
|||
"height": 300, |
|||
"validate": "", |
|||
"heading_color": "", |
|||
"text_color": "", |
|||
"hide_heading": true, |
|||
"hide_text": true |
|||
} |
|||
}, |
|||
{ |
|||
"id": "-c", |
|||
"type": "Counter", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "counter", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"-c", |
|||
"--counter" |
|||
], |
|||
"choices": [ |
|||
"1", |
|||
"2", |
|||
"3", |
|||
"4", |
|||
"5", |
|||
"6", |
|||
"7", |
|||
"8", |
|||
"9", |
|||
"10" |
|||
], |
|||
"default": "3", |
|||
"dest": "counter" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "-o", |
|||
"type": "CheckBox", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "overwrite", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"-o", |
|||
"--overwrite" |
|||
], |
|||
"choices": [], |
|||
"default": true, |
|||
"dest": "overwrite" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "-bo", |
|||
"type": "BlockCheckbox", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "blockcheckbox", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"-bo", |
|||
"--blockcheckbox" |
|||
], |
|||
"choices": [], |
|||
"default": true, |
|||
"dest": "blockcheckbox" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "94c2fd11-1925-4cc8-8634-44ef0ce07986", |
|||
"type": "RadioGroup", |
|||
"cli_type": "optional", |
|||
"group_name": "Choose Option", |
|||
"required": true, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"type": "local", |
|||
"test": "lambda x: True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
}, |
|||
"initial_selection": 1 |
|||
}, |
|||
"data": { |
|||
"commands": [ |
|||
[ |
|||
"--mutexone" |
|||
], |
|||
[ |
|||
"--mutextwo" |
|||
] |
|||
], |
|||
"widgets": [ |
|||
{ |
|||
"id": "--mutexone", |
|||
"type": "CheckBox", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "mutexone", |
|||
"help": "Show more details", |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--mutexone" |
|||
], |
|||
"choices": [], |
|||
"default": true, |
|||
"dest": "mutexone" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--mutextwo", |
|||
"type": "TextField", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "mutextwo", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--mutextwo" |
|||
], |
|||
"choices": [], |
|||
"default": "mut-2", |
|||
"dest": "mutextwo" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
} |
|||
] |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--filechooser", |
|||
"type": "FileChooser", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "filechooser", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--filechooser" |
|||
], |
|||
"choices": [], |
|||
"default": "fc-value", |
|||
"dest": "filechooser" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--filesaver", |
|||
"type": "FileSaver", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "filesaver", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--filesaver" |
|||
], |
|||
"choices": [], |
|||
"default": "fs-value", |
|||
"dest": "filesaver" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--dirchooser", |
|||
"type": "DirChooser", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "dirchooser", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--dirchooser" |
|||
], |
|||
"choices": [], |
|||
"default": "dc-value", |
|||
"dest": "dirchooser" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--datechooser", |
|||
"type": "DateChooser", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "datechooser", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--datechooser" |
|||
], |
|||
"choices": [], |
|||
"default": "2015-01-01", |
|||
"dest": "datechooser" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
}, |
|||
{ |
|||
"id": "--multidirchooser", |
|||
"type": "MultiDirChooser", |
|||
"cli_type": "optional", |
|||
"required": false, |
|||
"data": { |
|||
"display_name": "multidirchooser", |
|||
"help": null, |
|||
"required": false, |
|||
"nargs": "", |
|||
"commands": [ |
|||
"--multidirchooser" |
|||
], |
|||
"choices": [], |
|||
"default": "2015-01-01", |
|||
"dest": "multidirchooser" |
|||
}, |
|||
"options": { |
|||
"error_color": "#ea7878", |
|||
"label_color": "#000000", |
|||
"help_color": "#363636", |
|||
"full_width": false, |
|||
"validator": { |
|||
"test": "True", |
|||
"message": "" |
|||
}, |
|||
"external_validator": { |
|||
"cmd": "" |
|||
} |
|||
} |
|||
} |
|||
], |
|||
"groups": [], |
|||
"description": null, |
|||
"options": { |
|||
"label_color": "#000000", |
|||
"description_color": "#363636", |
|||
"legacy": { |
|||
"required_cols": 2, |
|||
"optional_cols": 2 |
|||
}, |
|||
"columns": 2, |
|||
"padding": 10, |
|||
"show_border": false |
|||
} |
|||
} |
|||
] |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
import time |
|||
|
|||
from gooey import Gooey |
|||
from gooey import GooeyParser |
|||
|
|||
|
|||
@Gooey( |
|||
sidebar_title="Your Custom Title", |
|||
show_sidebar=True, |
|||
show_success_modal=False, |
|||
force_stop_is_error=False, |
|||
) |
|||
def main(): |
|||
parser = get_parser() |
|||
args = parser.parse_args() |
|||
time.sleep(2) |
|||
print("Success") |
|||
|
|||
|
|||
def get_parser(): |
|||
""" |
|||
A simple parser with a single required argument and no default thus |
|||
ensuring that clicking the start button in the UI will throw |
|||
a validation error. |
|||
""" |
|||
desc = "Example application to show Gooey's various widgets" |
|||
parser = GooeyParser(description=desc, add_help=False) |
|||
parser.add_argument('--textfield', widget="TextField", required=True) |
|||
return parser |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
main() |
@ -0,0 +1,46 @@ |
|||
import os |
|||
import time |
|||
from concurrent import futures |
|||
|
|||
from gooey.gui.util.freeze import getResourcePath |
|||
from gooey.python_bindings import config_generator |
|||
from gooey.util.functional import merge |
|||
|
|||
|
|||
def run_integration(module, assertionFunction, **kwargs): |
|||
""" |
|||
Integration test harness. |
|||
|
|||
WXPython is *super* finicky when it comes to integration tests. It needs |
|||
the main Python thread for its app loop, which means we have to integration |
|||
test on a separate thread. The causes further strangeness in how Unittest |
|||
and WXPython interact. In short, each test must be in its own module and |
|||
thus import its own wx instance, and be run in its own "space." |
|||
|
|||
So long as the above is satisfied, then integration tests can run reliably. |
|||
|
|||
""" |
|||
from gooey.gui import application |
|||
options = merge({ |
|||
'image_dir': '::gooey/default', |
|||
'language_dir': getResourcePath('languages'), |
|||
'show_success_modal': False |
|||
}, kwargs) |
|||
module_path = os.path.abspath(module.__file__) |
|||
parser = module.get_parser() |
|||
build_spec = config_generator.create_from_parser(parser, module_path, **options) |
|||
|
|||
time.sleep(2) |
|||
app = application.build_app(build_spec=build_spec) |
|||
executor = futures.ThreadPoolExecutor(max_workers=1) |
|||
# executor runs in parallel and will submit a wx.Destroy request |
|||
# when done making its assertions |
|||
testResult = executor.submit(assertionFunction, app, build_spec) |
|||
# main loop blocks the main thread |
|||
app.MainLoop() |
|||
# .result() blocks as well while we wait for the thread to finish |
|||
# any waiting it may be doing. |
|||
testResult.result() |
|||
del app |
|||
|
|||
|
@ -1,174 +0,0 @@ |
|||
import json |
|||
import sys |
|||
import time |
|||
import unittest |
|||
from concurrent import futures |
|||
from os import path |
|||
|
|||
from gooey.gui import application |
|||
from gooey.gui.lang.i18n import _ |
|||
from gooey.gui.util.freeze import getResourcePath |
|||
from gooey.gui.util.quoting import quote |
|||
|
|||
|
|||
class TestGooeyIntegration(unittest.TestCase): |
|||
""" |
|||
A few quick integration tests that exercise Gooey's various run modes |
|||
|
|||
WX Python needs to control the main thread. So, in order to simulate a user |
|||
running through the system, we have to execute the actual assertions in a |
|||
different thread |
|||
""" |
|||
LOCAL_DIR = path.dirname(__file__) |
|||
|
|||
def performTest(self, configPath, assertionFunction): |
|||
""" |
|||
Primary test harness. |
|||
|
|||
Instantiates the WX App, and spawns the threads |
|||
required to make assertions against it |
|||
""" |
|||
with open(configPath, 'r') as f: |
|||
build_spec = json.loads(f.read()) |
|||
# swaps the absolute path stored by Gooey at write time |
|||
# for a relative one based on our current test location |
|||
target_pyfile = path.split(build_spec['target'].replace('"', ''))[-1] |
|||
file_path = path.join(path.dirname(__file__), target_pyfile) |
|||
run_cmd = '{} -u {}'.format(quote(sys.executable), quote(file_path)) |
|||
build_spec['language_dir'] = getResourcePath('languages') |
|||
build_spec['target'] = run_cmd |
|||
|
|||
app = application.build_app(build_spec=build_spec) |
|||
executor = futures.ThreadPoolExecutor(max_workers=1) |
|||
testResult = executor.submit(assertionFunction, app, build_spec) |
|||
app.MainLoop() |
|||
testResult.result() |
|||
# some extra padding time between starting/stopping the wx App |
|||
app.Destroy() |
|||
time.sleep(1) |
|||
|
|||
|
|||
def test_gooeyNormalRun(self): |
|||
""" Tests the happy path through the default run mode of Gooey """ |
|||
self.performTest(path.join(self.LOCAL_DIR, 'gooey_config__normal.json'), self.gooeySanityTest) |
|||
|
|||
def test_gooeySubparserMode(self): |
|||
""" Tests the happy path through the subparser run mode of Gooey """ |
|||
self.performTest(path.join(self.LOCAL_DIR, 'gooey_config__subparser.json'), self.gooeySanityTest) |
|||
|
|||
def test__gooeyAutoStart(self): |
|||
"""Verifies that issue #201 doesn't regress and auto_start skips the config |
|||
screen and hops right into the client's program""" |
|||
self.performTest(path.join(self.LOCAL_DIR, 'gooey_config__autostart.json'), self.verifyAutoStart) |
|||
|
|||
def test__gooeyValidation(self): |
|||
"""Verifies that custom validation routines supplied via gooey_options prevents |
|||
the user from advancing past the configuration page when they fail""" |
|||
self.performTest(path.join(self.LOCAL_DIR, 'gooey_config__autostart.json'), self.verifyValidators) |
|||
|
|||
|
|||
def verifyValidators(self, app, buildSpec): |
|||
time.sleep(1) |
|||
try: |
|||
app.TopWindow.onStart() |
|||
# we should still be on the configuration page due to a validation fail |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertNotEqual(title, buildSpec['program_name']) |
|||
self.assertNotEqual(subtitle, buildSpec['program_description']) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
app.TopWindow.Destroy() |
|||
return None |
|||
|
|||
def verifyAutoStart(self, app, buildSpec): |
|||
""" |
|||
When the auto_start flag == True Gooey should skip the |
|||
configuration screen |
|||
""" |
|||
time.sleep(1) |
|||
try: |
|||
# Gooey should NOT be showing the name/description headers |
|||
# present on the config page |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertNotEqual(title, buildSpec['program_name']) |
|||
self.assertNotEqual(subtitle, buildSpec['program_description']) |
|||
|
|||
# Gooey should be showing the console messages straight away |
|||
# without manually starting the program |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title,_("running_title")) |
|||
self.assertEqual(subtitle, _('running_msg')) |
|||
|
|||
# Wait for Gooey to swap the header to the final screen |
|||
while app.TopWindow.header._header.GetLabel() == _("running_title"): |
|||
time.sleep(.1) |
|||
|
|||
# verify that we've landed on the success screen |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, _("finished_title")) |
|||
self.assertEqual(subtitle, _('finished_msg')) |
|||
|
|||
|
|||
# and that output was actually written to the console |
|||
self.assertIn("Success", app.TopWindow.console.textbox.GetValue()) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
app.TopWindow.Destroy() |
|||
return None |
|||
|
|||
|
|||
def gooeySanityTest(self, app, buildSpec): |
|||
time.sleep(1) |
|||
try: |
|||
# Check out header is present and showing data |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, buildSpec['program_name']) |
|||
self.assertEqual(subtitle, buildSpec['program_description']) |
|||
|
|||
# switch to the run screen |
|||
app.TopWindow.onStart() |
|||
|
|||
# Should find the expected test in the header |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title,_("running_title")) |
|||
self.assertEqual(subtitle, _('running_msg')) |
|||
|
|||
# Wait for Gooey to swap the header to the final screen |
|||
while app.TopWindow.header._header.GetLabel() == _("running_title"): |
|||
time.sleep(.1) |
|||
|
|||
# verify that we've landed on the success screen |
|||
title = app.TopWindow.header._header.GetLabel() |
|||
subtitle = app.TopWindow.header._subheader.GetLabel() |
|||
self.assertEqual(title, _("finished_title")) |
|||
self.assertEqual(subtitle, _('finished_msg')) |
|||
|
|||
|
|||
# and that output was actually written to the console |
|||
self.assertIn("Success", app.TopWindow.console.textbox.GetValue()) |
|||
except: |
|||
app.TopWindow.Destroy() |
|||
raise |
|||
else: |
|||
app.TopWindow.Destroy() |
|||
return None |
|||
|
|||
|
|||
if __name__ == '__main__': |
|||
unittest.main() |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
Write
Preview
Loading…
Cancel
Save