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.

188 lines
7.1 KiB

  1. import unittest
  2. import wx
  3. from gooey import GooeyParser
  4. from tests.harness import instrumentGooey
  5. class TestRadioGroupBehavior(unittest.TestCase):
  6. def mutext_group(self, options):
  7. """
  8. Basic radio group consisting of two options.
  9. """
  10. parser = GooeyParser()
  11. group = parser.add_mutually_exclusive_group(**options)
  12. group.add_argument("-b", type=str)
  13. group.add_argument("-d", type=str, widget="DateChooser")
  14. return parser
  15. def test_initial_selection_options(self):
  16. """
  17. Ensure that the initial_selection GooeyOption behaves as expected.
  18. """
  19. # each pair in the below datastructure represents input/output
  20. # First position: kwargs which will be supplied to the parser
  21. # Second position: expected indices which buttons/widgets should be enabled/disabled
  22. testCases = [
  23. [{'required': True, 'gooey_options': {}},
  24. {'selected': None, 'enabled': [], 'disabled': [0, 1]}],
  25. # Issue #517 - initial section with required=True was not enabling
  26. # the inner widget
  27. [{'required': True, 'gooey_options': {"initial_selection": 0}},
  28. {'selected': 0, 'enabled': [0], 'disabled': [1]}],
  29. [{'required': True, 'gooey_options': {"initial_selection": 1}},
  30. {'selected': 1, 'enabled': [1], 'disabled': [0]}],
  31. [{'required': False, 'gooey_options': {}},
  32. {'selected': None, 'enabled': [], 'disabled': [0, 1]}],
  33. [{'required': False, 'gooey_options': {"initial_selection": 0}},
  34. {'selected': 0, 'enabled': [0], 'disabled': [1]}],
  35. [{'required': False, 'gooey_options': {"initial_selection": 1}},
  36. {'selected': 1, 'enabled': [1], 'disabled': [0]}],
  37. ]
  38. for options, expected in testCases:
  39. parser = self.mutext_group(options)
  40. with self.subTest(options):
  41. with instrumentGooey(parser) as (app, gooeyApp):
  42. radioGroup = gooeyApp.configs[0].reifiedWidgets[0]
  43. # verify that the checkboxes themselves are correct
  44. if expected['selected'] is not None:
  45. self.assertEqual(
  46. radioGroup.selected,
  47. radioGroup.radioButtons[expected['selected']])
  48. else:
  49. self.assertEqual(radioGroup.selected, None)
  50. # verify the widgets contained in the radio group
  51. # are in the correct state
  52. for enabled in expected['enabled']:
  53. # The widget contained within the group should be enabled
  54. self.assertTrue(radioGroup.widgets[enabled].IsEnabled())
  55. # make sure all widgets other than the selected
  56. # are disabled
  57. for enabled in expected['disabled']:
  58. self.assertFalse(radioGroup.widgets[enabled].IsEnabled())
  59. def test_optional_radiogroup_click_behavior(self):
  60. """
  61. Testing that select/deselect behaves as expected
  62. """
  63. testcases = [
  64. self.click_scenarios_optional_widget(),
  65. self.click_scenarios_required_widget(),
  66. self.click_scenarios_initial_selection()
  67. ]
  68. for testcase in testcases:
  69. with self.subTest(testcase['name']):
  70. # wire up the parse with our test case options
  71. parser = self.mutext_group(testcase['input'])
  72. with instrumentGooey(parser) as (app, gooeyApp):
  73. radioGroup = gooeyApp.configs[0].reifiedWidgets[0]
  74. for scenario in testcase['scenario']:
  75. targetButton = scenario['clickButton']
  76. event = wx.CommandEvent(wx.wxEVT_LEFT_DOWN, wx.Window.NewControlId())
  77. event.SetEventObject(radioGroup.radioButtons[targetButton])
  78. radioGroup.radioButtons[targetButton].ProcessEvent(event)
  79. expectedEnabled, expectedDisabled = scenario['postState']
  80. for index in expectedEnabled:
  81. self.assertEqual(radioGroup.selected, radioGroup.radioButtons[index])
  82. self.assertTrue(radioGroup.widgets[index].IsEnabled())
  83. for index in expectedDisabled:
  84. self.assertNotEqual(radioGroup.selected, radioGroup.radioButtons[index])
  85. self.assertFalse(radioGroup.widgets[index].IsEnabled())
  86. def click_scenarios_optional_widget(self):
  87. return {
  88. 'name': 'click_scenarios_optional_widget',
  89. 'input': {'required': False},
  90. 'scenario': [
  91. # clicking enabled the button
  92. {'clickButton': 0,
  93. 'postState': [[0], [1]]},
  94. # clicking again disables the button (*when not required*)
  95. {'clickButton': 0,
  96. 'postState': [[], [0, 1]]},
  97. # clicking group 2 enabled it
  98. {'clickButton': 1,
  99. 'postState': [[1], [0]]},
  100. # and similarly clicking group 2 again disables it
  101. {'clickButton': 1,
  102. 'postState': [[], [0, 1]]},
  103. # enable second group
  104. {'clickButton': 1,
  105. 'postState': [[1], [0]]},
  106. # can switch to group one
  107. {'clickButton': 0,
  108. 'postState': [[0], [1]]},
  109. ]
  110. }
  111. def click_scenarios_required_widget(self):
  112. return {
  113. 'name': 'click_scenarios_required_widget',
  114. 'input': {'required': True},
  115. 'scenario': [
  116. # clicking enables the button
  117. {'clickButton': 0,
  118. 'postState': [[0], [1]]},
  119. # unlike the the optional case, this
  120. # has no effect. You cannot _not_ select something
  121. # when it is required.
  122. {'clickButton': 0,
  123. 'postState': [[0], [1]]},
  124. # we can select a different button
  125. {'clickButton': 1,
  126. 'postState': [[1], [0]]},
  127. # again, if we click it again, we cannot deselect it
  128. {'clickButton': 1,
  129. 'postState': [[1], [0]]},
  130. # we can click back to the other group
  131. {'clickButton': 0,
  132. 'postState': [[0], [1]]},
  133. ]}
  134. def click_scenarios_initial_selection(self):
  135. return {
  136. 'name': 'click_scenarios_initial_selection',
  137. 'input': {'required': False, 'gooey_options': {'initial_selection': 0}},
  138. 'scenario': [
  139. # we start already selected via GooeyOptions. As such,
  140. # clicking on the radiobutton should deselect it
  141. {'clickButton': 0,
  142. 'postState': [[], [0, 1]]},
  143. # clicking again reselected it
  144. {'clickButton': 0,
  145. 'postState': [[0], [1]]},
  146. ]}
  147. if __name__ == '__main__':
  148. unittest.main()