psychopy 2024.1.1__py3-none-any.whl → 2024.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of psychopy might be problematic. Click here for more details.

Files changed (96) hide show
  1. psychopy/__init__.py +2 -2
  2. psychopy/alerts/_alerts.py +6 -2
  3. psychopy/alerts/alertsCatalogue/alertmsg.py +15 -0
  4. psychopy/app/builder/dialogs/paramCtrls.py +4 -2
  5. psychopy/app/builder/localizedStrings.py +16 -4
  6. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  7. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  8. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  9. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  10. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  11. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  12. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  13. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  14. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  15. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  16. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  17. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  18. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  19. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  20. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  21. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  22. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3548 -5422
  23. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  24. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  25. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  26. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  27. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  28. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  29. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  30. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  31. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  32. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  33. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  34. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  35. psychopy/app/plugin_manager/plugins.py +1 -1
  36. psychopy/app/preferencesDlg.py +2 -1
  37. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +552 -550
  38. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +572 -570
  39. psychopy/demos/coder/timing/timeByFrames.py +7 -1
  40. psychopy/experiment/components/_base.py +122 -0
  41. psychopy/experiment/components/aperture/__init__.py +6 -2
  42. psychopy/experiment/components/brush/__init__.py +3 -1
  43. psychopy/experiment/components/button/__init__.py +6 -2
  44. psychopy/experiment/components/buttonBox/__init__.py +2 -1
  45. psychopy/experiment/components/camera/__init__.py +13 -0
  46. psychopy/experiment/components/code/__init__.py +34 -1
  47. psychopy/experiment/components/form/formItems.xltx +0 -0
  48. psychopy/experiment/components/mouse/__init__.py +12 -0
  49. psychopy/experiment/components/polygon/__init__.py +14 -3
  50. psychopy/experiment/components/settings/__init__.py +4 -1
  51. psychopy/experiment/components/sound/__init__.py +1 -1
  52. psychopy/experiment/components/text/__init__.py +1 -1
  53. psychopy/experiment/params.py +17 -0
  54. psychopy/experiment/routines/_base.py +122 -0
  55. psychopy/experiment/routines/counterbalance/__init__.py +1 -1
  56. psychopy/hardware/button.py +4 -3
  57. psychopy/hardware/camera/__init__.py +6 -0
  58. psychopy/hardware/keyboard.py +8 -3
  59. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +1 -1
  60. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +1 -1
  61. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/calibration.py +1 -1
  62. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +1 -1
  63. psychopy/localization/generateTranslationTemplate.py +45 -19
  64. psychopy/localization/messages.pot +5049 -3418
  65. psychopy/preferences/Darwin.spec +2 -0
  66. psychopy/preferences/FreeBSD.spec +2 -0
  67. psychopy/preferences/Linux.spec +2 -0
  68. psychopy/preferences/Windows.spec +2 -0
  69. psychopy/preferences/baseNoArch.spec +2 -0
  70. psychopy/preferences/generateHints.py +2 -1
  71. psychopy/preferences/hints.py +118 -97
  72. psychopy/tests/test_experiment/test_components/__init__.py +1 -1
  73. psychopy/tests/test_experiment/test_components/{test_ButtonBox.py → test_ButtonBoxComponent.py} +9 -27
  74. psychopy/tests/test_experiment/test_components/{test_Code.py → test_CodeComponent.py} +8 -20
  75. psychopy/tests/test_experiment/test_components/test_GratingComponent.py +7 -0
  76. psychopy/tests/test_experiment/test_components/test_ImageComponent.py +8 -0
  77. psychopy/tests/test_experiment/test_components/{test_Mouse.py → test_MouseComponent.py} +44 -57
  78. psychopy/tests/test_experiment/test_components/{test_Polygon.py → test_PolygonComponent.py} +9 -25
  79. psychopy/tests/test_experiment/test_components/{test_ResourceManager.py → test_ResourceManagerComponent.py} +3 -13
  80. psychopy/tests/test_experiment/test_components/{test_Settings.py → test_SettingsComponent.py} +1 -3
  81. psychopy/tests/test_experiment/test_components/{test_Static.py → test_StaticComponent.py} +3 -12
  82. psychopy/tests/test_experiment/test_components/test_all_components.py +8 -66
  83. psychopy/tests/test_experiment/test_components/test_base_components.py +212 -125
  84. psychopy/tools/fontmanager.py +1 -1
  85. psychopy/tools/versionchooser.py +1 -1
  86. psychopy/visual/noise.py +9 -0
  87. psychopy/visual/radial.py +8 -0
  88. psychopy/visual/secondorder.py +9 -0
  89. psychopy/visual/textbox2/textbox2.py +19 -21
  90. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/METADATA +1 -1
  91. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/RECORD +95 -66
  92. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/WHEEL +1 -1
  93. psychopy/tests/test_experiment/test_components/test_Image.py +0 -24
  94. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/entry_points.txt +0 -0
  95. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/licenses/AUTHORS.md +0 -0
  96. {psychopy-2024.1.1.dist-info → psychopy-2024.1.3.dist-info}/licenses/LICENSE +0 -0
