You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
6.8 KiB

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