psychopy 2024.1.4__py3-none-any.whl → 2024.2.0__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/.DS_Store +0 -0
- psychopy/CHANGELOG.txt +206 -0
- psychopy/GIT_SHA +1 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +77 -15
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/__init__.py +76 -2
- psychopy/app/_psychopyApp.py +126 -101
- psychopy/app/builder/builder.py +14 -10
- psychopy/app/builder/dialogs/__init__.py +8 -8
- psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
- psychopy/app/builder/dialogs/paramCtrls.py +24 -57
- psychopy/app/builder/validators.py +2 -2
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +4 -4
- psychopy/app/connections/sendusage.py +2 -2
- psychopy/app/connections/updates.py +9 -9
- psychopy/app/dialogs.py +34 -2
- psychopy/app/idle.py +31 -0
- psychopy/app/jobs.py +21 -3
- psychopy/app/linuxconfig/__init__.py +9 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1011 -942
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
- psychopy/app/pavlovia_ui/_base.py +33 -3
- psychopy/app/pavlovia_ui/search.py +0 -1
- psychopy/app/plugin_manager/dialog.py +104 -51
- psychopy/app/plugin_manager/packages.py +5 -0
- psychopy/app/plugin_manager/plugins.py +145 -67
- psychopy/app/preferencesDlg.py +8 -8
- psychopy/app/psychopyApp.py +11 -5
- psychopy/app/ribbon.py +124 -14
- psychopy/app/runner/runner.py +6 -1
- psychopy/app/stdout/stdOutRich.py +27 -11
- psychopy/app/themes/icons.py +52 -2
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/next.png +0 -0
- psychopy/assets/psychopy.ico +0 -0
- psychopy/assets/psychopy.png +0 -0
- psychopy/assets/templates/__init__.py +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/window.ico +0 -0
- psychopy/changes/2023.1.0.md +9 -0
- psychopy/changes/2024.1.0.md +16 -0
- psychopy/changes/__init__.py +0 -0
- psychopy/clock.py +2 -2
- psychopy/colors.py +2 -1
- psychopy/compatibility.py +53 -1
- psychopy/contrib/.DS_Store +0 -0
- psychopy/contrib/configobj/__init__.py +10 -8
- psychopy/data/__init__.py +3 -2
- psychopy/data/base.py +5 -5
- psychopy/data/experiment.py +130 -4
- psychopy/data/routine.py +56 -0
- psychopy/data/staircase.py +2 -2
- psychopy/data/trial.py +559 -97
- psychopy/data/utils.py +56 -21
- psychopy/demos/.DS_Store +0 -0
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Hardware/.DS_Store +0 -0
- psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
- psychopy/demos/coder/iohub/.DS_Store +0 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/event.py +30 -29
- psychopy/experiment/.DS_Store +0 -0
- psychopy/experiment/_experiment.py +6 -6
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/__init__.py +6 -3
- psychopy/experiment/components/_base.py +286 -131
- psychopy/experiment/components/aperture/.DS_Store +0 -0
- psychopy/experiment/components/brush/.DS_Store +0 -0
- psychopy/experiment/components/button/.DS_Store +0 -0
- psychopy/experiment/components/button/__init__.py +5 -1
- psychopy/experiment/components/buttonBox/.DS_Store +0 -0
- psychopy/experiment/components/camera/.DS_Store +0 -0
- psychopy/experiment/components/code/.DS_Store +0 -0
- psychopy/experiment/components/dots/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/form/__init__.py +6 -2
- psychopy/experiment/components/grating/.DS_Store +0 -0
- psychopy/experiment/components/grating/__init__.py +14 -3
- psychopy/experiment/components/image/.DS_Store +0 -0
- psychopy/experiment/components/image/__init__.py +14 -3
- psychopy/experiment/components/joyButtons/.DS_Store +0 -0
- psychopy/experiment/components/joystick/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/__init__.py +22 -10
- psychopy/experiment/components/microphone/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +59 -39
- psychopy/experiment/components/mouse/.DS_Store +0 -0
- psychopy/experiment/components/mouse/__init__.py +44 -29
- psychopy/experiment/components/movie/.DS_Store +0 -0
- psychopy/experiment/components/movie/__init__.py +1 -1
- psychopy/experiment/components/panorama/.DS_Store +0 -0
- psychopy/experiment/components/parallelOut/.DS_Store +0 -0
- psychopy/experiment/components/patch/.DS_Store +0 -0
- psychopy/experiment/components/polygon/.DS_Store +0 -0
- psychopy/experiment/components/polygon/__init__.py +26 -6
- psychopy/experiment/components/progress/.DS_Store +0 -0
- psychopy/experiment/components/ratingScale/.DS_Store +0 -0
- psychopy/experiment/components/resourceManager/.DS_Store +0 -0
- psychopy/experiment/components/roi/.DS_Store +0 -0
- psychopy/experiment/components/roi/__init__.py +5 -0
- psychopy/experiment/components/routineSettings/.DS_Store +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +57 -10
- psychopy/experiment/components/serialOut/.DS_Store +0 -0
- psychopy/experiment/components/settings/.DS_Store +0 -0
- psychopy/experiment/components/settings/__init__.py +117 -42
- psychopy/experiment/components/slider/.DS_Store +0 -0
- psychopy/experiment/components/sound/.DS_Store +0 -0
- psychopy/experiment/components/sound/__init__.py +54 -19
- psychopy/experiment/components/static/.DS_Store +0 -0
- psychopy/experiment/components/static/__init__.py +1 -1
- psychopy/experiment/components/text/.DS_Store +0 -0
- psychopy/experiment/components/text/__init__.py +28 -3
- psychopy/experiment/components/textbox/.DS_Store +0 -0
- psychopy/experiment/components/textbox/__init__.py +12 -2
- psychopy/experiment/components/unknown/.DS_Store +0 -0
- psychopy/experiment/components/unknown/__init__.py +1 -2
- psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
- psychopy/experiment/components/variable/.DS_Store +0 -0
- psychopy/experiment/flow.py +11 -4
- psychopy/experiment/loops.py +85 -37
- psychopy/experiment/params.py +74 -32
- psychopy/experiment/py2js_transpiler.py +8 -1
- psychopy/experiment/routines/.DS_Store +0 -0
- psychopy/experiment/routines/_base.py +102 -22
- psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
- psychopy/experiment/routines/counterbalance/__init__.py +5 -1
- psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
- psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
- psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/__init__.py +6 -5
- psychopy/experiment/routines/unknown/.DS_Store +0 -0
- psychopy/gui/wxgui.py +4 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/__init__.py +1 -1
- psychopy/hardware/base.py +12 -0
- psychopy/hardware/camera/__init__.py +1 -15
- psychopy/hardware/cedrus.py +10 -11
- psychopy/hardware/crs/colorcal.py +13 -22
- psychopy/hardware/crs/optical.py +10 -20
- psychopy/hardware/emulator.py +17 -14
- psychopy/hardware/eyetracker.py +42 -118
- psychopy/hardware/gammasci.py +4 -15
- psychopy/hardware/keyboard.py +102 -10
- psychopy/hardware/listener.py +3 -0
- psychopy/hardware/microphone.py +148 -18
- psychopy/hardware/minolta.py +8 -15
- psychopy/hardware/photodiode.py +191 -16
- psychopy/hardware/photometer/__init__.py +11 -19
- psychopy/hardware/pr.py +8 -15
- psychopy/hardware/speaker.py +39 -4
- psychopy/info.py +0 -71
- psychopy/iohub/.DS_Store +0 -0
- psychopy/iohub/__init__.py +1 -1
- psychopy/iohub/client/__init__.py +30 -20
- psychopy/iohub/client/keyboard.py +24 -24
- psychopy/iohub/datastore/__init__.py +2 -2
- psychopy/iohub/datastore/util.py +2 -2
- psychopy/iohub/default_config.yaml +1 -1
- psychopy/iohub/devices/.DS_Store +0 -0
- psychopy/iohub/devices/__init__.py +112 -25
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
- psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
- psychopy/iohub/devices/eyetracker/__init__.py +46 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
- psychopy/iohub/server.py +2 -2
- psychopy/iohub/start_iohub_process.py +3 -0
- psychopy/iohub/util/__init__.py +62 -70
- psychopy/layout.py +5 -5
- psychopy/logging.py +8 -1
- psychopy/microphone.py +10 -37
- psychopy/platform_specific/__init__.py +0 -2
- psychopy/platform_specific/darwin.py +1 -3
- psychopy/platform_specific/linux.py +31 -33
- psychopy/platform_specific/win32.py +38 -13
- psychopy/plugins/__init__.py +148 -116
- psychopy/plugins/util.py +39 -0
- psychopy/preferences/Darwin.spec +4 -2
- psychopy/preferences/FreeBSD.spec +4 -2
- psychopy/preferences/Linux.spec +4 -2
- psychopy/preferences/Windows.spec +4 -2
- psychopy/preferences/baseNoArch.spec +4 -2
- psychopy/preferences/preferences.py +47 -24
- psychopy/projects/pavlovia.py +47 -4
- psychopy/scripts/psyexpCompile.py +0 -4
- psychopy/session.py +153 -21
- psychopy/sound/__init__.py +31 -21
- psychopy/sound/_base.py +20 -3
- psychopy/sound/audioclip.py +320 -33
- psychopy/sound/backend_ptb.py +47 -58
- psychopy/sound/backend_pygame.py +1 -1
- psychopy/sound/backend_pysound.py +6 -15
- psychopy/sound/transcribe.py +53 -0
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
- psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_session/.DS_Store +0 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/conftest.py +2 -2
- psychopy/tests/test_app/test_speed.py +4 -1
- psychopy/tests/test_data/test_TrialHandler2.py +146 -1
- psychopy/tests/test_experiment/.DS_Store +0 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
- psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
- psychopy/tests/test_experiment/test_py2js.py +1 -1
- psychopy/tests/test_hardware/test_keyboard.py +31 -0
- psychopy/tests/test_hardware/test_ports.py +1 -11
- psychopy/tests/test_liaison/test_Liaison.py +47 -0
- psychopy/tests/test_misc/test_core.py +5 -0
- psychopy/tests/test_session/test_Session.py +5 -1
- psychopy/tests/test_tools/test_versionchooser.py +39 -8
- psychopy/tests/test_visual/test_all_stimuli.py +0 -97
- psychopy/tests/test_visual/test_image.py +6 -5
- psychopy/tests/test_visual/test_textbox.py +36 -0
- psychopy/tests/utils.py +4 -0
- psychopy/tools/filetools.py +1 -1
- psychopy/tools/pkgtools.py +160 -137
- psychopy/tools/versionchooser.py +10 -10
- psychopy/tools/wizard.py +3 -3
- psychopy/visual/.DS_Store +0 -0
- psychopy/visual/backends/pygletbackend.py +24 -13
- psychopy/visual/basevisual.py +5 -11
- psychopy/visual/button.py +2 -14
- psychopy/visual/helpers.py +5 -5
- psychopy/visual/line.py +1 -2
- psychopy/visual/movie2.py +7 -816
- psychopy/visual/movie3.py +7 -589
- psychopy/visual/movies/__init__.py +8 -11
- psychopy/visual/movies/frame.py +5 -2
- psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
- psychopy/visual/noise.py +8 -7
- psychopy/visual/patch.py +7 -16
- psychopy/visual/radial.py +9 -7
- psychopy/visual/ratingscale.py +8 -1415
- psychopy/visual/secondorder.py +10 -9
- psychopy/visual/shape.py +7 -2
- psychopy/visual/text.py +1 -1
- psychopy/visual/textbox2/textbox2.py +28 -5
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/RECORD +307 -213
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
- psychopy/app/Resources/click.png +0 -0
- psychopy/app/Resources/next.png +0 -0
- psychopy/experiment/components/patch/__init__.py +0 -121
- psychopy/experiment/components/patch/classic/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
- psychopy/experiment/components/patch/light/patch.png +0 -0
- psychopy/experiment/components/patch/light/patch@2x.png +0 -0
- psychopy/experiment/components/ratingScale/__init__.py +0 -337
- psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
- psychopy/platform_specific/posix.py +0 -16
- psychopy/tests/test_sound/test_microphone.py +0 -217
- psychopy/tests/test_visual/test_ratingScale.py +0 -299
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
- /psychopy/{app/Resources → assets}/USB-C.png +0 -0
- /psychopy/{app/Resources → assets}/USB.png +0 -0
- /psychopy/{app/Resources → assets}/creditCard.png +0 -0
- /psychopy/{app/Resources → assets}/default.mp3 +0 -0
- /psychopy/{app/Resources → assets}/default.mp4 +0 -0
- /psychopy/{app/Resources → assets}/default.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -9,6 +9,8 @@ from psychopy import experiment
|
|
|
9
9
|
from psychopy.experiment.loops import TrialHandler
|
|
10
10
|
from psychopy.experiment.components import BaseComponent
|
|
11
11
|
from psychopy.experiment.exports import IndentingBuffer
|
|
12
|
+
from psychopy.constants import FOREVER
|
|
13
|
+
from psychopy.tests import utils
|
|
12
14
|
|
|
13
15
|
|
|
14
16
|
def _find_global_resource_in_js_experiment(script, resource):
|
|
@@ -147,6 +149,62 @@ class BaseComponentTests:
|
|
|
147
149
|
assert buff.indentLevel == 0, errMsg.format(
|
|
148
150
|
"experiment end", buff.indentLevel
|
|
149
151
|
)
|
|
152
|
+
|
|
153
|
+
def test_blank_timing(self):
|
|
154
|
+
"""
|
|
155
|
+
Check that this Component can handle blank start/stop values.
|
|
156
|
+
"""
|
|
157
|
+
# make minimal experiment just for this test
|
|
158
|
+
comp, rt, exp = self.make_minimal_experiment()
|
|
159
|
+
# skip if Component doesn't have the relevant params (e.g. Code Component)
|
|
160
|
+
for key in ("startVal", "startType", "stopVal", "stopType"):
|
|
161
|
+
if key not in comp.params:
|
|
162
|
+
pytest.skip()
|
|
163
|
+
# StaticComponent has entirely bespoke start/stop tests so skip it here
|
|
164
|
+
if type(comp).__name__ == "StaticComponent":
|
|
165
|
+
pytest.skip()
|
|
166
|
+
# make sure start and stop are as times
|
|
167
|
+
comp.params['startType'].val = "time (s)"
|
|
168
|
+
comp.params['stopType'].val = "duration (s)"
|
|
169
|
+
# define cases and expected start/dur
|
|
170
|
+
cases = [
|
|
171
|
+
# blank start
|
|
172
|
+
{'startVal': "", 'stopVal': "1", 'startTime': None, 'duration': 1},
|
|
173
|
+
# blank stop
|
|
174
|
+
{'startVal': "0", 'stopVal': "", 'startTime': 0, 'duration': FOREVER},
|
|
175
|
+
# blank both
|
|
176
|
+
{'startVal': "", 'stopVal': "", 'startTime': None, 'duration': FOREVER},
|
|
177
|
+
]
|
|
178
|
+
# run all cases
|
|
179
|
+
for case in cases:
|
|
180
|
+
# apply values from case
|
|
181
|
+
comp.params['startVal'].val = case['startVal']
|
|
182
|
+
comp.params['stopVal'].val = case['stopVal']
|
|
183
|
+
# get values from start and duration method
|
|
184
|
+
startTime, duration, nonSlipSafe = comp.getStartAndDuration()
|
|
185
|
+
# check against expected
|
|
186
|
+
assert startTime == case['startTime']
|
|
187
|
+
assert duration == case['duration']
|
|
188
|
+
# check that it's never non-slip safe
|
|
189
|
+
assert not nonSlipSafe
|
|
190
|
+
# temp file to save scripts to for flake
|
|
191
|
+
import tempfile
|
|
192
|
+
file = Path(tempfile.gettempdir()) / "test_blank_timing_script.py"
|
|
193
|
+
# write the script
|
|
194
|
+
script = exp.writeScript(target="PsychoPy")
|
|
195
|
+
file.write_text(script, encoding="utf-8")
|
|
196
|
+
# check for syntax errors
|
|
197
|
+
try:
|
|
198
|
+
compile(script, str(file), "exec")
|
|
199
|
+
except Exception as err:
|
|
200
|
+
# save script
|
|
201
|
+
case['fail'] = Path(utils.TESTS_FAILS_PATH) / "test_blank_timing_script.py"
|
|
202
|
+
case['fail'].write_text(script, encoding="utf-8")
|
|
203
|
+
# raise error
|
|
204
|
+
raise AssertionError(
|
|
205
|
+
"Syntax error in compiled Builder code when startVal was '%(startVal)s' and "
|
|
206
|
+
"stopVal was '%(stopVal)s'. Failed script saved in '%(fail)s'" % case
|
|
207
|
+
)
|
|
150
208
|
|
|
151
209
|
def test_disabled_default_val(self):
|
|
152
210
|
"""
|
|
@@ -67,7 +67,7 @@ class TestTranspiler:
|
|
|
67
67
|
{'py': "a.upper()", 'js': "a.toUpperCase();\n"},
|
|
68
68
|
{'py': "a.extend([4, 5, 6])", 'js': "a.concat([4, 5, 6]);\n"},
|
|
69
69
|
{'py': "a.pop(0)", 'js': "a.splice(0, 1);\n"},
|
|
70
|
-
{'py': "a.pop()", 'js': "a.splice((- 1), 1);\n"},
|
|
70
|
+
{'py': "a.pop()", 'js': "a.splice((a.length - 1), 1);\n"},
|
|
71
71
|
]
|
|
72
72
|
# Try each case
|
|
73
73
|
for case in cases:
|
|
@@ -3,6 +3,7 @@ from psychopy.hardware import keyboard
|
|
|
3
3
|
import pytest
|
|
4
4
|
import time
|
|
5
5
|
from psychopy import logging
|
|
6
|
+
from psychopy.tests.utils import RUNNING_IN_VM
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
class _TestBaseKeyboard:
|
|
@@ -26,6 +27,33 @@ class _TestBaseKeyboard:
|
|
|
26
27
|
assert keys[-1] is evt
|
|
27
28
|
assert keys[-1].value == case['val']
|
|
28
29
|
|
|
30
|
+
def testAcceptDuplicateResponses(self):
|
|
31
|
+
"""
|
|
32
|
+
Test that KeyboardDevice can receive multiple presses of the same key without accepting
|
|
33
|
+
genuine duplicates (e.g. KeyPress objects added twice, or the same object added for press
|
|
34
|
+
and release)
|
|
35
|
+
"""
|
|
36
|
+
# clear
|
|
37
|
+
self.kb.clearEvents()
|
|
38
|
+
# press space twice and don't release
|
|
39
|
+
resp1 = self.kb.makeResponse(tDown=0.1, code="space")
|
|
40
|
+
resp2 = self.kb.makeResponse(tDown=0.2, code="space")
|
|
41
|
+
# make sure we only have 2 press objects
|
|
42
|
+
keys = self.kb.getKeys(waitRelease=False, clear=False)
|
|
43
|
+
assert len(keys) == 2
|
|
44
|
+
# simulate a release
|
|
45
|
+
resp1.duration = 0.2
|
|
46
|
+
resp2.duration = 0.1
|
|
47
|
+
self.kb.responses += [resp1, resp2]
|
|
48
|
+
# we should still only have 2 press objects (as these are duplicates)
|
|
49
|
+
keys = self.kb.getKeys(waitRelease=True, clear=False)
|
|
50
|
+
assert len(keys) == 2
|
|
51
|
+
# add the same objects again for no good reason
|
|
52
|
+
self.kb.responses += [resp1, resp2]
|
|
53
|
+
# we should STILL only have 2 press objects
|
|
54
|
+
keys = self.kb.getKeys(waitRelease=True, clear=False)
|
|
55
|
+
assert len(keys) == 2
|
|
56
|
+
|
|
29
57
|
def testMuteOutsidePsychopyNotSlower(self):
|
|
30
58
|
"""
|
|
31
59
|
Test that responses aren't worryingly slower when using muteOutsidePsychopy
|
|
@@ -33,6 +61,9 @@ class _TestBaseKeyboard:
|
|
|
33
61
|
# skip this test on Linux (as MOP *is* slower due to having to use subprocess)
|
|
34
62
|
if sys.platform == "linux":
|
|
35
63
|
pytest.skip()
|
|
64
|
+
# skip speed tests under vm
|
|
65
|
+
if RUNNING_IN_VM:
|
|
66
|
+
pytest.skip()
|
|
36
67
|
|
|
37
68
|
# array to store times
|
|
38
69
|
times = {}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import psychopy.hardware as hw
|
|
2
3
|
import pytest
|
|
3
4
|
try:
|
|
@@ -109,17 +110,6 @@ def test_getCRSPhotometers():
|
|
|
109
110
|
photoms = list(hw.getAllPhotometers())
|
|
110
111
|
assert faked in photoms
|
|
111
112
|
|
|
112
|
-
def test_getPhotometers():
|
|
113
|
-
photoms = hw.getAllPhotometers()
|
|
114
|
-
|
|
115
|
-
# Always iterable
|
|
116
|
-
assert isinstance(photoms, Iterable)
|
|
117
|
-
|
|
118
|
-
photoms = list(photoms)
|
|
119
|
-
|
|
120
|
-
assert len(photoms) > 0
|
|
121
|
-
|
|
122
|
-
|
|
123
113
|
# I wish our PR650 would behave like this ;-)
|
|
124
114
|
_MockPhotometer = type("MockPhotometer",(),{"OK": True,"type": "MockPhotometer"})
|
|
125
115
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import threading
|
|
1
2
|
from psychopy import liaison, session, hardware
|
|
2
3
|
from psychopy.hardware import DeviceManager
|
|
3
4
|
from psychopy.tests import utils, skip_under_vm
|
|
@@ -88,6 +89,52 @@ class TestLiaison:
|
|
|
88
89
|
self.server, self.protocol, "session", "runExperiment",
|
|
89
90
|
"exp1"
|
|
90
91
|
)
|
|
92
|
+
|
|
93
|
+
def test_future_trials(self):
|
|
94
|
+
# add experiment
|
|
95
|
+
runInLiaison(
|
|
96
|
+
self.server, self.protocol, "session", "addExperiment",
|
|
97
|
+
"testFutureTrials/testFutureTrials.psyexp", "testFutureTrials"
|
|
98
|
+
)
|
|
99
|
+
time.sleep(1)
|
|
100
|
+
# define a threaded task to run alongside experiment
|
|
101
|
+
def _thread():
|
|
102
|
+
# wait for first meaningful result
|
|
103
|
+
resp = None
|
|
104
|
+
i = 0
|
|
105
|
+
while resp is None and i < 24:
|
|
106
|
+
# get future trial
|
|
107
|
+
runInLiaison(
|
|
108
|
+
self.server, self.protocol, "session", "getFutureTrial",
|
|
109
|
+
"1", "True"
|
|
110
|
+
)
|
|
111
|
+
# get result
|
|
112
|
+
resp = json.loads(self.protocol.messages[-1]["result"])
|
|
113
|
+
# wait 0.1s
|
|
114
|
+
time.sleep(0.1)
|
|
115
|
+
# iterate towards limit
|
|
116
|
+
i += 1
|
|
117
|
+
# if we hit iteration limit, fail
|
|
118
|
+
assert i < 24, "Timed out waiting for a non-None result from getFutureTrial"
|
|
119
|
+
# does response have all the keys we expect?
|
|
120
|
+
expectedKeys = (
|
|
121
|
+
"type", "thisN", "thisRepN", "thisTrialN", "thisIndex", "data"
|
|
122
|
+
)
|
|
123
|
+
keysPresent = [key in resp for key in expectedKeys]
|
|
124
|
+
assert all(keysPresent), "Trial object missing key(s): {}".format(
|
|
125
|
+
expectedKeys[i] for i, val in enumerate(keysPresent) if not val
|
|
126
|
+
)
|
|
127
|
+
# resp should have type "trial_data"
|
|
128
|
+
assert resp['type'] == "trial_data", (
|
|
129
|
+
f"First non-None result from getFutureTrial doesn't look like a Trial object: {resp}"
|
|
130
|
+
)
|
|
131
|
+
# start thread
|
|
132
|
+
threading.Thread(target=_thread).start()
|
|
133
|
+
# run experiment
|
|
134
|
+
runInLiaison(
|
|
135
|
+
self.server, self.protocol, "session", "runExperiment",
|
|
136
|
+
"testFutureTrials"
|
|
137
|
+
)
|
|
91
138
|
|
|
92
139
|
def test_experiment_error(self):
|
|
93
140
|
"""
|
|
@@ -25,6 +25,7 @@ import pytest
|
|
|
25
25
|
|
|
26
26
|
import psychopy
|
|
27
27
|
import psychopy.logging as logging
|
|
28
|
+
from psychopy.tests.utils import RUNNING_IN_VM
|
|
28
29
|
from psychopy.visual import Window
|
|
29
30
|
from psychopy.core import (getTime, MonotonicClock, Clock, CountdownTimer, wait,
|
|
30
31
|
StaticPeriod, shellCall)
|
|
@@ -346,6 +347,10 @@ def test_LoggingDefaultClock():
|
|
|
346
347
|
|
|
347
348
|
@pytest.mark.staticperiod
|
|
348
349
|
def test_StaticPeriod():
|
|
350
|
+
# this test is speed sensitive, so skip under VM
|
|
351
|
+
if RUNNING_IN_VM:
|
|
352
|
+
pytest.skip()
|
|
353
|
+
|
|
349
354
|
static = StaticPeriod()
|
|
350
355
|
static.start(0.1)
|
|
351
356
|
wait(0.05)
|
|
@@ -22,7 +22,8 @@ class TestSession:
|
|
|
22
22
|
'exp2': "exp2/exp2.psyexp",
|
|
23
23
|
'testCtrls': "testCtrls/testCtrls.psyexp",
|
|
24
24
|
'error': "error/error.psyexp",
|
|
25
|
-
'annotation': "annotation/annotation.psyexp"
|
|
25
|
+
'annotation': "annotation/annotation.psyexp",
|
|
26
|
+
'trialNav': "testTrialNav/trialNav.psyexp"
|
|
26
27
|
}
|
|
27
28
|
)
|
|
28
29
|
# setup devices
|
|
@@ -45,6 +46,9 @@ class TestSession:
|
|
|
45
46
|
self.sess.runExperiment("exp2")
|
|
46
47
|
self.sess.runExperiment("exp1")
|
|
47
48
|
|
|
49
|
+
def test_trial_navigation(self):
|
|
50
|
+
self.sess.runExperiment("trialNav")
|
|
51
|
+
|
|
48
52
|
def test_ctrls(self):
|
|
49
53
|
"""
|
|
50
54
|
Check that experiments check Session often enough for pause/resume commands sent asynchronously will still work.
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"""Tests for psychopy.tools.versionchooser"""
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
|
+
import unittest
|
|
6
|
+
import subprocess
|
|
7
|
+
import shutil
|
|
5
8
|
from pathlib import Path
|
|
6
9
|
|
|
7
10
|
import psychopy
|
|
@@ -168,11 +171,39 @@ class TestVersionRange:
|
|
|
168
171
|
)
|
|
169
172
|
|
|
170
173
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
""
|
|
174
|
+
class TestGitInstallation(unittest.TestCase):
|
|
175
|
+
def test_git_installed(self):
|
|
176
|
+
# Test if Git is installed on this system.
|
|
177
|
+
try:
|
|
178
|
+
# Attempt to get the Git version
|
|
179
|
+
result = subprocess.run(["git", "--version"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
|
180
|
+
# Check if the command was successful
|
|
181
|
+
self.assertTrue(result.returncode == 0, "Git is not installed or not in the PATH.")
|
|
182
|
+
except subprocess.CalledProcessError:
|
|
183
|
+
# If an error occurs, the test should fail
|
|
184
|
+
self.fail("Git is not installed or not in the PATH.")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class TestGitClone(unittest.TestCase):
|
|
188
|
+
def test_git_can_clone_repo(self):
|
|
189
|
+
# Test that Git can clone a repository
|
|
190
|
+
repo_url = "https://github.com/git/git" # Using a reliable repo that is always available
|
|
191
|
+
target_dir = "temp_repo"
|
|
192
|
+
|
|
193
|
+
try:
|
|
194
|
+
# Ensure the target directory does not exist before cloning
|
|
195
|
+
if os.path.exists(target_dir):
|
|
196
|
+
shutil.rmtree(target_dir)
|
|
197
|
+
|
|
198
|
+
# Run 'git clone' and capture output
|
|
199
|
+
subprocess.run(['git', 'clone', repo_url, target_dir], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
|
200
|
+
except subprocess.CalledProcessError as e:
|
|
201
|
+
# If Git clone fails for any reason
|
|
202
|
+
self.fail(f"Git clone command failed: {e}")
|
|
203
|
+
except FileNotFoundError:
|
|
204
|
+
# If the 'git' command is not found
|
|
205
|
+
self.fail("Git is not installed on this system.")
|
|
206
|
+
finally:
|
|
207
|
+
# Clean up by removing the cloned directory if it exists
|
|
208
|
+
if os.path.exists(target_dir):
|
|
209
|
+
shutil.rmtree(target_dir)
|
|
@@ -100,21 +100,6 @@ class _baseVisualTest():
|
|
|
100
100
|
#make sure we start with a clean window
|
|
101
101
|
self.win.flip()
|
|
102
102
|
|
|
103
|
-
def test_auto_draw(self):
|
|
104
|
-
win = self.win
|
|
105
|
-
stims=[]
|
|
106
|
-
stims.append(visual.PatchStim(win))
|
|
107
|
-
stims.append(visual.ShapeStim(win))
|
|
108
|
-
stims.append(visual.TextStim(win))
|
|
109
|
-
for stim in stims:
|
|
110
|
-
assert stim.status==constants.NOT_STARTED
|
|
111
|
-
stim.autoDraw = True
|
|
112
|
-
assert stim.status==constants.STARTED
|
|
113
|
-
stim.autoDraw = False
|
|
114
|
-
assert stim.status==constants.FINISHED
|
|
115
|
-
assert stim.status==constants.STOPPED
|
|
116
|
-
"{}".format(stim) #check that str(xxx) is working
|
|
117
|
-
|
|
118
103
|
def test_imageAndGauss(self):
|
|
119
104
|
win = self.win
|
|
120
105
|
fileName = os.path.join(utils.TESTS_DATA_PATH, 'testimage.jpg')
|
|
@@ -219,47 +204,6 @@ class _baseVisualTest():
|
|
|
219
204
|
utils.compareScreenshot('circleHex_%s.png' %(self.contextName), win)
|
|
220
205
|
win.flip()
|
|
221
206
|
|
|
222
|
-
|
|
223
|
-
def test_gabor(self):
|
|
224
|
-
win = self.win
|
|
225
|
-
#using init
|
|
226
|
-
gabor = visual.PatchStim(win, mask='gauss', ori=-45,
|
|
227
|
-
pos=[0.6 * self.scaleFactor, -0.6 * self.scaleFactor],
|
|
228
|
-
sf=2.0 / self.scaleFactor, size=2 * self.scaleFactor,
|
|
229
|
-
interpolate=True)
|
|
230
|
-
gabor.draw()
|
|
231
|
-
utils.compareScreenshot('gabor1_%s.png' %(self.contextName), win)
|
|
232
|
-
win.flip()#AFTER compare screenshot
|
|
233
|
-
|
|
234
|
-
#using .set()
|
|
235
|
-
gabor.ori = 45
|
|
236
|
-
gabor.size -= 0.2 * self.scaleFactor
|
|
237
|
-
gabor.setColor([45, 30, 0.3], colorSpace='dkl')
|
|
238
|
-
gabor.sf += 0.2 / self.scaleFactor
|
|
239
|
-
gabor.pos += [-0.5*self.scaleFactor, 0.5*self.scaleFactor]
|
|
240
|
-
gabor.contrast = 0.8
|
|
241
|
-
gabor.opacity = 0.8
|
|
242
|
-
gabor.draw()
|
|
243
|
-
utils.compareScreenshot('gabor2_%s.png' %(self.contextName), win)
|
|
244
|
-
win.flip()
|
|
245
|
-
"{}".format(gabor) #check that str(xxx) is working
|
|
246
|
-
|
|
247
|
-
@pytest.mark.bufferimage
|
|
248
|
-
def test_bufferImage(self):
|
|
249
|
-
"""BufferImage inherits from ImageStim, so test .ori. .pos etc there not here
|
|
250
|
-
"""
|
|
251
|
-
win = self.win
|
|
252
|
-
gabor = visual.PatchStim(win, mask='gauss', ori=-45,
|
|
253
|
-
pos=[0.6*self.scaleFactor, -0.6*self.scaleFactor],
|
|
254
|
-
sf=2.0/self.scaleFactor, size=2*self.scaleFactor,
|
|
255
|
-
interpolate=True)
|
|
256
|
-
|
|
257
|
-
bufferImgStim = visual.BufferImageStim(self.win, stim=[gabor],
|
|
258
|
-
interpolate=True)
|
|
259
|
-
bufferImgStim.draw()
|
|
260
|
-
utils.compareScreenshot('bufferimg_gabor_%s.png' %(self.contextName), win, crit=8)
|
|
261
|
-
win.flip()
|
|
262
|
-
|
|
263
207
|
#def testMaskMatrix(self):
|
|
264
208
|
# #aims to draw the exact same stimulus as in testGabor, but using filters
|
|
265
209
|
# win=self.win
|
|
@@ -334,33 +278,6 @@ class _baseVisualTest():
|
|
|
334
278
|
utils.compareScreenshot('blend_add_%s.png' %self.contextName,
|
|
335
279
|
win, crit=20)
|
|
336
280
|
|
|
337
|
-
def test_mov(self):
|
|
338
|
-
win = self.win
|
|
339
|
-
if self.win.winType == 'pygame':
|
|
340
|
-
pytest.skip("movies only available for pyglet backend")
|
|
341
|
-
|
|
342
|
-
win.flip()
|
|
343
|
-
#construct full path to the movie file
|
|
344
|
-
fileName = os.path.join(utils.TESTS_DATA_PATH, 'testMovie.mp4')
|
|
345
|
-
#check if present
|
|
346
|
-
if not os.path.isfile(fileName):
|
|
347
|
-
raise IOError('Could not find movie file: %s'
|
|
348
|
-
% os.path.abspath(fileName))
|
|
349
|
-
#then do actual drawing
|
|
350
|
-
pos = [0.6*self.scaleFactor, -0.6*self.scaleFactor]
|
|
351
|
-
mov = visual.MovieStim3(win, fileName, pos=pos, noAudio=True)
|
|
352
|
-
mov.setFlipVert(True)
|
|
353
|
-
mov.setFlipHoriz(True)
|
|
354
|
-
threshold = 30
|
|
355
|
-
for frameN in range(10):
|
|
356
|
-
mov.draw()
|
|
357
|
-
|
|
358
|
-
if frameN==0:
|
|
359
|
-
utils.compareScreenshot('movFrame1_%s.png' %self.contextName,
|
|
360
|
-
win, crit=threshold)
|
|
361
|
-
win.flip()
|
|
362
|
-
"{}".format(mov) #check that str(xxx) is working
|
|
363
|
-
|
|
364
281
|
def test_rect(self):
|
|
365
282
|
win = self.win
|
|
366
283
|
rect = visual.Rect(win)
|
|
@@ -550,20 +467,6 @@ class _baseVisualTest():
|
|
|
550
467
|
win, crit=30)
|
|
551
468
|
#aperture should automatically disable on exit
|
|
552
469
|
|
|
553
|
-
def test_rating_scale(self):
|
|
554
|
-
if self.win.winType=='pygame':
|
|
555
|
-
pytest.skip("RatingScale not available on pygame")
|
|
556
|
-
# try to avoid text; avoid default / 'triangle' because it does not display on win XP
|
|
557
|
-
win = self.win
|
|
558
|
-
win.flip()
|
|
559
|
-
rs = visual.RatingScale(win, low=0, high=1, precision=100, size=3, pos=(0,-.4),
|
|
560
|
-
labels=[' ', ' '], scale=' ',
|
|
561
|
-
marker='glow', markerStart=0.7, markerColor='darkBlue', autoLog=False)
|
|
562
|
-
"{}".format(rs) #check that str(xxx) is working
|
|
563
|
-
rs.draw()
|
|
564
|
-
utils.compareScreenshot('ratingscale1_%s.png' %(self.contextName), win, crit=40.0)
|
|
565
|
-
win.flip()#AFTER compare screenshot
|
|
566
|
-
|
|
567
470
|
@skip_under_vm
|
|
568
471
|
def test_refresh_rate(self):
|
|
569
472
|
if self.win.winType=='pygame':
|
|
@@ -3,10 +3,8 @@ from pathlib import Path
|
|
|
3
3
|
from psychopy import visual, colors, core
|
|
4
4
|
from .test_basevisual import _TestUnitsMixin
|
|
5
5
|
from psychopy.tests.test_experiment.test_component_compile_python import _TestBoilerplateMixin
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
from ..utils import TESTS_DATA_PATH
|
|
9
|
-
|
|
6
|
+
from psychopy.tests import utils
|
|
7
|
+
import pytest
|
|
10
8
|
|
|
11
9
|
class TestImage(_TestUnitsMixin, _TestBoilerplateMixin):
|
|
12
10
|
"""
|
|
@@ -17,7 +15,7 @@ class TestImage(_TestUnitsMixin, _TestBoilerplateMixin):
|
|
|
17
15
|
self.win = visual.Window()
|
|
18
16
|
self.obj = visual.ImageStim(
|
|
19
17
|
self.win,
|
|
20
|
-
str(Path(TESTS_DATA_PATH) / 'testimage.jpg'),
|
|
18
|
+
str(Path(utils.TESTS_DATA_PATH) / 'testimage.jpg'),
|
|
21
19
|
colorSpace='rgb1',
|
|
22
20
|
)
|
|
23
21
|
|
|
@@ -187,6 +185,9 @@ class TestImageAnimation:
|
|
|
187
185
|
"""
|
|
188
186
|
Check that images can be updated sufficiently fast to create frame animations
|
|
189
187
|
"""
|
|
188
|
+
# skip speed tests under vm
|
|
189
|
+
if utils.RUNNING_IN_VM:
|
|
190
|
+
pytest.skip()
|
|
190
191
|
# Create clock
|
|
191
192
|
clock = core.Clock()
|
|
192
193
|
# Try at each size
|
|
@@ -102,6 +102,42 @@ class Test_textbox(_TestColorMixin, _TestUnitsMixin, _TestBoilerplateMixin):
|
|
|
102
102
|
#self.win.getMovieFrame(buffer='back').save(Path(utils.TESTS_DATA_PATH) / filename)
|
|
103
103
|
utils.compareScreenshot(Path(utils.TESTS_DATA_PATH) / filename, self.win, crit=20)
|
|
104
104
|
|
|
105
|
+
def test_ori(self):
|
|
106
|
+
# setup textbox
|
|
107
|
+
self.textbox.color = "black"
|
|
108
|
+
self.textbox.fillColor = "white"
|
|
109
|
+
self.textbox.units = "pix"
|
|
110
|
+
self.textbox.size = (100, 50)
|
|
111
|
+
self.textbox.pos = (0, 0)
|
|
112
|
+
self.textbox.letterHeight = 5
|
|
113
|
+
# define params to use
|
|
114
|
+
orientations = [
|
|
115
|
+
0, 120, 180, 240,
|
|
116
|
+
]
|
|
117
|
+
anchors = [
|
|
118
|
+
"top left", "center", "bottom right",
|
|
119
|
+
]
|
|
120
|
+
# try each combination
|
|
121
|
+
for ori in orientations:
|
|
122
|
+
for anchor in anchors:
|
|
123
|
+
# flip
|
|
124
|
+
self.win.flip()
|
|
125
|
+
# set params
|
|
126
|
+
self.textbox.ori = ori
|
|
127
|
+
self.textbox.anchor = anchor
|
|
128
|
+
self.textbox._layout()
|
|
129
|
+
# draw
|
|
130
|
+
self.textbox.draw()
|
|
131
|
+
# construct exemplar filename
|
|
132
|
+
exemplar = f"test_ori_{ori}_{anchor}.png"
|
|
133
|
+
# check/make exemplar
|
|
134
|
+
# self.win.getMovieFrame(buffer='back').save(
|
|
135
|
+
# Path(utils.TESTS_DATA_PATH) / "Test_textbox" / exemplar
|
|
136
|
+
# )
|
|
137
|
+
utils.compareScreenshot(
|
|
138
|
+
Path(utils.TESTS_DATA_PATH) / "Test_textbox" / exemplar, self.win, crit=20
|
|
139
|
+
)
|
|
140
|
+
|
|
105
141
|
def test_colors(self):
|
|
106
142
|
# Do base tests
|
|
107
143
|
_TestColorMixin.test_colors(self)
|
psychopy/tests/utils.py
CHANGED
|
@@ -6,6 +6,7 @@ import shutil
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import io
|
|
8
8
|
from psychopy import logging, colors
|
|
9
|
+
from psychopy.tools import systemtools
|
|
9
10
|
|
|
10
11
|
try:
|
|
11
12
|
from PIL import Image
|
|
@@ -14,6 +15,9 @@ except ImportError:
|
|
|
14
15
|
|
|
15
16
|
import pytest
|
|
16
17
|
|
|
18
|
+
# boolean indicating whether tests are running in a VM
|
|
19
|
+
RUNNING_IN_VM = systemtools.isVM_CI() is not None
|
|
20
|
+
|
|
17
21
|
# define the path where to find testing data
|
|
18
22
|
# so tests could be ran from any location
|
|
19
23
|
TESTS_PATH = abspath(dirname(__file__))
|
psychopy/tools/filetools.py
CHANGED
|
@@ -74,7 +74,7 @@ def _synonymiseExtensions(assets):
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
# Names accepted by stimulus classes & the filename of the default stimulus to use
|
|
77
|
-
defaultStimRoot = Path(__file__).parent.parent / "
|
|
77
|
+
defaultStimRoot = Path(__file__).parent.parent / "assets"
|
|
78
78
|
defaultStim = {
|
|
79
79
|
# Image stimuli
|
|
80
80
|
"default.png": "default.png",
|