def test_relevant_suggestions_shown(self): choices = ['alpha1', 'alpha2', 'beta', 'gamma'] cases = [['a', choices[:2]], ['A', choices[:2]], ['AlPh', choices[:2]], ['Alpha1', choices[:1]], ['b', choices[2:3]], ['g', choices[-1:]]] parser = self.make_parser(choices=choices) with instrumentGooey(parser) as (app, gooeyApp): for input, expected in cases: with self.subTest(f'given input {input}, expect: {expected}'): dropdown = gooeyApp.configs[0].reifiedWidgets[0] event = wx.CommandEvent(wx.wxEVT_TEXT, wx.Window.NewControlId()) event.SetString(input) dropdown.widget.GetTextCtrl().ProcessEvent(event) # model and UI agree self.assertTrue(dropdown.model.suggestionsVisible, dropdown.listbox.IsShown()) # model and UI agree self.assertEqual( dropdown.model.suggestions, dropdown.listbox.GetItems(), ) self.assertEqual(dropdown.model.suggestions, expected)
def test_validate_form_without_errors(self): from gooey.tests.dynamics.files import basic params = { 'target': '{} -u {}'.format(sys.executable, basic.__file__), 'use_events': [Events.VALIDATE_FORM], # setting to false because it interferes with the test 'show_success_modal': False } with instrumentGooey(basic.make_parser(), **params) as (app, frame, gapp): gapp.getActiveConfig().widgetsMap['foo'].setValue( '10') # valid int self.assertEqual(gapp.getActiveFormState()[0]['error'], '') gapp.onStart() wx.CallLater(2500, app.ExitMainLoop) app.MainLoop() # no errors blocked the run, so we should have executed and finished. # we're now on the success screen. self.assertEqual(gapp.state['image'], gapp.state['images']['successIcon']) # and indeed no errors were written to the UI self.assertEqual(gapp.getActiveFormState()[0]['error'], '') # and we find the expected output written to the console # rather than some unexpected error self.assertIn('DONE', frame.FindWindowByName("console").getText())
def test_validate_form(self): """ Integration testing the Dynamic Validation features. """ # Because it's a live test, nothing is mocked. This basic.py file # will be called via subprocess as part of the test. As such, we # grab both its path on disk (for use as a target for Gooey) as # well as its parser instance (so that we can bootstrap) from gooey.tests.dynamics.files import basic params = { 'target': '{} -u {}'.format(sys.executable, basic.__file__), 'use_events': [Events.VALIDATE_FORM], } with instrumentGooey(basic.make_parser(), **params) as (app, frame, gapp): # the parser has a single arg of type int. # We purposefully give it invalid input for the sake of the test. gapp.getActiveConfig().widgetsMap['foo'].setValue('not a number') # and make sure we're not somehow starting with an error self.assertEqual(gapp.getActiveFormState()[0]['error'], '') gapp.onStart() # All subprocess calls ultimately pump though wx's event queue # so we have to kick off the mainloop and let it run long enough # to let the subprocess complete and the event queue flush wx.CallLater(2500, app.ExitMainLoop) app.MainLoop() # after the subprocess call is complete, our UI should have # been updated with the data dynamically returned from the # basic.py invocation. self.assertIn('invalid literal', gapp.getActiveFormState()[0]['error'])
def test_input_spawns_popup(self): parser = self.make_parser( choices=['alpha1', 'alpha2', 'beta', 'gamma']) with instrumentGooey(parser) as (app, gooeyApp): dropdown = gooeyApp.configs[0].reifiedWidgets[0] event = wx.CommandEvent(wx.wxEVT_TEXT, wx.Window.NewControlId()) event.SetEventObject(dropdown.widget.GetTextCtrl()) dropdown.widget.GetTextCtrl().ProcessEvent(event) self.assertTrue(dropdown.model.suggestionsVisible, dropdown.listbox.IsShown())
def test_arrow_key_selection_cycling(self): """ Testing that the up/down arrow keys spawn the dropdown and cycle through its options wrapping around as needed. """ Scenario = namedtuple('Scenario', [ 'key', 'expectVisible', 'expectedSelection', 'expectedDisplayValue' ]) choices = ['alpha', 'beta'] # no text entered yet initial = Scenario(None, False, -1, '') scenarios = [ # cycling down [ Scenario(wx.WXK_DOWN, True, -1, ''), Scenario(wx.WXK_DOWN, True, 0, 'alpha'), Scenario(wx.WXK_DOWN, True, 1, 'beta'), # wraps around to top Scenario(wx.WXK_DOWN, True, 0, 'alpha') ], # cycling up [ Scenario(wx.WXK_UP, True, -1, ''), Scenario(wx.WXK_UP, True, 1, 'beta'), Scenario(wx.WXK_UP, True, 0, 'alpha'), # wraps around to top Scenario(wx.WXK_UP, True, 1, 'beta'), ] ] for actions in scenarios: parser = self.make_parser(choices=choices) with instrumentGooey(parser) as (app, gooeyApp): dropdown = gooeyApp.configs[0].reifiedWidgets[0] # sanity check we're starting from our known initial state self.assertEqual(dropdown.model.suggestionsVisible, initial.expectVisible) self.assertEqual(dropdown.model.displayValue, initial.expectedDisplayValue) self.assertEqual(dropdown.model.selectedSuggestion, initial.expectedSelection) for action in actions: self.pressButton(dropdown, action.key) self.assertEqual(dropdown.model.suggestionsVisible, dropdown.listbox.IsShown()) self.assertEqual(dropdown.model.displayValue, action.expectedDisplayValue) self.assertEqual(dropdown.model.selectedSuggestion, action.expectedSelection)
def test_lifecycle_handlers(self): cases = [{ 'input': 'happy path', 'expected_stdout': 'DONE', 'expected_update': 'success' }, { 'input': 'fail', 'expected_stdout': 'EXCEPTION', 'expected_update': 'error' }] from gooey.tests.dynamics.files import lifecycles params = { 'target': '{} -u {}'.format(sys.executable, lifecycles.__file__), 'use_events': [Events.ON_SUCCESS, Events.ON_ERROR], 'show_success_modal': False, 'show_failure_modal': False } for case in cases: with self.subTest(case): with instrumentGooey(lifecycles.make_parser(), **params) as (app, frame, gapp): gapp.getActiveConfig().widgetsMap['foo'].setValue( case['input']) gapp.onStart() # give everything a chance to run wx.CallLater(2000, app.ExitMainLoop) app.MainLoop() # `lifecycle.py` is set up to raise an exception for certain inputs # so we check that we find our expected stdout here console = frame.FindWindowByName("console") self.assertIn(case['expected_stdout'], console.getText()) # Now, based on what happened during the run (success/exception) our # respective lifecycle handler should have been called. These are # configured to update the form field in the UI with a relevant value. # Thus we we're checking here to see that out input has changed, and now # matches the value we expect from the handler textfield = gapp.getActiveFormState()[0] print(case['expected_update'], textfield['value']) self.assertEqual(case['expected_update'], textfield['value'])