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.2 KiB

2 years ago
2 years ago
  1. import unittest
  2. from gooey import GooeyParser
  3. from gooey.tests import *
  4. from gooey.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, frame, gapp):
  42. radioGroup = gapp.getActiveConfig().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, frame, gapp):
  73. radioGroup = gapp.getActiveConfig().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()