psychopy 2024.1.2__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.
- psychopy/__init__.py +2 -2
- psychopy/experiment/components/mouse/__init__.py +12 -0
- psychopy/experiment/routines/counterbalance/__init__.py +1 -1
- psychopy/hardware/keyboard.py +1 -1
- psychopy/tests/test_experiment/test_components/__init__.py +1 -1
- psychopy/tests/test_experiment/test_components/{test_ButtonBox.py → test_ButtonBoxComponent.py} +9 -27
- psychopy/tests/test_experiment/test_components/{test_Code.py → test_CodeComponent.py} +8 -20
- psychopy/tests/test_experiment/test_components/test_GratingComponent.py +7 -0
- psychopy/tests/test_experiment/test_components/test_ImageComponent.py +8 -0
- psychopy/tests/test_experiment/test_components/{test_Mouse.py → test_MouseComponent.py} +44 -57
- psychopy/tests/test_experiment/test_components/{test_Polygon.py → test_PolygonComponent.py} +9 -25
- psychopy/tests/test_experiment/test_components/{test_ResourceManager.py → test_ResourceManagerComponent.py} +3 -13
- psychopy/tests/test_experiment/test_components/{test_Settings.py → test_SettingsComponent.py} +1 -3
- psychopy/tests/test_experiment/test_components/{test_Static.py → test_StaticComponent.py} +3 -12
- psychopy/tests/test_experiment/test_components/test_all_components.py +8 -66
- psychopy/tests/test_experiment/test_components/test_base_components.py +212 -125
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/METADATA +2 -2
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/RECORD +22 -21
- psychopy/tests/test_experiment/test_components/test_Image.py +0 -24
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/WHEEL +0 -0
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.2.dist-info → psychopy-2024.1.3.dist-info}/licenses/LICENSE +0 -0
psychopy/__init__.py
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
import os
|
|
13
13
|
import sys
|
|
14
14
|
|
|
15
|
-
__version__ = '2024.1.
|
|
15
|
+
__version__ = '2024.1.3'
|
|
16
16
|
__license__ = 'GPL v3'
|
|
17
17
|
__author__ = 'Open Science Tools Ltd'
|
|
18
18
|
__author_email__ = 'support@opensciencetools.org'
|
|
19
19
|
__maintainer_email__ = 'support@opensciencetools.org'
|
|
20
20
|
__url__ = 'https://www.psychopy.org/'
|
|
21
21
|
__download_url__ = 'https://github.com/psychopy/psychopy/releases/'
|
|
22
|
-
__git_sha__ = '
|
|
22
|
+
__git_sha__ = 'a2e6ccdec'
|
|
23
23
|
__build_platform__ = 'n/a'
|
|
24
24
|
|
|
25
25
|
__all__ = ["gui", "misc", "visual", "core",
|
|
@@ -364,10 +364,22 @@ class MouseComponent(BaseComponent):
|
|
|
364
364
|
buff.writeIndentedLines(code % self.params)
|
|
365
365
|
buff.setIndentLevel(1, relative=True)
|
|
366
366
|
dedent += 1
|
|
367
|
+
# keep track of whether something's been written
|
|
368
|
+
hasContent = False
|
|
369
|
+
# write code to check clickable stim, if there are any
|
|
367
370
|
if self.params['clickable'].val:
|
|
368
371
|
self._writeClickableObjectsCode(buff)
|
|
372
|
+
hasContent = True
|
|
373
|
+
# write code to check correct stim, if there are any
|
|
369
374
|
if self.params['storeCorrect']:
|
|
370
375
|
self._writeCorrectAnsCode(buff)
|
|
376
|
+
hasContent = True
|
|
377
|
+
# if current if statement has no content, add a pass
|
|
378
|
+
if not hasContent:
|
|
379
|
+
buff.writeIndentedLines(
|
|
380
|
+
"pass"
|
|
381
|
+
)
|
|
382
|
+
|
|
371
383
|
return buff, dedent
|
|
372
384
|
|
|
373
385
|
# No mouse tracking, end routine on any or valid click
|
|
@@ -43,7 +43,7 @@ class CounterbalanceRoutine(BaseStandaloneRoutine):
|
|
|
43
43
|
self.params['specMode'] = Param(
|
|
44
44
|
specMode, valType="str", inputType="choice", categ="Basic",
|
|
45
45
|
allowedVals=["uniform", "file"],
|
|
46
|
-
allowedLabels=[_translate("Num. groups"), _translate("Conditions file")],
|
|
46
|
+
allowedLabels=[_translate("Num. groups"), _translate("Conditions file (local only)")],
|
|
47
47
|
label=_translate("Groups from..."),
|
|
48
48
|
hint=_translate(
|
|
49
49
|
"Specify groups using an Excel file (for fine tuned control), specify as a variable name, or specify a "
|
psychopy/hardware/keyboard.py
CHANGED
|
@@ -573,7 +573,7 @@ class KeyboardDevice(BaseResponseDevice, aliases=["keyboard"]):
|
|
|
573
573
|
if message.type == "KEYBOARD_PRESS":
|
|
574
574
|
# if message is from a key down event, make a new response
|
|
575
575
|
response = KeyPress(code=message.char, tDown=message.time, name=message.key)
|
|
576
|
-
response.rt = response.tDown
|
|
576
|
+
response.rt = response.tDown - self.clock.getLastResetTime()
|
|
577
577
|
self._keysStillDown.append(response)
|
|
578
578
|
else:
|
|
579
579
|
# if message is from a key up event, alter existing response
|
|
@@ -1 +1 @@
|
|
|
1
|
-
from .test_base_components import
|
|
1
|
+
from .test_base_components import BaseComponentTests
|
psychopy/tests/test_experiment/test_components/{test_ButtonBox.py → test_ButtonBoxComponent.py}
RENAMED
|
@@ -11,21 +11,14 @@ from psychopy.hardware.button import ButtonResponse
|
|
|
11
11
|
from psychopy.experiment.routines import Routine
|
|
12
12
|
from psychopy.experiment.components.buttonBox import ButtonBoxComponent
|
|
13
13
|
from psychopy.experiment.components.code import CodeComponent
|
|
14
|
-
from .test_base_components import
|
|
14
|
+
from psychopy.tests.test_experiment.test_components.test_base_components import BaseComponentTests
|
|
15
|
+
from psychopy.hardware.button import ButtonBox
|
|
15
16
|
|
|
16
17
|
|
|
17
|
-
class TestButtonBoxComponent(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
# make component
|
|
25
|
-
self.comp = ButtonBoxComponent(
|
|
26
|
-
exp=self.exp, name="testPhotodiodeValidatorRoutine", parentName="testRoutine"
|
|
27
|
-
)
|
|
28
|
-
|
|
18
|
+
class TestButtonBoxComponent(BaseComponentTests):
|
|
19
|
+
comp = ButtonBoxComponent
|
|
20
|
+
libraryClass = ButtonBox
|
|
21
|
+
|
|
29
22
|
def test_values(self):
|
|
30
23
|
"""
|
|
31
24
|
Test that a variety of different values work when run from Builder.
|
|
@@ -65,9 +58,8 @@ class TestButtonBoxComponent(_TestBaseComponentsMixin):
|
|
|
65
58
|
thisCase[keys[i]] = val
|
|
66
59
|
# add case
|
|
67
60
|
cases.append(thisCase)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
exp = Experiment()
|
|
61
|
+
# make minimal experiment just for this test
|
|
62
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
71
63
|
# configure experiment
|
|
72
64
|
exp.requireImport("ButtonResponse", importFrom="psychopy.hardware.button")
|
|
73
65
|
exp.settings.params['Full-screen window'].val = False
|
|
@@ -79,18 +71,8 @@ class TestButtonBoxComponent(_TestBaseComponentsMixin):
|
|
|
79
71
|
resps = case.pop("resps")
|
|
80
72
|
if not isinstance(resps, (list, tuple)):
|
|
81
73
|
resps = [resps]
|
|
82
|
-
# make a name
|
|
83
|
-
name = f"rt{i}"
|
|
84
|
-
# make a Routine
|
|
85
|
-
rt = exp.addRoutine(name, Routine(name=name, exp=exp))
|
|
86
|
-
exp.flow.addRoutine(rt, 0)
|
|
87
74
|
# add timeout
|
|
88
75
|
rt.settings.params['stopVal'].val = 0.2
|
|
89
|
-
# make a Component
|
|
90
|
-
comp = ButtonBoxComponent(
|
|
91
|
-
exp, parentName=name, name=name + "_comp", **case
|
|
92
|
-
)
|
|
93
|
-
rt.addComponent(comp)
|
|
94
76
|
# make a Code Component to send responses
|
|
95
77
|
code = (
|
|
96
78
|
"if frameN > 1:\n"
|
|
@@ -104,7 +86,7 @@ class TestButtonBoxComponent(_TestBaseComponentsMixin):
|
|
|
104
86
|
name=comp.name, value=resp.value, channel=resp.channel
|
|
105
87
|
)
|
|
106
88
|
codeComp = CodeComponent(
|
|
107
|
-
exp, parentName=name + "_code", eachFrame=code
|
|
89
|
+
exp, parentName=comp.name + "_code", eachFrame=code
|
|
108
90
|
)
|
|
109
91
|
rt.addComponent(codeComp)
|
|
110
92
|
# save exp in temp directory
|
|
@@ -2,42 +2,30 @@ from pathlib import Path
|
|
|
2
2
|
from tempfile import mkdtemp
|
|
3
3
|
|
|
4
4
|
from psychopy import experiment
|
|
5
|
-
from . import
|
|
5
|
+
from . import BaseComponentTests
|
|
6
6
|
from psychopy.experiment.loops import TrialHandler
|
|
7
7
|
from psychopy.experiment.routines import Routine
|
|
8
8
|
from psychopy.experiment.components.code import CodeComponent
|
|
9
9
|
from psychopy.tests.utils import TESTS_DATA_PATH
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
class TestCodeComponent(
|
|
12
|
+
class TestCodeComponent(BaseComponentTests):
|
|
13
13
|
"""
|
|
14
14
|
Test that Code coponents have the correct params and write as expected.
|
|
15
15
|
"""
|
|
16
|
+
comp = CodeComponent
|
|
16
17
|
|
|
17
18
|
@classmethod
|
|
18
19
|
def setup_class(cls):
|
|
19
|
-
cls.exp = experiment.Experiment() # create once, not every test
|
|
20
20
|
try:
|
|
21
21
|
cls.tempDir = mkdtemp(dir=Path(__file__).root, prefix='psychopy-tests-app')
|
|
22
22
|
except (PermissionError, OSError):
|
|
23
23
|
# can't write to root on Linux
|
|
24
24
|
cls.tempDir = mkdtemp(prefix='psychopy-tests-app')
|
|
25
25
|
|
|
26
|
-
def setup_method(self):
|
|
27
|
-
# Make blank experiment
|
|
28
|
-
self.exp = experiment.Experiment()
|
|
29
|
-
# Make blank routine
|
|
30
|
-
self.routine = Routine(name="testRoutine", exp=self.exp)
|
|
31
|
-
self.exp.addRoutine("testRoutine", self.routine)
|
|
32
|
-
self.exp.flow.addRoutine(self.routine, 0)
|
|
33
|
-
# Add loop around routine
|
|
34
|
-
self.loop = TrialHandler(exp=self.exp, name="testLoop")
|
|
35
|
-
self.exp.flow.addLoop(self.loop, 0, -1)
|
|
36
|
-
# Make Mouse component
|
|
37
|
-
self.comp = CodeComponent(exp=self.exp, parentName="testRoutine", name="testCode")
|
|
38
|
-
self.routine.addComponent(self.comp)
|
|
39
|
-
|
|
40
26
|
def test_all_code_component_tabs(self):
|
|
27
|
+
# make minimal experiment just for this test
|
|
28
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
41
29
|
# Names of each tab in a Code component
|
|
42
30
|
tabs = {
|
|
43
31
|
'Before Experiment': '___before_experiment___',
|
|
@@ -50,11 +38,11 @@ class TestCodeComponent(_TestBaseComponentsMixin, _TestDisabledMixin):
|
|
|
50
38
|
# Add markers to component
|
|
51
39
|
for paramName, marker in tabs.items():
|
|
52
40
|
jsParamName = paramName.replace(" ", " JS ")
|
|
53
|
-
|
|
41
|
+
comp.params[paramName].val = comp.params[jsParamName].val = " = ".join([self.comp.__name__, comp.name, marker])
|
|
54
42
|
|
|
55
43
|
# Write script
|
|
56
|
-
pyScript =
|
|
57
|
-
jsScript =
|
|
44
|
+
pyScript = exp.writeScript(target="PsychoPy")
|
|
45
|
+
jsScript = exp.writeScript(target="PsychoJS")
|
|
58
46
|
|
|
59
47
|
# Check that code from each tab exists in compiled script
|
|
60
48
|
for lang, script in {"Python": pyScript, "JS": jsScript}.items():
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from psychopy.tests.test_experiment.test_components.test_base_components import BaseComponentTests, _TestLibraryClassMixin
|
|
2
|
+
from psychopy.experiment.components.grating import GratingComponent
|
|
3
|
+
from psychopy.visual import GratingStim
|
|
4
|
+
|
|
5
|
+
class TestGratingComponent(BaseComponentTests, _TestLibraryClassMixin):
|
|
6
|
+
comp = GratingComponent
|
|
7
|
+
libraryClass = GratingStim
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from psychopy.experiment.components.image import ImageComponent
|
|
2
|
+
from psychopy.tests.test_experiment.test_components.test_base_components import BaseComponentTests, _TestDepthMixin, _TestLibraryClassMixin
|
|
3
|
+
from psychopy.visual.image import ImageStim
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class TestImage(BaseComponentTests, _TestLibraryClassMixin):
|
|
7
|
+
comp = ImageComponent
|
|
8
|
+
libraryClass = ImageStim
|
|
@@ -1,65 +1,52 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from . import
|
|
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(
|
|
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('
|
|
44
|
-
'avoid': ["
|
|
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('
|
|
47
|
-
"
|
|
48
|
-
'avoid': ["thisExp.addData('
|
|
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('
|
|
51
|
-
"
|
|
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('
|
|
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('
|
|
56
|
-
"
|
|
57
|
-
'avoid': ["thisExp.addData('
|
|
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('
|
|
61
|
-
"
|
|
62
|
-
"thisExp.addData('
|
|
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
|
-
|
|
75
|
+
comp.params['saveMouseState'].val = SMScase['val']
|
|
89
76
|
for FEROPcase in forceEndRoutineOnPressCases:
|
|
90
77
|
# Set forceEndRoutineOnPress
|
|
91
|
-
|
|
78
|
+
comp.params['forceEndRoutineOnPress'].val = FEROPcase['val']
|
|
92
79
|
for Ccase in clickableCases:
|
|
93
80
|
# Set clickable
|
|
94
|
-
|
|
81
|
+
comp.params['clickable'].val = Ccase['val']
|
|
95
82
|
|
|
96
83
|
# Compile script
|
|
97
|
-
script =
|
|
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={
|
|
103
|
-
f"forceEndRoutineOnPress={
|
|
104
|
-
f"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={
|
|
109
|
-
f"forceEndRoutineOnPress={
|
|
110
|
-
f"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={
|
|
115
|
-
f"forceEndRoutineOnPress={
|
|
116
|
-
f"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={
|
|
122
|
-
f"forceEndRoutineOnPress={
|
|
123
|
-
f"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={
|
|
128
|
-
f"forceEndRoutineOnPress={
|
|
129
|
-
f"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={
|
|
134
|
-
f"forceEndRoutineOnPress={
|
|
135
|
-
f"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
|
|
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(
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
53
|
+
comp.params['shape'].val = case['val']
|
|
70
54
|
# Write experiment
|
|
71
|
-
pyScript =
|
|
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
|
|
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(
|
|
11
|
-
|
|
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
|
"""
|
psychopy/tests/test_experiment/test_components/{test_Settings.py → test_SettingsComponent.py}
RENAMED
|
@@ -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
|
|
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
|
|
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(
|
|
11
|
-
|
|
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
|
|
2
|
+
from . import BaseComponentTests
|
|
3
3
|
from psychopy import experiment
|
|
4
4
|
import inspect
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class _Generic(
|
|
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
|
-
#
|
|
22
|
-
tester =
|
|
23
|
-
#
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
)
|
|
@@ -6,27 +6,9 @@ from pathlib import Path
|
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
8
|
from psychopy import experiment
|
|
9
|
+
from psychopy.experiment.loops import TrialHandler
|
|
9
10
|
from psychopy.experiment.components import BaseComponent
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
def _make_minimal_experiment(obj):
|
|
13
|
-
"""
|
|
14
|
-
Make a minimal experiment with just one routine containing just one component, of the same class as the current
|
|
15
|
-
component but with all default params.
|
|
16
|
-
"""
|
|
17
|
-
# Skip whole test if required attributes aren't present
|
|
18
|
-
if not hasattr(obj, "comp"):
|
|
19
|
-
pytest.skip()
|
|
20
|
-
# Make blank experiment
|
|
21
|
-
exp = experiment.Experiment()
|
|
22
|
-
rt = exp.addRoutine(routineName='TestRoutine')
|
|
23
|
-
exp.flow.addRoutine(rt, 0)
|
|
24
|
-
# Create instance of this component with all default params
|
|
25
|
-
compClass = type(obj.comp)
|
|
26
|
-
comp = compClass(exp=exp, parentName='TestRoutine', name=f"test{compClass.__name__}")
|
|
27
|
-
rt.append(comp)
|
|
28
|
-
# Return experiment, routine and component
|
|
29
|
-
return comp, rt, exp
|
|
11
|
+
from psychopy.experiment.exports import IndentingBuffer
|
|
30
12
|
|
|
31
13
|
|
|
32
14
|
def _find_global_resource_in_js_experiment(script, resource):
|
|
@@ -48,34 +30,228 @@ def _find_global_resource_in_js_experiment(script, resource):
|
|
|
48
30
|
return resource in resourcesStr
|
|
49
31
|
|
|
50
32
|
|
|
51
|
-
class
|
|
52
|
-
#
|
|
53
|
-
|
|
33
|
+
class BaseComponentTests:
|
|
34
|
+
# component class to test
|
|
35
|
+
comp = None
|
|
54
36
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
37
|
+
# --- Utility methods ---
|
|
38
|
+
def make_minimal_experiment(self):
|
|
39
|
+
"""
|
|
40
|
+
Make a minimal experiment with just one routine containing just one component, of the same class as the current component but with all default params.
|
|
41
|
+
"""
|
|
42
|
+
# make blank experiment
|
|
43
|
+
exp = experiment.Experiment()
|
|
44
|
+
# add a Routine
|
|
45
|
+
rt = exp.addRoutine(routineName='TestRoutine')
|
|
46
|
+
exp.flow.addRoutine(rt, 0)
|
|
47
|
+
# add a loop around the Routine
|
|
48
|
+
loop = TrialHandler(exp=exp, name="testLoop")
|
|
49
|
+
exp.flow.addLoop(loop, 0, -1)
|
|
50
|
+
# create instance of this test's Component with all default params
|
|
51
|
+
comp = self.comp(exp=exp, parentName='TestRoutine', name=f"test{self.comp.__name__}")
|
|
52
|
+
rt.append(comp)
|
|
53
|
+
# return experiment, Routine and Component
|
|
54
|
+
return comp, rt, exp
|
|
55
|
+
|
|
56
|
+
@pytest.fixture(autouse=True)
|
|
57
|
+
def assert_comp_class(self):
|
|
58
|
+
"""
|
|
59
|
+
Make sure this test object has an associated Component class - and skip the test if not. This is run before each test by default.
|
|
60
|
+
"""
|
|
61
|
+
# skip whole test if there is no Component connected to test class
|
|
62
|
+
if self.comp is None:
|
|
59
63
|
pytest.skip()
|
|
60
|
-
#
|
|
64
|
+
# continue with the test as normal
|
|
65
|
+
yield
|
|
66
|
+
|
|
67
|
+
# --- Heritable tests ---
|
|
68
|
+
|
|
69
|
+
def test_icons(self):
|
|
70
|
+
"""
|
|
71
|
+
Check that Component has icons for each app theme and that these point to real files
|
|
72
|
+
"""
|
|
73
|
+
# pathify icon file path
|
|
61
74
|
icon = Path(self.comp.iconFile)
|
|
62
|
-
#
|
|
75
|
+
# get paths for each theme
|
|
63
76
|
files = [
|
|
64
77
|
icon.parent / "light" / icon.name,
|
|
65
78
|
icon.parent / "dark" / icon.name,
|
|
66
79
|
icon.parent / "classic" / icon.name,
|
|
67
80
|
]
|
|
68
|
-
#
|
|
81
|
+
# check that each path is a file
|
|
69
82
|
for file in files:
|
|
70
|
-
assert file.is_file()
|
|
83
|
+
assert file.is_file(), (
|
|
84
|
+
f"Could not find file: {file}"
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def test_indentation_consistency(self):
|
|
88
|
+
"""
|
|
89
|
+
No component should exit any of its write methods at a different indent level as it entered, as this would break subsequent components / routines.
|
|
90
|
+
"""
|
|
91
|
+
# make minimal experiment just for this test
|
|
92
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
93
|
+
# skip if component doesn't have a start/stop time
|
|
94
|
+
if "startVal" not in comp.params or "stopVal" not in comp.params:
|
|
95
|
+
pytest.skip()
|
|
96
|
+
# create a text buffer to write to
|
|
97
|
+
buff = IndentingBuffer(target="PsychoPy")
|
|
98
|
+
# template message for if test fails
|
|
99
|
+
errMsgTemplate = "Writing {} code for {} changes indent level by {} when start is `{}` and stop is `{}`."
|
|
100
|
+
# setup flow for writing
|
|
101
|
+
exp.flow.writeStartCode(buff)
|
|
102
|
+
# combinations of start/stop being set/unset to try
|
|
103
|
+
cases = [
|
|
104
|
+
{"startVal": "0", "stopVal": "1"},
|
|
105
|
+
{"startVal": "", "stopVal": "1"},
|
|
106
|
+
{"startVal": "0", "stopVal": ""},
|
|
107
|
+
{"startVal": "", "stopVal": ""},
|
|
108
|
+
]
|
|
109
|
+
for case in cases:
|
|
110
|
+
# update error message for this case
|
|
111
|
+
errMsg = errMsgTemplate.format(
|
|
112
|
+
"{}", type(comp).__name__, "{}", case['startVal'], case['stopVal']
|
|
113
|
+
)
|
|
114
|
+
# set start/stop types
|
|
115
|
+
comp.params["startType"].val = "time (s)"
|
|
116
|
+
comp.params["stopType"].val = "time (s)"
|
|
117
|
+
# set start/stop values
|
|
118
|
+
for param, val in case.items():
|
|
119
|
+
comp.params[param].val = val
|
|
120
|
+
# write init code
|
|
121
|
+
comp.writeInitCode(buff)
|
|
122
|
+
# check indent
|
|
123
|
+
assert buff.indentLevel == 0, errMsg.format(
|
|
124
|
+
"init", buff.indentLevel
|
|
125
|
+
)
|
|
126
|
+
# write routine start code
|
|
127
|
+
comp.writeRoutineStartCode(buff)
|
|
128
|
+
# check indent
|
|
129
|
+
assert buff.indentLevel == 0, errMsg.format(
|
|
130
|
+
"routine start", buff.indentLevel
|
|
131
|
+
)
|
|
132
|
+
# write each frame code
|
|
133
|
+
comp.writeFrameCode(buff)
|
|
134
|
+
# check indent
|
|
135
|
+
assert buff.indentLevel == 0, errMsg.format(
|
|
136
|
+
"each frame", buff.indentLevel
|
|
137
|
+
)
|
|
138
|
+
# write end routine code
|
|
139
|
+
comp.writeRoutineEndCode(buff)
|
|
140
|
+
# check indent
|
|
141
|
+
assert buff.indentLevel == 0, errMsg.format(
|
|
142
|
+
"routine end", buff.indentLevel
|
|
143
|
+
)
|
|
144
|
+
# write end experiment code
|
|
145
|
+
comp.writeExperimentEndCode(buff)
|
|
146
|
+
# check indent
|
|
147
|
+
assert buff.indentLevel == 0, errMsg.format(
|
|
148
|
+
"experiment end", buff.indentLevel
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
def test_disabled_default_val(self):
|
|
152
|
+
"""
|
|
153
|
+
Test that components created with default params are not disabled
|
|
154
|
+
"""
|
|
155
|
+
# make minimal experiment just for this test
|
|
156
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
157
|
+
# check whether it can be disabled
|
|
158
|
+
assert 'disabled' in comp.params, (
|
|
159
|
+
f"{type(comp).__name__} does not have a 'disabled' attribute."
|
|
160
|
+
)
|
|
161
|
+
# check that disabled defaults to False
|
|
162
|
+
assert comp.params['disabled'].val is False, f"{type(comp).__name__} is defaulting to disabled."
|
|
163
|
+
|
|
164
|
+
def test_disabled_code_muting(self):
|
|
165
|
+
"""
|
|
166
|
+
Test that components are only written when enabled and targets match.
|
|
167
|
+
"""
|
|
168
|
+
# Code Component is never referenced by name, so skip it for this test
|
|
169
|
+
if self.comp.__name__ == "CodeComponent":
|
|
170
|
+
pytest.skip()
|
|
171
|
+
# Make minimal experiment just for this test
|
|
172
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
173
|
+
# Write experiment and check that component is written
|
|
174
|
+
pyScript = exp.writeScript(target="PsychoPy")
|
|
175
|
+
if "PsychoPy" in type(comp).targets:
|
|
176
|
+
assert comp.name in pyScript, (
|
|
177
|
+
f"{type(comp).__name__} not found in compiled Python script when enabled and PsychoPy in targets."
|
|
178
|
+
)
|
|
179
|
+
else:
|
|
180
|
+
assert comp.name not in pyScript, (
|
|
181
|
+
f"{type(comp).__name__} found in compiled Python script when enabled but PsychoPy not in targets."
|
|
182
|
+
)
|
|
183
|
+
# ## disabled until js can compile without saving
|
|
184
|
+
# jsScript = exp.writeScript(target="PsychoJS")
|
|
185
|
+
# if "PsychoJS" in type(comp).targets:
|
|
186
|
+
# assert comp.name in jsScript, (
|
|
187
|
+
# f"{type(comp).__name__} not found in compiled Python script when enabled and PsychoJS in targets."
|
|
188
|
+
# )
|
|
189
|
+
# else:
|
|
190
|
+
# assert comp.name not in jsScript, (
|
|
191
|
+
# f"{type(comp).__name__} found in compiled Python script when enabled but PsychoJS not in targets."
|
|
192
|
+
# )
|
|
193
|
+
|
|
194
|
+
# disable component then do same tests but assert not present
|
|
195
|
+
comp.params['disabled'].val = True
|
|
196
|
+
|
|
197
|
+
pyScript = exp.writeScript(target="PsychoPy")
|
|
198
|
+
if "PsychoPy" in type(comp).targets:
|
|
199
|
+
assert comp.name not in pyScript, (
|
|
200
|
+
f"{type(comp).__name__} found in compiled Python script when disabled but PsychoPy in targets."
|
|
201
|
+
)
|
|
202
|
+
else:
|
|
203
|
+
assert comp.name not in pyScript, (
|
|
204
|
+
f"{type(comp).__name__} found in compiled Python script when disabled and PsychoPy not in targets."
|
|
205
|
+
)
|
|
206
|
+
# ## disabled until js can compile without saving
|
|
207
|
+
# jsScript = exp.writeScript(target="PsychoJS")
|
|
208
|
+
# if "PsychoJS" in type(comp).targets:
|
|
209
|
+
# assert comp.name not in jsScript, (
|
|
210
|
+
# f"{type(comp).__name__} found in compiled Python script when disabled but PsychoJS in targets."
|
|
211
|
+
# )
|
|
212
|
+
# else:
|
|
213
|
+
# assert comp.name not in jsScript, (
|
|
214
|
+
# f"{type(comp).__name__} found in compiled Python script when disabled and PsychoJS not in targets."
|
|
215
|
+
# )
|
|
71
216
|
|
|
72
|
-
def
|
|
217
|
+
def test_disabled_components_stay_in_routine(self):
|
|
218
|
+
"""
|
|
219
|
+
Test that disabled components aren't removed from their routine when experiment is written.
|
|
220
|
+
"""
|
|
221
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
222
|
+
# Disable component
|
|
223
|
+
comp.params['disabled'].val = True
|
|
224
|
+
# Writing the script drops the component but, if working properly, only from a copy of the routine, not the
|
|
225
|
+
# original!
|
|
226
|
+
exp.writeScript()
|
|
227
|
+
|
|
228
|
+
assert comp in rt, f"Disabling {type(comp).name} appears to remove it from its routine on compile."
|
|
229
|
+
class _TestLibraryClassMixin:
|
|
230
|
+
# class in the PsychoPy libraries (visual, sound, hardware, etc.) corresponding to this component
|
|
231
|
+
libraryClass = None
|
|
232
|
+
|
|
233
|
+
# --- Utility methods ---
|
|
234
|
+
|
|
235
|
+
@pytest.fixture(autouse=True)
|
|
236
|
+
def assert_lib_class(self):
|
|
237
|
+
"""
|
|
238
|
+
Make sure this test object has an associated library class - and skip the test if not. This is run before each test by default.
|
|
239
|
+
"""
|
|
240
|
+
# skip whole test if there is no Component connected to test class
|
|
241
|
+
if self.libraryClass is None:
|
|
242
|
+
pytest.skip()
|
|
243
|
+
# continue with the test as normal
|
|
244
|
+
yield
|
|
245
|
+
|
|
246
|
+
# --- Heritable tests ---
|
|
247
|
+
|
|
248
|
+
def test_device_class_refs(self):
|
|
73
249
|
"""
|
|
74
250
|
Check that any references to device classes in this Routine object point to classes which
|
|
75
251
|
exist.
|
|
76
252
|
"""
|
|
77
253
|
# make minimal experiment just for this test
|
|
78
|
-
comp, rt, exp =
|
|
254
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
79
255
|
# skip test if this element doesn't point to any hardware class
|
|
80
256
|
if not hasattr(comp, "deviceClasses"):
|
|
81
257
|
pytest.skip()
|
|
@@ -91,13 +267,7 @@ class _TestBaseComponentsMixin:
|
|
|
91
267
|
|
|
92
268
|
def test_params_used(self):
|
|
93
269
|
# Make minimal experiment just for this test
|
|
94
|
-
comp, rt, exp =
|
|
95
|
-
# Skip if component shouldn't use all of its params
|
|
96
|
-
if type(comp).__name__ in ["SettingsComponent", "CodeComponent"]:
|
|
97
|
-
pytest.skip()
|
|
98
|
-
# Skip if component is deprecated
|
|
99
|
-
if type(comp).__name__ in ['RatingScaleComponent', 'PatchComponent']:
|
|
100
|
-
pytest.skip()
|
|
270
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
101
271
|
# Try with PsychoPy and PsychoJS
|
|
102
272
|
for target in ("PsychoPy", "PsychoJS"):
|
|
103
273
|
## Skip PsychoJS until can write script without saving
|
|
@@ -134,11 +304,8 @@ class _TestBaseComponentsMixin:
|
|
|
134
304
|
"""
|
|
135
305
|
Check that all params which are settable each frame/repeat have a set method in the corresponding class.
|
|
136
306
|
"""
|
|
137
|
-
# Skip if there's no corresponding library class
|
|
138
|
-
if self.libraryClass is None:
|
|
139
|
-
return
|
|
140
307
|
# Make minimal experiment just for this test
|
|
141
|
-
comp, rt, exp =
|
|
308
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
142
309
|
# Check each param
|
|
143
310
|
for paramName, param in comp.params.items():
|
|
144
311
|
if not param.direct:
|
|
@@ -167,91 +334,11 @@ class _TestBaseComponentsMixin:
|
|
|
167
334
|
)
|
|
168
335
|
|
|
169
336
|
|
|
170
|
-
class _TestDisabledMixin:
|
|
171
|
-
def test_disabled_default_val(self):
|
|
172
|
-
"""
|
|
173
|
-
Test that components created with default params are not disabled
|
|
174
|
-
"""
|
|
175
|
-
# Make minimal experiment just for this test
|
|
176
|
-
comp, rt, exp = _make_minimal_experiment(self)
|
|
177
|
-
# Check whether it can be disabled
|
|
178
|
-
assert 'disabled' in comp.params, (
|
|
179
|
-
f"{type(comp).__name__} does not have a 'disabled' attribute."
|
|
180
|
-
)
|
|
181
|
-
# Check that disabled defaults to False
|
|
182
|
-
assert comp.params['disabled'].val is False, f"{type(comp).__name__} is defaulting to disabled."
|
|
183
|
-
|
|
184
|
-
def test_code_muting(self):
|
|
185
|
-
"""
|
|
186
|
-
Test that components are only written when enabled and targets match.
|
|
187
|
-
"""
|
|
188
|
-
# Make minimal experiment just for this test
|
|
189
|
-
comp, rt, exp = _make_minimal_experiment(self)
|
|
190
|
-
# Skip for Code components as these purely inject code, name isn't used
|
|
191
|
-
if type(comp).__name__ in ("CodeComponent"):
|
|
192
|
-
pytest.skip()
|
|
193
|
-
# Write experiment and check that component is written
|
|
194
|
-
pyScript = exp.writeScript(target="PsychoPy")
|
|
195
|
-
if "PsychoPy" in type(comp).targets:
|
|
196
|
-
assert comp.name in pyScript, (
|
|
197
|
-
f"{type(comp).__name__} not found in compiled Python script when enabled and PsychoPy in targets."
|
|
198
|
-
)
|
|
199
|
-
else:
|
|
200
|
-
assert comp.name not in pyScript, (
|
|
201
|
-
f"{type(comp).__name__} found in compiled Python script when enabled but PsychoPy not in targets."
|
|
202
|
-
)
|
|
203
|
-
# ## disabled until js can compile without saving
|
|
204
|
-
# jsScript = exp.writeScript(target="PsychoJS")
|
|
205
|
-
# if "PsychoJS" in type(comp).targets:
|
|
206
|
-
# assert comp.name in jsScript, (
|
|
207
|
-
# f"{type(comp).__name__} not found in compiled Python script when enabled and PsychoJS in targets."
|
|
208
|
-
# )
|
|
209
|
-
# else:
|
|
210
|
-
# assert comp.name not in jsScript, (
|
|
211
|
-
# f"{type(comp).__name__} found in compiled Python script when enabled but PsychoJS not in targets."
|
|
212
|
-
# )
|
|
213
|
-
|
|
214
|
-
# Disable component then do same tests but assert not present
|
|
215
|
-
comp.params['disabled'].val = True
|
|
216
|
-
|
|
217
|
-
pyScript = exp.writeScript(target="PsychoPy")
|
|
218
|
-
if "PsychoPy" in type(comp).targets:
|
|
219
|
-
assert comp.name not in pyScript, (
|
|
220
|
-
f"{type(comp).__name__} found in compiled Python script when disabled but PsychoPy in targets."
|
|
221
|
-
)
|
|
222
|
-
else:
|
|
223
|
-
assert comp.name not in pyScript, (
|
|
224
|
-
f"{type(comp).__name__} found in compiled Python script when disabled and PsychoPy not in targets."
|
|
225
|
-
)
|
|
226
|
-
# ## disabled until js can compile without saving
|
|
227
|
-
# jsScript = exp.writeScript(target="PsychoJS")
|
|
228
|
-
# if "PsychoJS" in type(comp).targets:
|
|
229
|
-
# assert comp.name not in jsScript, (
|
|
230
|
-
# f"{type(comp).__name__} found in compiled Python script when disabled but PsychoJS in targets."
|
|
231
|
-
# )
|
|
232
|
-
# else:
|
|
233
|
-
# assert comp.name not in jsScript, (
|
|
234
|
-
# f"{type(comp).__name__} found in compiled Python script when disabled and PsychoJS not in targets."
|
|
235
|
-
# )
|
|
236
|
-
|
|
237
|
-
def test_disabled_components_stay_in_routine(self):
|
|
238
|
-
"""
|
|
239
|
-
Test that disabled components aren't removed from their routine when experiment is written.
|
|
240
|
-
"""
|
|
241
|
-
comp, rt, exp = _make_minimal_experiment(self)
|
|
242
|
-
# Disable component
|
|
243
|
-
comp.params['disabled'].val = True
|
|
244
|
-
# Writing the script drops the component but, if working properly, only from a copy of the routine, not the
|
|
245
|
-
# original!
|
|
246
|
-
exp.writeScript()
|
|
247
|
-
|
|
248
|
-
assert comp in rt, f"Disabling {type(comp).name} appears to remove it from its routine on compile."
|
|
249
|
-
|
|
250
337
|
|
|
251
338
|
class _TestDepthMixin:
|
|
252
339
|
def test_depth(self):
|
|
253
340
|
# Make minimal experiment
|
|
254
|
-
comp, rt, exp =
|
|
341
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
255
342
|
# Get class we're currently working with
|
|
256
343
|
compClass = type(comp)
|
|
257
344
|
# Add index to component name
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: psychopy
|
|
3
|
-
Version: 2024.1.
|
|
3
|
+
Version: 2024.1.3
|
|
4
4
|
Summary: PsychoPy provides easy, precise, flexible experiments in behavioural sciences
|
|
5
5
|
Author-Email: Open Science Tools Ltd <support@opensciencetools.org>
|
|
6
6
|
Maintainer-Email: Open Science Tools Ltd <support@opensciencetools.org>
|
|
@@ -23,7 +23,7 @@ Requires-Dist: matplotlib
|
|
|
23
23
|
Requires-Dist: pyglet==1.4.11; platform_system == "Windows"
|
|
24
24
|
Requires-Dist: pyglet==1.5.27; platform_system != "Windows"
|
|
25
25
|
Requires-Dist: pillow>=9.4.0
|
|
26
|
-
Requires-Dist:
|
|
26
|
+
Requires-Dist: pyqt6
|
|
27
27
|
Requires-Dist: pandas>=1.5.3
|
|
28
28
|
Requires-Dist: questplus>=2023.1
|
|
29
29
|
Requires-Dist: openpyxl
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
psychopy-2024.1.
|
|
2
|
-
psychopy-2024.1.
|
|
3
|
-
psychopy-2024.1.
|
|
4
|
-
psychopy-2024.1.
|
|
5
|
-
psychopy-2024.1.
|
|
1
|
+
psychopy-2024.1.3.dist-info/METADATA,sha256=Dgf2hQgHlVrGjHGkRlF_xx0N_lUO9X6FETfx-vdWyic,6993
|
|
2
|
+
psychopy-2024.1.3.dist-info/WHEEL,sha256=7sv5iXvIiTVJSnAxCz2tGBm9DHsb2vPSzeYeT7pvGUY,90
|
|
3
|
+
psychopy-2024.1.3.dist-info/entry_points.txt,sha256=1LXVqRMSILrbEagrzpJDtmXyEPHX3GnpBJ85TEnxuoI,56
|
|
4
|
+
psychopy-2024.1.3.dist-info/licenses/AUTHORS.md,sha256=MmZf-GmSBscBa_z7ePoqYxbaGe6XOJnld_s6JIQGfS4,2395
|
|
5
|
+
psychopy-2024.1.3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
6
6
|
psychopy/CHANGELOG.txt,sha256=bRyB9AEemUO4KBYhtBOIWOaXFmX9X3pHgMMF9QyeITA,203527
|
|
7
7
|
psychopy/LICENSE.txt,sha256=d2HeFOYbuXc2LZobE1EkFq3lYV5ge3YSaTL3y1r7KQc,746
|
|
8
8
|
psychopy/LICENSES.txt,sha256=T59KljDkUEEtd40IHWS-S0OTSjzqueGD6oNmgqpRIf0,3145
|
|
9
|
-
psychopy/__init__.py,sha256=
|
|
9
|
+
psychopy/__init__.py,sha256=TaSpE94UGKdQ0J3pbhPIO_aH4HsJ3AlNIdFspPjwik0,2757
|
|
10
10
|
psychopy/alerts/__init__.py,sha256=buvC7HFn71FhIp1D4XGXkZLeNLk22uO9TSQsxLlYZqU,2178
|
|
11
11
|
psychopy/alerts/_alerts.py,sha256=IMHMXY1mzTCmlOYhHW0_Upb9oAcYzzTWe44BUNXj-ec,6120
|
|
12
12
|
psychopy/alerts/_errorHandler.py,sha256=JNkdx3OJv0PeAeARG09Rgne7dH-aGgUdxdoriDd4KW4,1501
|
|
@@ -1446,7 +1446,7 @@ psychopy/experiment/components/microphone/dark/microphone.png,sha256=q6XPPab-nnF
|
|
|
1446
1446
|
psychopy/experiment/components/microphone/dark/microphone@2x.png,sha256=x58B_E0YQNUV2dyye52APaf-25S7nfpP70j-2-7PpLQ,1853
|
|
1447
1447
|
psychopy/experiment/components/microphone/light/microphone.png,sha256=bQztv6e7oCUK8852Zc5RcLt_kEgqI9c_d_S8W-6WEt4,988
|
|
1448
1448
|
psychopy/experiment/components/microphone/light/microphone@2x.png,sha256=swrycVelLJd8k57jbaS5AYXq5ievFSs-rhsNePv_rQM,1841
|
|
1449
|
-
psychopy/experiment/components/mouse/__init__.py,sha256=
|
|
1449
|
+
psychopy/experiment/components/mouse/__init__.py,sha256=pT5xrJxpOhiZEUKrbkPBFgTGG_yA6xgsDYmZj9dNqUE,34739
|
|
1450
1450
|
psychopy/experiment/components/mouse/classic/mouse.png,sha256=rXSJ4vFYekhNjANSuJnLdLmCF0-Y6p6s8b7JyL6It9Y,3735
|
|
1451
1451
|
psychopy/experiment/components/mouse/classic/mouse@2x.png,sha256=Ms-piLdbP1zKFBP5bbiBb7sF_Bps67GG7ZpBnItxoNM,11310
|
|
1452
1452
|
psychopy/experiment/components/mouse/dark/mouse.png,sha256=KWXV2z5bUx80lwu3H98-8h2XWo9ZyQvM3iRU22CQ7z8,772
|
|
@@ -1609,7 +1609,7 @@ psychopy/experiment/questPlusTemplate.xltx,sha256=8c1yt6el4v_iE79FoelLX267TpFrPs
|
|
|
1609
1609
|
psychopy/experiment/questTemplate.xltx,sha256=p0FzYmMWJH0uaGRFlAdPT4uSzNBHpV7uPM0gZN5yYds,20668
|
|
1610
1610
|
psychopy/experiment/routines/__init__.py,sha256=mQTjLeu5H7K_EGp_WZ7I5jXDKNgPF4ViJz00aG_pV-g,3672
|
|
1611
1611
|
psychopy/experiment/routines/_base.py,sha256=VMln_MS1QPNga64wBR0fB0pMsHu28UeyElZAuIil7pA,38584
|
|
1612
|
-
psychopy/experiment/routines/counterbalance/__init__.py,sha256=
|
|
1612
|
+
psychopy/experiment/routines/counterbalance/__init__.py,sha256=XxkGNfrQoTvuL0i80bWWYy2VANsxN7Fl93Y2C7xpc5c,12616
|
|
1613
1613
|
psychopy/experiment/routines/counterbalance/classic/counterbalance.png,sha256=ficKpm9rX1A-YIzgFNfM6EbwAklenfKeOwP74ktCgfo,3977
|
|
1614
1614
|
psychopy/experiment/routines/counterbalance/classic/counterbalance@2x.png,sha256=UwSvAzg0Y9k1jEtkvbzr277tApPB08o4gFRuhhN5NpA,10628
|
|
1615
1615
|
psychopy/experiment/routines/counterbalance/counterbalanceItems.xltx,sha256=Ht1ZE6c800RGF1LxE6WjWGujNwsMQ04pw6j_VZu86uE,18707
|
|
@@ -1683,7 +1683,7 @@ psychopy/hardware/forp.py,sha256=P19o4cmrZD4kHhJwNT0kj5LR-F4kdwXSu5GpYyiis4U,135
|
|
|
1683
1683
|
psychopy/hardware/gammasci.py,sha256=odRzQ1kKduDqrQshp582YtKnXnSFPXWc8qic9jjPZMc,1000
|
|
1684
1684
|
psychopy/hardware/iolab.py,sha256=8fqy-xGe15naHLgYfxELpes5ooNDTUytLTTz9_NhTi0,1067
|
|
1685
1685
|
psychopy/hardware/joystick/__init__.py,sha256=wBhX_21kRPAlKM2UyEZBYBKhDCfiLHIp-K7r_2bDorI,19109
|
|
1686
|
-
psychopy/hardware/keyboard.py,sha256=
|
|
1686
|
+
psychopy/hardware/keyboard.py,sha256=enf7nluy1w3_SYA2B2mCrVY0Cx3ytM5BjtXdkIjiLqk,34192
|
|
1687
1687
|
psychopy/hardware/knownDevices.json,sha256=rGsTu0MaBdUTUA6bwCKU9D-J03i0oFPDWOw28Eu4Ik0,1791
|
|
1688
1688
|
psychopy/hardware/labhackers.py,sha256=_fRtMUtSd5f2DXRVgVsXQdF3x9ZDFypXcuxaD0J1C0E,864
|
|
1689
1689
|
psychopy/hardware/labjacks.py,sha256=CQfxgty2uGdG2bzkcbfw-pKBzxHlnSSVfcPHKlsOC8E,980
|
|
@@ -2744,17 +2744,18 @@ psychopy/tests/test_experiment/needs_wx/test_Experiment.py,sha256=HpN-2uiKFitW6y
|
|
|
2744
2744
|
psychopy/tests/test_experiment/needs_wx/test_components.py,sha256=nr06cyK0vPbJVOFXESx5Q5ehjKI9i669HbS6cJDzlGA,7092
|
|
2745
2745
|
psychopy/tests/test_experiment/test_component_compile_js.py,sha256=LrVUQ-izAN23e5M1t3Tg7NaourscsDABSBtPZeEWm24,2775
|
|
2746
2746
|
psychopy/tests/test_experiment/test_component_compile_python.py,sha256=SALVfXswwu64hyfIsqzPhDru5EVO5tyuUDAOLrXDE10,7002
|
|
2747
|
-
psychopy/tests/test_experiment/test_components/__init__.py,sha256=
|
|
2748
|
-
psychopy/tests/test_experiment/test_components/
|
|
2749
|
-
psychopy/tests/test_experiment/test_components/
|
|
2750
|
-
psychopy/tests/test_experiment/test_components/
|
|
2751
|
-
psychopy/tests/test_experiment/test_components/
|
|
2752
|
-
psychopy/tests/test_experiment/test_components/
|
|
2753
|
-
psychopy/tests/test_experiment/test_components/
|
|
2754
|
-
psychopy/tests/test_experiment/test_components/
|
|
2755
|
-
psychopy/tests/test_experiment/test_components/
|
|
2756
|
-
psychopy/tests/test_experiment/test_components/
|
|
2757
|
-
psychopy/tests/test_experiment/test_components/
|
|
2747
|
+
psychopy/tests/test_experiment/test_components/__init__.py,sha256=qQqf5031kA1-Qcj4ActVGQbE6wB4DQQ2JpdBnf4e7Sc,52
|
|
2748
|
+
psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py,sha256=sG_M3v97JIrFvpDGRYn7Y21--zvzpQkPTtEnsXspBPk,6748
|
|
2749
|
+
psychopy/tests/test_experiment/test_components/test_CodeComponent.py,sha256=8U4Z2FDhn6Gf1DRnOAEEScl47gFHWz1-6_nhAiQwrkI,3460
|
|
2750
|
+
psychopy/tests/test_experiment/test_components/test_GratingComponent.py,sha256=zdaSZhd-XAkihUBt7mnq93QEuEDniUeRxE0LHWl98Qo,363
|
|
2751
|
+
psychopy/tests/test_experiment/test_components/test_ImageComponent.py,sha256=oFlxj67_r5H68VF84FcGa8rrgBxTo81lURS9L6mBSpA,366
|
|
2752
|
+
psychopy/tests/test_experiment/test_components/test_MouseComponent.py,sha256=2pFUhxQmCWBeUvaUxWaayEDFfgkIOP8CtzWP3o2e4UI,7876
|
|
2753
|
+
psychopy/tests/test_experiment/test_components/test_PolygonComponent.py,sha256=wXaGVfe-qERMcgtRexFofpjsBjR4WdWKBFtPIBut8Wo,2954
|
|
2754
|
+
psychopy/tests/test_experiment/test_components/test_ResourceManagerComponent.py,sha256=n-mB_VoTn3PxUWETjggyU5yvh56k4xQQMYruOy2ScM0,2533
|
|
2755
|
+
psychopy/tests/test_experiment/test_components/test_SettingsComponent.py,sha256=hdcoBh8u9X4si97L8naTz7Ix2rzlHK4FpP52-hDYENY,3338
|
|
2756
|
+
psychopy/tests/test_experiment/test_components/test_StaticComponent.py,sha256=Ta0gzNMN-lqE77iyQ6z0eR_71ijNlGhSr01IFaiHJoE,2434
|
|
2757
|
+
psychopy/tests/test_experiment/test_components/test_all_components.py,sha256=O-7fSqlk-oaTK4HC65_lsDv0sTF4xQ9p0P3uXoenMzc,4403
|
|
2758
|
+
psychopy/tests/test_experiment/test_components/test_base_components.py,sha256=StKDjDX8Hg88s_znEpD6ivZlz4Fxuvm_UWiS38dJv_k,17849
|
|
2758
2759
|
psychopy/tests/test_experiment/test_experiment.py,sha256=WRWimiyviyzkPc85PuqTumrVrbrZe0yB95WYraGXLsw,4439
|
|
2759
2760
|
psychopy/tests/test_experiment/test_loops.py,sha256=8-lHo7nAXaiorP_hpv2oSyA_UZAt2617L3CyusrIUCs,3703
|
|
2760
2761
|
psychopy/tests/test_experiment/test_params.py,sha256=e2WjO4T1xvb0sRtZXph9CAcN3YjIN79hzziTiqoEu8o,13172
|
|
@@ -2947,4 +2948,4 @@ psychopy/voicekey/parallel_vks.py,sha256=I6a07GvN0Q2k9xidl9YbEUDORG2v9l2H_5Owbpw
|
|
|
2947
2948
|
psychopy/voicekey/signal.py,sha256=Mk363qVsvJampVDfsOTdGq7lPESlKmogmNFqasdghJE,1013
|
|
2948
2949
|
psychopy/voicekey/vk_tools.py,sha256=pFvOvF9b9CfS-JkZ_fv38LxI59hJXQqiz9ymcrJiAFc,8483
|
|
2949
2950
|
psychopy/web.py,sha256=ohiFb7lW1-0pH_62cR-z8ufZ5Nta2jRIjGS4_zosX_U,10228
|
|
2950
|
-
psychopy-2024.1.
|
|
2951
|
+
psychopy-2024.1.3.dist-info/RECORD,,
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
from psychopy.experiment import Experiment
|
|
2
|
-
from psychopy.experiment.components.image import ImageComponent
|
|
3
|
-
from psychopy.experiment.loops import TrialHandler
|
|
4
|
-
from psychopy.experiment.routines import Routine
|
|
5
|
-
from .test_base_components import _TestDepthMixin, _TestBaseComponentsMixin
|
|
6
|
-
from psychopy.visual.image import ImageStim
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class TestImage(_TestBaseComponentsMixin, _TestDepthMixin):
|
|
10
|
-
libraryClass = ImageStim
|
|
11
|
-
|
|
12
|
-
def setup_method(self):
|
|
13
|
-
# Make blank experiment
|
|
14
|
-
self.exp = Experiment()
|
|
15
|
-
# Make blank routine
|
|
16
|
-
self.routine = Routine(name="testRoutine", exp=self.exp)
|
|
17
|
-
self.exp.addRoutine("testRoutine", self.routine)
|
|
18
|
-
self.exp.flow.addRoutine(self.routine, 0)
|
|
19
|
-
# Add loop around routine
|
|
20
|
-
self.loop = TrialHandler(exp=self.exp, name="testLoop")
|
|
21
|
-
self.exp.flow.addLoop(self.loop, 0, -1)
|
|
22
|
-
# Make a rect for when we need something to click on
|
|
23
|
-
self.comp = ImageComponent(exp=self.exp, parentName="testRoutine", name="testImage")
|
|
24
|
-
self.routine.addComponent(self.comp)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|