@@ -1,65 +1,52 @@
1
1
  from pathlib import Path
2
2
 
3
- from . import _TestDisabledMixin, _TestBaseComponentsMixin
4
- from psychopy.experiment import Experiment
3
+ from . import BaseComponentTests
5
4
  from psychopy.experiment.loops import TrialHandler
6
- from psychopy.experiment.routines import Routine
7
5
  from psychopy.experiment.components.mouse import MouseComponent
8
6
  from psychopy.experiment.components.polygon import PolygonComponent
9
7
  from psychopy.tests.utils import TESTS_DATA_PATH
10
8
  from psychopy.hardware.mouse import Mouse
11
9
 
12
10
 
13
- class TestMouseComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
11
+ class TestMouseComponent(BaseComponentTests):
14
12
  """
15
13
  Test that Mouse coponents have the correct params and write as expected.
16
14
  """
15
+ comp = MouseComponent
17
16
  libraryClass = Mouse
18
17
 
19
- def setup_method(self):
20
- # Make blank experiment
21
- self.exp = Experiment()
22
- # Make blank routine
23
- self.routine = Routine(name="testRoutine", exp=self.exp)
24
- self.exp.addRoutine("testRoutine", self.routine)
25
- self.exp.flow.addRoutine(self.routine, 0)
26
- # Add loop around routine
27
- self.loop = TrialHandler(exp=self.exp, name="testLoop")
28
- self.exp.flow.addLoop(self.loop, 0, -1)
29
- # Make Mouse component
30
- self.comp = MouseComponent(exp=self.exp, parentName="testRoutine", name="testMouse")
31
- self.routine.addComponent(self.comp)
32
- # Make a rect for when we need something to click on
33
- self.target = PolygonComponent(exp=self.exp, parentName="testRoutine", name="testPolygon")
34
- self.routine.addComponent(self.target)
35
-
36
18
  def test_click_save_end_clickable_cases(self):
37
19
  """
38
20
  Test all combinations of options for what to save, what can be clicked on & what kind of clicks to end the
39
21
  routine on.
40
22
  """
