def testPos(component, win, units): """ Runs position testing for component Parameters ---------- component: Component The component used for size testing win : TestWin object Used for testing component position in bounds units : str` Screen units """ if 'pos' not in component.params: return try: pos = convertParamToPix(component.params['pos'].val, win, units) except Exception: # Use of variables fails check return # Test X position if abs(pos[0]) > win.size[0]: alert(2155, component, {'dimension': 'X'}) # Test Y position if abs(pos[1]) > win.size[1]: alert(2155, component, {'dimension': 'Y'})
def testValidVisualStimTiming(component): """Test whether visual stimuli presented accurately for times requested, relative to screen refresh rate of 60 and 100Hz monitors. """ if component.type not in ["Text", "Aperture", "Dots", "EnvGrating", "Form", "Grating", "Image", "Movie", "NoiseStim", "Polygon"]: return if "startType" not in component.params or "stopType" not in component.params: return # Check for string / variable startVal = component.params['startVal'].val stopVal = component.params['stopVal'].val if testFloat(startVal): if component.params['startType'] == "time (s)": # Test times are valid multiples of screen refresh for 60Hz and 100Hz monitors if not validDuration(startVal, 60): alert(3115, component, {'type': 'start', 'time': startVal, 'Hz': 60}) if testFloat(stopVal): if component.params['stopType'] == "duration (s)": # Test times are valid multiples of screen refresh for 60Hz and 100Hz monitors if not validDuration(stopVal, 60): alert(3115, component, {'type': 'stop', 'time': stopVal, 'Hz': 60})
def testStartEndTiming(component): """ Tests stimuli starts before end time. Parameters ---------- component: Component The component used for size testing """ if "startType" not in component.params or "stopType" not in component.params : return if (component.params['startType'] not in ["time (s)", "frame N"] or component.params['stopType'] not in ["time (s)", "frame N"]): return start = {'type': component.params['startType'].val, 'val' : component.params['startVal'].val} stop = {'type': component.params['stopType'].val, 'val' : component.params['stopVal'].val} # Check for string / variable if not all([testFloat(start['val']), testFloat(stop['val'])]): return if [start['type'], stop['type']] == ["time (s)", "time (s)"]: if float(start['val']) > float(stop['val']): alert(4105, component, {'type': 'time'}) if [start['type'], stop['type']] == ["frame N", "frame N"]: if int(float(start['val'])) > int(float(stop['val'].strip())): alert(4105, component, {'type': 'frame'})
def testFramesAsInt(component): """ Test whole numbers are used for frames. """ if "startType" not in component.params or "stopType" not in component.params: return startVal = component.params['startVal'].val stopVal = component.params['stopVal'].val if testFloat(startVal): if component.params['startType'] in ["frame N", "duration (frames)"]: # Test frames are whole numbers if not float.is_integer(float(startVal)): alert(4115, component, { 'type': 'start', 'frameType': component.params['startType'] }) if testFloat(stopVal): if component.params['stopType'] in ["frame N", "duration (frames)"]: # Test frames are whole numbers if not float.is_integer(float(stopVal)): alert(4115, component, { 'type': 'stop', 'frameType': component.params['stopType'] })
def checkPythonSyntax(component, tab): """ Checks each Python code component tabs for syntax errors. Note, catalogue message is formatted using a dict that contains: { 'codeTab': The code component tab as string, 'code': The code containing the error, 'lineNumber': The line number of error as string } Parameters ---------- component: Component The code component being tested tab: str The name of the code component tab being tested """ try: compile(str(component.params[tab].val), "path", 'exec') except Exception as err: strFields = { 'codeTab': tab, 'lineNumber': err.lineno, 'code': err.text } # Dont sent traceback because strFields gives better localisation of error alert(4205, component, strFields)
def testStartEndTiming(component): """ Tests stimuli starts before end time. Parameters ---------- component: Component The component used for size testing """ if "startType" not in component.params or "stopType" not in component.params : return if (component.params['startType'] not in ["time (s)", "frame N"] or component.params['stopType'] not in ["time (s)", "frame N"]): return start = {'type': component.params['startType'].val, 'val' : component.params['startVal'].val} stop = {'type': component.params['stopType'].val, 'val' : component.params['stopVal'].val} try: float(start['val']) float(stop['val']) except Exception: # Conversion to float fails - probably a variable return if [start['type'], stop['type']] == ["time (s)", "time (s)"]: if float(start['val']) > float(stop['val']): alert(4105, component, {'type': 'time'}) if [start['type'], stop['type']] == ["frame N", "frame N"]: if int(float(start['val'])) > int(float(stop['val'].strip())): alert(4105, component, {'type': 'frame'})
def test_errorhandler_flush(self): """Test flushing of alert to alertLog and clearing attributes""" alert(9999, self) assert (isinstance(sys.stderr.alerts[-1], AlertEntry)) sys.stderr.flush() assert (isinstance(alertLog[0], AlertEntry)) assert (sys.stderr.alerts == [])
def testFont(component): """ Tests whether font is stored locally or whether it needs to be retrieved from Google Fonts Parameters ---------- component: Component The component used for testing """ if 'font' in component.params: fontInfo = fontMGR.getFontsMatching(component.params['font'].val, fallback=False) if not fontInfo: alert(4320, strFields={'param': component.params['font']})
def testSize(component, win, units): """ Runs size testing for component Parameters ---------- component: Component The component used for size testing win : TestWin object Used for testing component size in bounds units : str` Screen units """ if 'size' not in component.params: return try: size = convertParamToPix(component.params['size'].val, win, units) except Exception: # Use of variables fails check return # Test X if size[0] > win.size[0]: alert(2115, component, {'dimension': 'X'}) # Test Y if size[1] > win.size[1]: alert(2115, component, {'dimension': 'Y'}) # Test if smaller than 1 pixel (X dimension) if size[0] < 1: alert(2120, component, {'dimension': 'X'}) # Test if smaller than 1 pixel (Y dimension) if size[1] < 1: alert(2120, component, {'dimension': 'Y'})
def testDisabled(component): """ Tests whether a component is enabled. Parameters ---------- component: Component The component used for testing """ if "disabled" not in component.params: return if component.params['disabled'].val: alert(4305, component)
def testAchievableVisualOnsetOffset(component): """Test whether start and end times are less than 1 screen refresh. """ if component.type not in ["Text", "Aperture", "Dots", "EnvGrating", "Form", "Grating", "Image", "Movie", "NoiseStim", "Polygon"]: return if "startType" not in component.params or "stopType" not in component.params: return startVal = component.params['startVal'].val stopVal = component.params['stopVal'].val if testFloat(startVal): if component.params['startType'] == "time (s)": # Test times are greater than 1 screen refresh for 60Hz and 100Hz monitors if not float.is_integer(float(startVal)) and float(startVal) < 1.0 / 60: alert(3110, component, {'type': 'start', 'time': startVal, 'Hz': 60}) if not float.is_integer(float(startVal)) and float(startVal) < 1.0 / 100: alert(3110, component, {'type': 'start', 'time': startVal, 'Hz': 100}) if testFloat(stopVal): if component.params['stopType'] == "duration (s)": # Test times are greater than 1 screen refresh for 60Hz and 100Hz monitors if not float.is_integer(float(stopVal)) and float(stopVal) < 1.0 / 60: alert(3110, component, {'type': 'stop', 'time': stopVal, 'Hz': 60}) if not float.is_integer(float(stopVal)) and float(stopVal) < 1.0 / 100: alert(3110, component, {'type': 'stop', 'time': stopVal, 'Hz': 100})
def testDollarSyntax(component): """ Tests that use of dollar signs in Builder components to denote literal interpretation are used correctly Parameters ---------- component: Component The component used for testing """ valid = {} for (key, param) in component.params.items(): if not param.dollarSyntax()[0]: alert(4315, strFields={'component': component, 'param': param}) return valid
def testValidVisualStimTiming(component): """Test whether visual stimuli presented accurately for times requested, relative to screen refresh rate of 60 and 100Hz monitors. """ if component.type not in ["Text", "Aperture", "Dots", "EnvGrating", "Form", "Grating", "Image", "Movie", "NoiseStim", "Polygon"]: return if "startType" not in component.params or "stopType" not in component.params: return startVal = component.params['startVal'].val stopVal = component.params['stopVal'].val if startVal not in ['', None, "None", "none"]: if component.params['startType'] == "time (s)": # Test times are valid multiples of screen refresh for 60Hz and 100Hz monitors if not float.is_integer(float(startVal)) and round(float(startVal) % (1.0 / 60), 3) != 0.0: alert(3115, component, {'type': 'start', 'time': startVal, 'Hz': 60}) if not float.is_integer(float(startVal)) and round(float(startVal) % (1.0 / 100), 3) != 0.0: alert(3115, component, {'type': 'start', 'time': startVal, 'Hz': 100}) if stopVal not in ['', None, "None", "none"]: if component.params['stopType'] == "duration (s)": # Test times are valid multiples of screen refresh for 60Hz and 100Hz monitors if not float.is_integer(float(stopVal)) and round(float(stopVal) % (1.0 / 60), 3) != 0.0: alert(3115, component, {'type': 'stop', 'time': stopVal, 'Hz': 60}) if not float.is_integer(float(stopVal)) and round(float(stopVal) % (1.0 / 100), 3) != 0.0: alert(3115, component, {'type': 'stop', 'time': stopVal, 'Hz': 100})
def checkJavaScriptSyntax(component, tab): """ Checks each JS code component tabs for syntax errors. Note, catalogue message is formatted using a dict that contains: { 'codeTab': The code component tab as string, 'lineNumber': The line number and error msg as string } Parameters ---------- component: Component The code component being tested tab: str The name of the code component tab being tested """ try: parseScript(str(component.params[tab].val)) except Exception as err: strFields = {'codeTab': tab, 'lineNumber': err.message} # Dont sent traceback because strFields gives better localisation of error alert(4210, component, strFields)
def test_alert_written_to_console(self, capsys): """Test alerts are written to console when no errorhandler exists""" _alerts.alert(9999, self, strFields={"testString": "TEST ALERT"}) out, err = capsys.readouterr() # Capture stdout stream and test assert ("TEST_MSG TEST ALERT" in err)
def test_errorhandler_receiveAlert(self): """Test flushing of alert to alertLog and clearing attributes""" alert(9999, self, {'testString': 'TEST MESSAGE'}) assert (isinstance(sys.stderr.alerts[-1], AlertEntry))