23
+ # make minimal experiment just for this test
24
+ comp, rt, exp = self.make_minimal_experiment()
25
+ # make a rect for when we need something to click on
26
+ target = PolygonComponent(exp=exp, parentName=rt.name, name="testPolygon")
27
+
41
28
  saveMouseStateCases = [
42
29
  {'val': "final",
43
- 'want': ["thisExp.addData('testMouse.x', x)"], # should contain code for adding final value of x
44
- 'avoid': ["testMouse.x.append(x)"]}, # should not contain code to update testMouse.x in frame loop
30
+ 'want': [f"thisExp.addData('{comp.name}.x', x)"], # should contain code for adding final value of x
31
+ 'avoid': [f"{comp.name}.x.append(x)"]}, # should not contain code to update testMouse.x in frame loop
45
32
  {'val': "on click",
46
- 'want': ["thisExp.addData('testMouse.x', testMouse.x)", # should add testMouse.x at the end
47
- "testMouse.x.append(x)"], # should contain code to update testMouse.x in frame loop
48
- 'avoid': ["thisExp.addData('testMouse.x', x)"]}, # should not add final value of x
33
+ 'want': [f"thisExp.addData('{comp.name}.x', {comp.name}.x)", # should add testMouse.x at the end
34
+ f"{comp.name}.x.append(x)"], # should contain code to update testMouse.x in frame loop
35
+ 'avoid': [f"thisExp.addData('{comp.name}.x', x)"]}, # should not add final value of x
49
36
  {'val': "on valid click",
50
- 'want': ["thisExp.addData('testMouse.x', testMouse.x)", # should add testMouse.x at the end
51
- "testMouse.x.append(x)", # should contain code to update testMouse.x in frame loop
37
+ 'want': [f"thisExp.addData('{comp.name}.x', {comp.name}.x)", # should add testMouse.x at the end
38
+ f"{comp.name}.x.append(x)", # should contain code to update testMouse.x in frame loop
52
39
  "if gotValidClick:"], # should check for valid clicks
53
- 'avoid': ["thisExp.addData('testMouse.x', x)"]}, # should not add final value of x
40
+ 'avoid': [f"thisExp.addData('{comp.name}.x', x)"]}, # should not add final value of x
54
41
  {'val': "every frame",
55
- 'want': ["thisExp.addData('testMouse.x', testMouse.x)", # should add testMouse.x at the end
56
- "testMouse.x.append(x)"], # should contain code to update testMouse.x in frame loop
57
- 'avoid': ["thisExp.addData('testMouse.x', x)"]}, # should not add final value of x
42
+ 'want': [f"thisExp.addData('{comp.name}.x', {comp.name}.x)", # should add testMouse.x at the end
43
+ f"{comp.name}.x.append(x)"], # should contain code to update testMouse.x in frame loop
44
+ 'avoid': [f"thisExp.addData('{comp.name}.x', x)"]}, # should not add final value of x
58
45
  {'val': "never",
59
46
  'want': [],
60
- 'avoid': ["thisExp.addData('testMouse.x', testMouse.x)", # should not add testMouse.x at the end
61
- "testMouse.x.append(x)", # should not contain code to update testMouse.x in frame loop
62
- "thisExp.addData('testMouse.x', x)"]}, # should not add final value of x]},
47
+ 'avoid': [f"thisExp.addData('{comp.name}.x', {comp.name}.x)", # should not add testMouse.x at the end
48
+ f"{comp.name}.x.append(x)", # should not contain code to update testMouse.x in frame loop
49
+ f"thisExp.addData('{comp.name}.x', x)"]}, # should not add final value of x]},
63
50
  ]
64
51
  forceEndRoutineOnPressCases = [
65
52
  {'val': "never",
@@ -85,54 +72,54 @@ class TestMouseComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
85
72
  # Iterate through saveMouseState cases
86
73
  for SMScase in saveMouseStateCases:
87
74
  # Set saveMouseState
88
- self.comp.params['saveMouseState'].val = SMScase['val']
75
+ comp.params['saveMouseState'].val = SMScase['val']
89
76
  for FEROPcase in forceEndRoutineOnPressCases:
90
77
  # Set forceEndRoutineOnPress
91
- self.comp.params['forceEndRoutineOnPress'].val = FEROPcase['val']
78
+ comp.params['forceEndRoutineOnPress'].val = FEROPcase['val']
92
79
  for Ccase in clickableCases:
93
80
  # Set clickable
94
- self.comp.params['clickable'].val = Ccase['val']
81
+ comp.params['clickable'].val = Ccase['val']
95
82
 
96
83
  # Compile script
97
- script = self.exp.writeScript(target="PsychoPy")
84
+ script = exp.writeScript(target="PsychoPy")
98
85
  try:
99
86
  # Look for wanted phrases
100
87
  for phrase in SMScase['want']:
101
88
  assert phrase in script, (
102
- f"{phrase} not found in script when saveMouseState={self.comp.params['saveMouseState']}, "
103
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
104
- f"clickable={self.comp.params['clickable']}"
89
+ f"{phrase} not found in script when saveMouseState={comp.params['saveMouseState']}, "
90
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
91
+ f"clickable={comp.params['clickable']}"
105
92
  )
106
93
  for phrase in FEROPcase['want']:
107
94
  assert phrase in script, (
108
- f"{phrase} not found in script when saveMouseState={self.comp.params['saveMouseState']}, "
109
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
110
- f"clickable={self.comp.params['clickable']}"
95
+ f"{phrase} not found in script when saveMouseState={comp.params['saveMouseState']}, "
96
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
97
+ f"clickable={comp.params['clickable']}"
111
98
  )
112
99
  for phrase in Ccase['want']:
113
100
  assert phrase in script, (
114
- f"{phrase} not found in script when saveMouseState={self.comp.params['saveMouseState']}, "
115
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
116
- f"clickable={self.comp.params['clickable']}"
101
+ f"{phrase} not found in script when saveMouseState={comp.params['saveMouseState']}, "
102
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
103
+ f"clickable={comp.params['clickable']}"
117
104
  )
118
105
  # Check there's no avoid phrases
119
106
  for phrase in SMScase['avoid']:
120
107
  assert phrase not in script, (
121
- f"{phrase} found in script when saveMouseState={self.comp.params['saveMouseState']}, "
122
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
123
- f"clickable={self.comp.params['clickable']}"
108
+ f"{phrase} found in script when saveMouseState={comp.params['saveMouseState']}, "
109
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
110
+ f"clickable={comp.params['clickable']}"
124
111
  )
125
112
  for phrase in FEROPcase['avoid']:
126
113
  assert phrase not in script, (
127
- f"{phrase} found in script when saveMouseState={self.comp.params['saveMouseState']}, "
128
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
129
- f"clickable={self.comp.params['clickable']}"
114
+ f"{phrase} found in script when saveMouseState={comp.params['saveMouseState']}, "
115
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
116
+ f"clickable={comp.params['clickable']}"
130
117
  )
131
118
  for phrase in Ccase['avoid']:
132
119
  assert phrase not in script, (
133
- f"{phrase} found in script when saveMouseState={self.comp.params['saveMouseState']}, "
134
- f"forceEndRoutineOnPress={self.comp.params['forceEndRoutineOnPress']} and "
135
- f"clickable={self.comp.params['clickable']}"
120
+ f"{phrase} found in script when saveMouseState={comp.params['saveMouseState']}, "
121
+ f"forceEndRoutineOnPress={comp.params['forceEndRoutineOnPress']} and "
122
+ f"clickable={comp.params['clickable']}"
136
123
  )
137
124
  except AssertionError as err:
138
125
  # If any assertion fails, save script to view
@@ -1,37 +1,21 @@
1
- from pathlib import Path
2
-
3
- from . import _TestDisabledMixin, _TestBaseComponentsMixin
4
- from psychopy.experiment import Experiment
5
- from psychopy.experiment.loops import TrialHandler
6
- from psychopy.experiment.routines import Routine
1
+ from psychopy.tests.test_experiment.test_components.test_base_components import BaseComponentTests, _TestLibraryClassMixin
7
2
  from psychopy.experiment.components.polygon import PolygonComponent
8
3
  from psychopy.visual.polygon import Polygon
9
4
 
10
5
 
11
- class TestPolygonComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
6
+ class TestPolygonComponent(BaseComponentTests, _TestLibraryClassMixin):
12
7
  """
13
8
  Test that Polygon coponents have the correct params and write as expected.
14
9
  """
10
+ comp = PolygonComponent
15
11
  libraryClass = Polygon
16
12
 
17
- def setup_method(self):
18
- # Make blank experiment
19
- self.exp = Experiment()
20
- # Make blank routine
21
- self.routine = Routine(name="testRoutine", exp=self.exp)
22
- self.exp.addRoutine("testRoutine", self.routine)
23
- self.exp.flow.addRoutine(self.routine, 0)
24
- # Add loop around routine
25
- self.loop = TrialHandler(exp=self.exp, name="testLoop")
26
- self.exp.flow.addLoop(self.loop, 0, -1)
27
- # Make a rect for when we need something to click on
28
- self.comp = PolygonComponent(exp=self.exp, parentName="testRoutine", name="testPolygon")
29
- self.routine.addComponent(self.comp)
30
-
31
13
  def test_vertices_usage(self):
32
14
  """
33
15
  Test that vertices values are used only under the correct conditions
34
16
  """
17
+ # make minimal experiment just for this test
18
+ comp, rt, exp = self.make_minimal_experiment()
35
19
  # Define values to look for and avoid in code according to value of shape
36
20
  cases = [
37
21
  # Shape is a line
@@ -61,14 +45,14 @@ class TestPolygonComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
61
45
  'avoid': ["___nVertices___"]},
62
46
  ]
63
47
  # Setup component with markers for nVertices and vertices
64
- self.comp.params['nVertices'].val = "___nVertices___"
65
- self.comp.params['vertices'].val = "___vertices___"
48
+ comp.params['nVertices'].val = "___nVertices___"
49
+ comp.params['vertices'].val = "___vertices___"
66
50
  # Test each case
67
51
  for case in cases:
68
52
  # Set shape
69
- self.comp.params['shape'].val = case['val']
53
+ comp.params['shape'].val = case['val']
70
54
  # Write experiment
71
- pyScript = self.exp.writeScript(target="PsychoPy")
55
+ pyScript = exp.writeScript(target="PsychoPy")
72
56
  # Look for sought values in experiment script
73
57
  for seekVal in case['seek']:
74
58
  assert seekVal in pyScript, (
@@ -1,23 +1,13 @@
1
1
  from pathlib import Path
2
2
 
3
- from . import _TestBaseComponentsMixin, _TestDisabledMixin
4
- from .test_base_components import _find_global_resource_in_js_experiment
3
+ from psychopy.tests.test_experiment.test_components.test_base_components import BaseComponentTests, _find_global_resource_in_js_experiment
5
4
  from psychopy.experiment.components.resourceManager import ResourceManagerComponent
6
5
  from psychopy import experiment
7
6
  from ...utils import TESTS_DATA_PATH
8
7
 
9
8
 
10
- class TestResourceManagerComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
11
- def setup_method(self):
12
- # Make blank experiment
13
- self.exp = experiment.Experiment()
14
- # Make blank routine
15
- self.routine = experiment.routines.Routine(name="testRoutine", exp=self.exp)
16
- self.exp.addRoutine("testRoutine", self.routine)
17
- self.exp.flow.addRoutine(self.routine, 0)
18
- # Make Resource Manager component
19
- self.comp = ResourceManagerComponent(exp=self.exp, parentName="testRoutine", name="testResourceManager")
20
- self.routine.addComponent(self.comp)
9
+ class TestResourceManagerComponent(BaseComponentTests):
10
+ comp = ResourceManagerComponent
21
11
 
22
12
  def test_handled_resources_removed(self):
23
13
  """
@@ -1,13 +1,11 @@
1
1
  from pathlib import Path
2
2
 
3
- from . import _TestBaseComponentsMixin, _TestDisabledMixin
4
3
  from .test_base_components import _find_global_resource_in_js_experiment
5
- from psychopy.experiment.components.settings import SettingsComponent
6
4
  from psychopy import experiment
7
5
  from ...utils import TESTS_DATA_PATH
8
6
 
9
7
 
10
- class TestSettingsComponent(_TestBaseComponentsMixin):
8
+ class TestSettingsComponent:
11
9
  def test_unhandled_resources_js(self):
12
10
  """
13
11
  Check that resources not otherwise handled are present at the start of the experiment
@@ -1,23 +1,14 @@
1
1
  from pathlib import Path
2
2
 
3
- from . import _TestBaseComponentsMixin, _TestDisabledMixin
3
+ from . import BaseComponentTests
4
4
  from .test_base_components import _find_global_resource_in_js_experiment
5
5
  from psychopy.experiment.components.static import StaticComponent
6
6
  from psychopy import experiment, data
7
7
  from ...utils import TESTS_DATA_PATH
8
8
 
9
9
 
10
- class TestStaticComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
11
- def setup_method(self):
12
- # Make blank experiment
13
- self.exp = experiment.Experiment()
14
- # Make blank routine
15
- self.routine = experiment.routines.Routine(name="testRoutine", exp=self.exp)
16
- self.exp.addRoutine("testRoutine", self.routine)
17
- self.exp.flow.addRoutine(self.routine, 0)
18
- # Make Static component
19
- self.comp = StaticComponent(exp=self.exp, parentName="testRoutine", name="testStatic")
20
- self.routine.addComponent(self.comp)
10
+ class TestStaticComponent(BaseComponentTests):
11
+ comp = StaticComponent
21
12
 
22
13
  def test_handled_resources_removed(self):
23
14
  """
@@ -1,10 +1,10 @@
1
1
  from psychopy.experiment.exports import IndentingBuffer
2
- from . import _TestBaseComponentsMixin, _TestDisabledMixin
2
+ from . import BaseComponentTests
3
3
  from psychopy import experiment
4
4
  import inspect
5
5
 
6
6
 
7
- class _Generic(_TestBaseComponentsMixin, _TestDisabledMixin):
7
+ class _Generic(BaseComponentTests):
8
8
  def __init__(self, compClass):
9
9
  self.exp = experiment.Experiment()
10
10
  self.rt = experiment.routines.Routine(exp=self.exp, name="testRoutine")
@@ -18,14 +18,12 @@ def test_all_components():
18
18
  for compName, compClass in experiment.getAllComponents().items():
19
19
  if compName == "SettingsComponent":
20
20
  continue
21
- # Make a generic testing object for this component
22
- tester = _Generic(compClass)
23
- # Run each method from _TestBaseComponentsMixin on tester
24
- for attr, meth in _TestBaseComponentsMixin.__dict__.items():
25
- if inspect.ismethod(meth):
26
- meth(tester)
27
- # Run each method from _TestBaseComponentsMixin on tester
28
- for attr, meth in _TestDisabledMixin.__dict__.items():
21
+ # make a generic testing object for this component
22
+ tester = BaseComponentTests()
23
+ # make sure it has a comp class assigned
24
+ tester.comp = compClass
25
+ # Run each method from BaseComponentTests on tester
26
+ for attr, meth in BaseComponentTests.__dict__.items():
29
27
  if inspect.ismethod(meth):
30
28
  meth(tester)
31
29
 
@@ -104,59 +102,3 @@ def test_visual_set_autodraw():
104
102
  f"{compName} does not set autoDraw in its Each Frame code. If this is acceptable, add the component name "
105
103
  f"to `skipComponents`."
106
104
  )
107
-
108
- def test_indentation_consistency():
109
- """
110
- No component should exit any of its write methods at a different indent level as it entered, as this would break
111
- subsequent components / routines.
112
- """
113
- for compName, compClass in experiment.getAllComponents().items():
114
- if compName == "SettingsComponent":
115
- continue
116
- # Make a generic testing object for this component
117
- tester = _Generic(compClass)
118
- # Skip if component doesn't have a start/stop time
119
- if "startVal" not in tester.comp.params or "stopVal" not in tester.comp.params:
120
- continue
121
- # Check that each write method exits at the same indent level as it entered
122
- buff = IndentingBuffer(target="PsychoPy")
123
- msg = "Writing {} code for {} changes indent level by {} when start is `{}` and stop is `{}`."
124
- # Setup flow for writing
125
- tester.exp.flow.writeStartCode(buff)
126
- # Try combinations of start/stop being set/unset
127
- cases = [
128
- {"startVal": "0", "stopVal": "1"},
129
- {"startVal": "", "stopVal": "1"},
130
- {"startVal": "0", "stopVal": ""},
131
- {"startVal": "", "stopVal": ""},
132
- ]
133
- for case in cases:
134
- tester.comp.params["startType"].val = "time (s)"
135
- tester.comp.params["stopType"].val = "time (s)"
136
- for param, val in case.items():
137
- tester.comp.params[param].val = val
138
- # Init
139
- tester.comp.writeInitCode(buff)
140
- assert buff.indentLevel == 0, msg.format(
141
- "init", type(tester.comp).__name__, buff.indentLevel, case['startVal'], case['stopVal']
142
- )
143
- # Start routine
144
- tester.comp.writeRoutineStartCode(buff)
145
- assert buff.indentLevel == 0, msg.format(
146
- "routine start", type(tester.comp).__name__, buff.indentLevel, case['startVal'], case['stopVal']
147
- )
148
- # Each frame
149
- tester.comp.writeFrameCode(buff)
150
- assert buff.indentLevel == 0, msg.format(
151
- "each frame", type(tester.comp).__name__, buff.indentLevel, case['startVal'], case['stopVal']
152
- )
153
- # End routine
154
- tester.comp.writeRoutineEndCode(buff)
155
- assert buff.indentLevel == 0, msg.format(
156
- "routine end", type(tester.comp).__name__, buff.indentLevel, case['startVal'], case['stopVal']
157
- )
158
- # End experiment
159
- tester.comp.writeExperimentEndCode(buff)
160
- assert buff.indentLevel == 0, msg.format(
161
- "experiment end", type(tester.comp).__name__, buff.indentLevel, case['startVal'], case['stopVal']
162
- )