< Summary - Igor Pro Universal Testing Framework

Information
Class: procedures.igortest-reporting
Assembly: procedures
File(s): /builds/mirror/igortest/procedures/igortest-reporting.ipf
Tag: 74147b3
Line coverage
85%
Covered lines: 274
Uncovered lines: 45
Coverable lines: 319
Total lines: 617
Line coverage: 85.8%
Branch coverage
69%
Covered branches: 39
Total branches: 56
Branch coverage: 69.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/mirror/igortest/procedures/igortest-reporting.ipf

#LineLine coverage
 1#pragma rtGlobals=3
 2#pragma TextEncoding="UTF-8"
 3#pragma rtFunctionErrors=1
 4#pragma version=1.10
 5#pragma ModuleName=IUTF_Reporting
 6
 7static Constant IP8_PRINTF_STR_MAX_LENGTH = 2400
 8
 9/// @brief Get the current time in seconds since the start of the computer. This conversion is
 10/// required as the time has to be stored in a TextGrid later.
 24511static Function/S GetTimeString()
 24512  string msg
 13
 24514  sprintf msg, "%.6f", StopMSTimer(-2) * IUTF_MICRO_TO_ONE
 24515  return msg
 24516End
 17
 18/// @brief Set parentWave[%CURRENT][%CHILD_END] to the length of the child wave. This is recommended
 19/// to do after a row is added to the child wave or a new entry in the parent wave is created.
 20///
 21/// @param parentWave   the parent wave to update
 22/// @param childWave    the child wave to get the length
 23/// @param init         [optional, default 0] if set to non zero this will also set
 24///                     parentWave[%CURRENT][%CHILD_START] to the length of the child wave.
 25125static Function UpdateChildRange(parentWave, childWave, [init])
 26  WAVE/T parentWave, childWave
 27  variable init
 28
 25129  variable length = IUTF_Utils_Vector#GetLength(childWave)
 30
 25131  init = ParamIsDefault(init) ? 0 : !!init
 32
 25133  if(init)
 12334    parentWave[%CURRENT][%CHILD_START] = num2istr(length)
 25135  endif
 25136  parentWave[%CURRENT][%CHILD_END] = num2istr(length)
 25137End
 38
 39/// @brief Get the results wave for the whole test run. This wave contains the following column
 40/// dimension labels:
 41///   - HOSTNAME: the name of the computer
 42///   - USERNAME: the username for which Igor is run
 43///   - STARTTIME: time in seconds (since since computer start) when this test run was started
 44///   - ENDTIME: time in seconds (since since computer start) when this test run was finished. Empty
 45///     if still running.
 46///   - NUM_ERROR: number of failed test cases
 47///   - NUM_SKIPPED: number of skipped test cases
 48///   - NUM_TESTS: number of test cases
 49///   - NUM_ASSERT: number of called assertions in all test cases
 50///   - NUM_ASSERT_ERROR: number of failed or errored assertions in all test cases
 51///   - SYSTEMINFO: information of the current system
 52///   - IGORINFO: information of the current igor instance
 53///   - VERSION: version number of the used IUTF
 54///   - EXPERIMENT: name of the experiment file
 55///   - CHILD_START: the start index (inclusive) for all test suites that belong to this test run
 56///   - CHILD_END: the end index (exclusive) for all test suites that belong to this test run
 57///
 58/// Warning: You have to initialize the TestRunWave with IUTF_Reporting_Control#SetupTestRun()
 59/// before its first usage. This should usually be done at the start of IUTF_Basics#RunTest() after
 60/// clearing the waves.
 21161static Function/WAVE GetTestRunWave()
 21162  DFREF    dfr  = GetPackageFolder()
 21163  string   name = "TestRunResult"
 21164  WAVE/Z/T wv   = dfr:$name
 21165  if(WaveExists(wv))
 20666    return wv
 567  endif
 68
 569  WAVE/T wv = IUTF_Utils_TextGrid#Create("HOSTNAME;USERNAME;STARTTIME;ENDTIME;NUM_ERROR;NUM_SKIPPED;NUM_TESTS;NUM_ASSERT
 570  MoveWave wv, dfr:$name
 71
 572  return wv
 21173End
 74
 75/// @brief Get the results wave for the test suites. This wave contains the following column
 76/// dimension labels:
 77///   - PROCEDURENAME: the name of the procedure file
 78///   - STARTTIME: time in seconds (since since computer start) when this test suite was started
 79///   - ENDTIME: time in seconds (since since computer start) when this test suite was finished.
 80///     Empty if still running.
 81///   - NUM_ERROR: number of failed test cases
 82///   - NUM_SKIPPED: number of skipped test cases
 83///   - NUM_TESTS: number of test cases
 84///   - NUM_ASSERT: number of called assertions in all test cases
 85///   - NUM_ASSERT_ERROR: number of failed or errored assertions in all test cases
 86///   - STDOUT: the copy of the output that was printed to the history during execution of this test
 87///     suite
 88///   - STDERR: the error messages that are collected during execution of this test suite
 89///   - CHILD_START: the start index (inclusive) for all test cases that belong to this test suite
 90///   - CHILD_END: the end index (exclusive) for all test cases that belong to this test suite
 37691static Function/WAVE GetTestSuiteWave()
 37692  DFREF    dfr  = GetPackageFolder()
 37693  string   name = "TestSuiteResult"
 37694  WAVE/Z/T wv   = dfr:$name
 37695  if(WaveExists(wv))
 36596    return wv
 1197  endif
 98
 1199  WAVE/T wv = IUTF_Utils_TextGrid#Create("PROCEDURENAME;STARTTIME;ENDTIME;NUM_ERROR;NUM_SKIPPED;NUM_TESTS;NUM_ASSERT;NUM
 11100  MoveWave wv, dfr:$name
 101
 11102  return wv
 376103End
 104
 105/// @brief Get the results wave for the test cases. This wave contains the following column
 106/// dimension labels:
 107///   - NAME: the full name of the testcase
 108///   - STARTTIME: time in seconds (since since computer start) when this test case was started
 109///   - ENDTIME: time in seconds (since since computer start) when this test case was finished.
 110///     Empty if still running.
 111///   - STATUS: The resulting status of this test case. Its one of IUTF_STATUS_UNKNOWN,
 112///     IUTF_STATUS_ERROR, IUTF_STATUS_FAIL, IUTF_STATUS_SKIP, IUTF_STATUS_SUCCESS or
 113///     IUTF_STATUS_RETRY.
 114///   - NUM_ASSERT: number of called assertions in this test case
 115///   - NUM_ASSERT_ERROR: number of failed or errored assertions in this test case
 116///   - STDOUT: the copy of the output that was printed to the history during execution of this test
 117///     case
 118///   - STDERR: the error messages that are collected during execution of this test case
 119///   - CHILD_START: the start index (inclusive) for all assertion that belong to this test case
 120///   - CHILD_END: the end index (exclusive) for all assertion that belong to this test case
 1133121static Function/WAVE GetTestCaseWave()
 1133122  DFREF    dfr  = GetPackageFolder()
 1133123  string   name = "TestCaseResult"
 1133124  WAVE/Z/T wv   = dfr:$name
 1133125  if(WaveExists(wv))
 1122126    return wv
 11127  endif
 128
 11129  WAVE/T wv = IUTF_Utils_TextGrid#Create("NAME;STARTTIME;ENDTIME;STATUS;NUM_ASSERT;NUM_ASSERT_ERROR;STDOUT;STDERR;CHILD_
 11130  MoveWave wv, dfr:$name
 131
 11132  return wv
 1133133End
 134
 135/// @brief Get the results wave for the test assertions. This wave contains the following column
 136/// dimension labels:
 137///   - MESSAGE: the full message of this assertion
 138///   - TYPE: the type of this assertion. Currently used are IUTF_STATUS_ERROR and IUTF_STATUS_FAIL.
 139///   - SEVERITY: the severity of this assertion. Currently used are IUTF_SEVERITY_WARN and
 140///     IUTF_SEVERITY_ERROR.
 141///   - STACKTRACE: the partial stack trace between the entry of the test case and the call of the
 142///     assertion
 143///   - CHILD_START: the start index (inclusive) for all information that belong to this assertion
 144///   - CHILD_END: the end index (exclusive) for all information that belong to this assertion
 185145static Function/WAVE GetTestAssertionWave()
 185146  DFREF    dfr  = GetPackageFolder()
 185147  string   name = "TestAssertionResult"
 185148  WAVE/Z/T wv   = dfr:$name
 185149  if(WaveExists(wv))
 174150    return wv
 11151  endif
 152
 11153  WAVE/T wv = IUTF_Utils_TextGrid#Create("MESSAGE;TYPE;SEVERITY;STACKTRACE;CHILD_START;CHILD_END;")
 11154  MoveWave wv, dfr:$name
 155
 11156  return wv
 185157End
 158
 159/// @brief Get the results wave for the test information. This wave contains the following column
 160/// dimension labels:
 161///   - MESSAGE: the full information text for the parent assertion
 15162static Function/WAVE GetTestInfoWave()
 15163  DFREF    dfr  = GetPackageFolder()
 15164  string   name = "TestInfoResult"
 15165  WAVE/Z/T wv   = dfr:$name
 15166  if(WaveExists(wv))
 5167    return wv
 10168  endif
 169
 10170  WAVE/T wv = IUTF_Utils_TextGrid#Create("MESSAGE;")
 10171  MoveWave wv, dfr:$name
 172
 10173  return wv
 15174End
 175
 5176static Function ClearTestResultWaves()
 5177  WAVE/T wvTestRun   = GetTestRunWave()
 5178  WAVE/T wvTestSuite = GetTestSuiteWave()
 5179  WAVE/T wvTestCase  = GetTestCaseWave()
 5180  WAVE/T wvAssertion = GetTestAssertionWave()
 5181  WAVE/T wvInfo      = GetTestInfoWave()
 182
 5183  KillWaves wvTestRun, wvTestSuite, wvTestCase, wvAssertion, wvInfo
 5184End
 185
 186/// @brief Add a failed assertion to the current test case.
 187/// @param message          The message to add to this assertion.
 188/// @param type             The type of failed assertion
 189/// @param incrErrorCounter [optional, default enabled] If set different to zero it  will increment
 190///                         the current assertion error counter of the current test case.
 5191static Function AddError(message, type, [incrErrorCounter])
 192  string message, type
 193  variable incrErrorCounter
 194
 5195  string msg
 5196  variable i, length, startIndex
 197
 5198  incrErrorCounter = ParamIsDefault(incrErrorCounter) ? 1 : !!incrErrorCounter
 199
 5200  WAVE/T wvAssertion = GetTestAssertionWave()
 5201  IUTF_Utils_Vector#AddRow(wvAssertion)
 5202  wvAssertion[%CURRENT][%MESSAGE]  = message
 5203  wvAssertion[%CURRENT][%TYPE]     = type
 5204  wvAssertion[%CURRENT][%SEVERITY] = SelectString(incrErrorCounter, IUTF_SEVERITY_WARN, IUTF_SEVERITY_ERROR)
 205
 5206  WAVE/T wvTestCase = GetTestCaseWave()
 5207  UpdateChildRange(wvTestCase, wvAssertion)
 5208  if(incrErrorCounter)
 0209    wvTestCase[%CURRENT][%STATUS]           = type
 0210    wvTestCase[%CURRENT][%NUM_ASSERT_ERROR] = num2istr(str2num(wvTestCase[%CURRENT][%NUM_ASSERT_ERROR]) + 1)
 5211  endif
 5212  if(!IUTF_Utils#IsEmpty(message))
 5213    wvTestCase[%CURRENT][%STDERR] = AddListItem(message, wvTestCase[%CURRENT][%STDERR], "\n", Inf)
 5214  endif
 215
 5216  WAVE/T wvInfo = GetTestInfoWave()
 5217  UpdateChildRange(wvAssertion, wvInfo, init = 1)
 218
 5219  WAVE/T wvInfoMsg = GetInfoMsg()
 5220  length = IUTF_Utils_Vector#GetLength(wvInfoMsg)
 5221  if(length > 0)
 5222    startIndex = IUTF_Utils_Vector#GetLength(wvInfo)
 5223    IUTF_Utils_Vector#AddRows(wvInfo, length)
 5224    UpdateChildRange(wvAssertion, wvInfo)
 5225    wvInfo[startIndex, startIndex + length - 1][%MESSAGE] = wvInfoMsg[p - startIndex]
 226
 5227    for(i = 0; i < length; i += 1)
 5228      msg                           = "  " + TC_ASSERTION_INFO_INDICATOR + " " + wvInfoMsg[i]
 5229      wvTestCase[%CURRENT][%STDERR] = AddListItem(msg, wvTestCase[%CURRENT][%STDERR], "\n", Inf)
 5230    endfor
 5231  endif
 5232End
 233
 234/// Increments the assertion counter for the current test case
 515235static Function incrAssert()
 515236  WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 515237  wvTestCase[%CURRENT][%NUM_ASSERT] = num2istr(str2num(wvTestCase[%CURRENT][%NUM_ASSERT]) + 1)
 515238End
 239
 240/// Increments the global error counter for the complete test run. This wont change the error
 241/// counter for test cases. Use AddError for these cases.
 0242static Function incrGlobalError()
 0243  WAVE/T wvTestRun = IUTF_Reporting#GetTestRunWave()
 0244  wvTestRun[%CURRENT][%NUM_ASSERT_ERROR] = num2istr(str2num(wvTestRun[%CURRENT][%NUM_ASSERT_ERROR]) + 1)
 0245End
 246
 247/// Get the wave that can store information for the next assertion. These wave is cleared
 248/// automatically at the end of the test case or assertion. This wave is considered as a list. Use
 249/// IUTF_Utils_Waves#GetListLength to retrieve its length.
 799250static Function/WAVE GetInfoMsg()
 799251  DFREF    dfr  = GetPackageFolder()
 799252  string   name = "InfoMsg"
 799253  WAVE/Z/T wv   = dfr:$name
 799254  if(WaveExists(wv))
 794255    return wv
 5256  endif
 257
 5258  MAKE/FREE/T/N=(IUTF_WAVECHUNK_SIZE) wv
 5259  IUTF_Utils_Vector#SetLength(wv, 0)
 5260  MoveWave wv, dfr:$name
 261
 5262  return wv
 799263End
 264
 265/// Clears all stored information for the next assertion. This will only update the length of the
 266/// list and not its contents.
 594267static Function CleanupInfoMsg()
 594268  WAVE/T wv = GetInfoMsg()
 269
 594270  IUTF_Utils_Vector#SetLength(wv, 0)
 594271End
 272
 273/// Get or create the wave that contains the failed procedures
 100274static Function/WAVE GetFailedProcWave()
 100275  string name = "FailedProcWave"
 276
 100277  DFREF    dfr = GetPackageFolder()
 100278  WAVE/Z/T wv  = dfr:$name
 100279  if(WaveExists(wv))
 95280    return wv
 5281  endif
 282
 5283  Make/T/N=(IUTF_WAVECHUNK_SIZE) dfr:$name/WAVE=wv
 5284  IUTF_Utils_Vector#SetLength(wv, 0)
 285
 5286  return wv
 100287End
 288
 289/// @brief Add msg to the failed summary. This list will be printed to the
 290///        history area to reference errors briefly.
 291///
 292/// @param msg  The message to add to list
 5293static Function AddFailedSummaryInfo(msg)
 294  string msg
 295
 5296  variable index
 5297  WAVE/T wvFailed = GetFailedProcWave()
 298
 5299  index = IUTF_Utils_Vector#GetLength(wvFailed)
 5300  IUTF_Utils_Vector#EnsureCapacity(wvFailed, index)
 5301  IUTF_Utils_Vector#SetLength(wvFailed, index + 1)
 5302  wvFailed[index] = msg
 5303End
 304
 305/// Make a test case fail. This method is intended to use outside the user code
 306/// of the test case as such as it won't look in the stack trace which assertion
 307/// triggered the error.
 308///
 309/// This method is a short version of
 310///   ReportResults(0, msg, OUTPUT_MESSAGE | INCREASE_ERROR)
 311/// without the stack trace detection and special handling of output.
 312///
 313/// @param message  The message to output to the history
 314/// @param summaryMsg (optional, default is message) The message to output in the summary at the
 315///                 end of the test run. If this parameter is omitted it will use message for the
 316///                 summary.
 317/// @param isFailure (optional, default disabled) If set to non zero this will be handled as a
 318///                 FAILURE instead an ERROR. This changes the following:
 319///                 - the test case status is set to IUTF_STATUS_FAIL
 320///                 - updateStatus is set to 0 in AddError
 321/// @param incrErrorCounter (optional, default enabled) Enabled if set to a value different to 0.
 322///                 Increases the assertion error counter for the current test case.
 5323static Function TestCaseFail(message, [summaryMsg, isFailure, incrErrorCounter])
 324  string message
 325  string summaryMsg
 326  variable isFailure, incrErrorCounter
 327
 5328  summaryMsg       = SelectString(ParamIsDefault(summaryMsg), summaryMsg, message)
 5329  isFailure        = ParamIsDefault(isFailure) ? 0 : !!isFailure
 5330  incrErrorCounter = ParamIsDefault(incrErrorCounter) ? 1 : !!incrErrorCounter
 331
 5332  AddError(message, SelectString(isFailure, IUTF_STATUS_ERROR, IUTF_STATUS_FAIL), incrErrorCounter = incrErrorCounter)
 333
 5334  // We are increasing the local error counter so there is no need to increase the global error
 5335  // counter.
 5336  ReportError(message, incrGlobalErrorCounter = 0)
 5337  ShowInfoMsg()
 338
 5339  AddFailedSummaryInfo(summaryMsg)
 5340End
 341
 342/// Prints message that was stored through the INFO assertion
 5343static Function ShowInfoMsg()
 344
 5345  variable i, length
 346
 5347  WAVE/T wvInfoMsg = GetInfoMsg()
 5348  length = IUTF_Utils_Vector#GetLength(wvInfoMsg)
 5349  for(i = 0; i < length; i += 1)
 5350    ReportError("  " + TC_ASSERTION_INFO_INDICATOR + " " + wvInfoMsg[i], incrGlobalErrorCounter = 0)
 5351  endfor
 5352End
 353
 354/// Prints an informative message that the test case failed
 355///
 356/// @param message          the fail message to print to the output
 357/// @param expectedFailure  if set to non zero the error will be considered as expected
 358/// @param incrErrorCounter if set to non zero the assertion error counter for the current test case
 359///                         will be updated. This setting is ignored if expectedFailure is set to
 360///                         non zero
 361/// @param callStack        [optional, default current callStack] Can be used to set the callStack
 362///                         to a previous recorded callStack (GetRTStackInfo(3)).
 5363static Function PrintFailInfo(message, expectedFailure, incrErrorCounter, [callStack])
 364  string message
 365  variable expectedFailure, incrErrorCounter
 366  string callStack
 367
 5368  string str, partialStack
 5369  string prefix = SelectString(expectedFailure, "", "Expected Failure: ")
 370
 5371  if(ParamIsDefault(callStack))
 5372    str = getInfo(0, partialStack)
 0373  else
 0374    str = getInfo(0, partialStack, callStack = callStack)
 5375  endif
 5376  message = prefix + message + " " + str
 377
 5378  TestCaseFail(message, summaryMsg = str, isFailure = 1, incrErrorCounter = incrErrorCounter)
 379
 5380  if(!expectedFailure)
 5381    WAVE/T wvAssertion = GetTestAssertionWave()
 5382    wvAssertion[%CURRENT][%STACKTRACE] = partialStack
 5383  endif
 5384End
 385
 386/// @brief returns the informative message about the assertions state and location.
 387///
 388/// @param result            Assertion states: 0 failed, 1 succeeded
 389/// @param[out] partialStack The partial stacktrace between the entry of the test case and the call
 390///                          of the assertion.
 391/// @param callStack         [optional, default current callStack] Can be used to set the callStack
 392///                          to a previous recorded callStack (GetRTStackInfo(3)).
 393///
 394/// @returns The informative message
 5395static Function/S getInfo(result, partialStack, [callStack])
 396  variable result
 397  string  &partialStack
 398  string   callStack
 399
 5400  string caller, func, procedure, contents, moduleName
 5401  string text, cleanText, line, callerTestCase, tmpStr
 5402  variable numCallers, i, assertLine, err
 5403  variable callerIndex = NaN
 5404  variable testCaseIndex
 405
 5406  callStack    = SelectString(ParamIsDefault(callStack), callStack, GetRTStackInfo(3))
 5407  numCallers   = ItemsInList(callStack)
 5408  moduleName   = ""
 5409  partialStack = ""
 410
 5411  // traverse the callstack from bottom up,
 5412  // the first function not in one of the igortest procedures is
 5413  // the one we want to report. Except if helper functions are involved.
 5414  for(i = numCallers - 1; i >= 0; i -= 1)
 40415    caller    = StringFromList(i, callStack)
 40416    procedure = StringFromList(1, caller, ",")
 417
 40418    if(StringMatch(procedure, "igortest*"))
 35419      if(IUTF_Utils#IsNaN(callerIndex))
 30420        continue
 5421      endif
 5422      testCaseIndex = i + 1
 5423      break
 5424    else
 5425      if(IUTF_Utils#IsNaN(callerIndex))
 5426        callerIndex = i
 5427      endif
 5428    endif
 5429  endfor
 430
 5431  if(IUTF_Utils#IsNaN(callerIndex))
 0432    WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 0433    if(str2num(wvTestCase[%CURRENT][%NUM_ASSERT]) == 0)
 0434      // We have no external caller, assuming the internal call was the check in AfterTestCase()
 0435      return "The test case did not make any assertions!"
 0436    else
 0437      // We have no external caller, but a test case assertion - should never happen
 0438      return "Assertion failed in unknown location"
 0439    endif
 5440  endif
 441
 5442  callerTestCase = StringFromList(testCaseIndex, callStack)
 443
 5444  caller     = StringFromList(callerIndex, callStack)
 5445  func       = StringFromList(0, caller, ",")
 5446  procedure  = StringFromList(1, caller, ",")
 5447  line       = StringFromList(2, caller, ",")
 5448  assertLine = str2num(StringFromList(2, caller, ","))
 449
 5450  text = IUTF_Basics#getFullFunctionName(err, func, procedure)
 5451  if(!err)
 5452    func = text
 5453  endif
 454
 5455  if(callerIndex != testcaseIndex)
 0456    tmpStr = StringFromList(0, callerTestCase, ",")
 0457    text   = IUTF_Basics#getFullFunctionName(err, tmpStr, StringFromList(1, callerTestCase, ","))
 0458    if(!err)
 0459      tmpStr = text
 0460    endif
 461
 0462    func = tmpStr + TC_ASSERTION_MLINE_INDICATOR + func
 0463    line = StringFromList(2, callerTestCase, ",") + TC_ASSERTION_MLINE_INDICATOR + line
 5464  endif
 465
 5466  for(i = testcaseIndex; i <= callerIndex; i += 1)
 5467    partialStack = AddListItem(StringFromList(i, callStack), partialStack, ";", Inf)
 5468  endfor
 469
 5470  if(!IUTF_Basics#IsProcGlobal())
 0471    moduleName = " [" + GetIndependentModuleName() + "]"
 5472  endif
 473
 5474  contents = ProcedureText("", -1, procedure + moduleName)
 5475  text     = StringFromList(assertLine, contents, "\r")
 476
 5477  cleanText = trimstring(text)
 478
 5479  tmpStr = IUTF_Utils#IUTF_PrepareStringForOut(cleanText)
 5480  sprintf text, "Assertion \"%s\" %s in %s%s (%s, line %s)", tmpStr, SelectString(result, "failed", "succeeded"), func, 
 5481  return text
 5482End
 483
 484/// @brief Wrapper function result reporting. This functions should only be called for
 485///        assertions in user test cases. For internal errors use ReportError* functions.
 486///
 487/// @param result Return value of a check function from `igortest-assertion-checks.ipf`
 488/// @param str    Message string
 489/// @param flags  Wrapper function `flags` argument
 490/// @param cleanupInfo [optional, default enabled] If set different to zero it will cleanup
 491///               any assertion info message at the end of this function.
 492///               Cleanup is enforced if flags contains the ABORT_FUNCTION flag.
 493/// @param callStack [optional, default current callStack] Can be used to set the callStack
 494///               to a previous recorded callStack (GetRTStackInfo(3)).
 355495static Function ReportResults(result, str, flags, [cleanupInfo, callStack])
 496  variable result, flags
 497  string   str
 498  variable cleanupInfo
 499  string   callStack
 500
 355501  variable expectedFailure
 502
 355503  cleanupInfo = ParamIsDefault(cleanupInfo) ? 1 : !!cleanupInfo
 504
 355505  if(!result)
 506
 5507    str             = str + ": is false."
 5508    expectedFailure = IsExpectedFailure()
 509
 5510    if(flags & OUTPUT_MESSAGE)
 5511      if(ParamIsDefault(callStack))
 5512        PrintFailInfo(str, expectedFailure, flags & INCREASE_ERROR)
 0513      else
 0514        PrintFailInfo(str, expectedFailure, flags & INCREASE_ERROR, callStack = callStack)
 5515      endif
 5516    endif
 517
 5518    if(!expectedFailure && (flags & ABORT_FUNCTION))
 0519      IUTF_Reporting#CleanupInfoMsg()
 0520      IUTF_Basics#setAbortFlag()
 0521      Abort
 5522    endif
 355523  endif
 524
 355525  if(cleanupInfo)
 355526    IUTF_Reporting#CleanupInfoMsg()
 355527  endif
 355528End
 529
 530/// @brief Print the given message to the Igor history area and to stdout (IP8 only)
 531///
 532/// Always use this function if you want to inform the user about something.
 533///
 534/// @param msg message to be outputted, without trailing end-of-line
 535/// @param allowEmptyLine (optional, default 0 disabled) If set to 1 it will allow to print empty
 536///            strings to the output. The default behavior is to skip printing empty strings.
 271537threadsafe static Function IUTF_PrintStatusMessage(msg, [allowEmptyLine])
 538  string   msg
 539  variable allowEmptyLine
 540
 271541  string   tmpStr
 271542  variable len
 543
 271544  allowEmptyLine = ParamIsDefault(allowEmptyLine) ? 0 : !!allowEmptyLine
 545
 271546  // Copy of IUTF_Tracing#IsNull() and IUTF_Tracing#IsEmpty().
 271547  // These functions cannot be used here as in Igor <= 8.0 can no threadsafe function use another
 271548  // static threadsafe function with the full name when using Independent Modules.
 271549  len = strlen(msg)
 271550  if(!allowEmptyLine && (numtype(len) == 2 || len <= 0))
 0551    return NaN
 271552  endif
 553
 554#if (IgorVersion() >= 9.0)
 271555  printf "%s\r", msg
 556#elif (IgorVersion() >= 8.0)
 0557  print/LEN=2500 msg
 558#elif (IgorVersion() >= 7.0)
 0559  print/LEN=1000 msg
 560#elif (IgorVersion() >= 6.0)
 0561  print/LEN=400 msg
 562#endif
 563
 564#if (IgorVersion() >= 9.0)
 271565  fprintf -1, "%s\r\n", msg
 566#elif (IgorVersion() >= 8.0)
 0567  tmpStr = IUTF_PrepareStringForOut(msg, maxLen = IP8_PRINTF_STR_MAX_LENGTH - 2)
 0568  fprintf -1, "%s\r\n", tmpStr
 569#endif
 271570End
 571
 572/// @brief Reports an internal error.
 573/// The execution of the current testcase will NOT be aborted!
 574///
 575/// @param  message    The message to output to the history.
 576/// @param  incrGlobalErrorCounter (optional, default enabled) Enabled if set to a value different
 577///                     to 0. Increases the global error counter.
 10578static Function ReportError(message, [incrGlobalErrorCounter])
 579  string   message
 580  variable incrGlobalErrorCounter
 581
 10582  variable currentIndex
 583
 10584  incrGlobalErrorCounter = ParamIsDefault(incrGlobalErrorCounter) ? 1 : !!incrGlobalErrorCounter
 585
 10586  IUTF_PrintStatusMessage(message)
 587
 10588  WAVE/T wvTestCase = IUTF_Reporting#GetTestCaseWave()
 10589  currentIndex = FindDimLabel(wvTestCase, UTF_COLUMN, "CURRENT")
 10590  if(currentIndex >= 0)
 0591    wvTestCase[currentIndex][%STDERR] += message + "\r"
 10592  endif
 593
 10594  if(incrGlobalErrorCounter)
 0595    incrGlobalError()
 10596  endif
 10597End
 598
 599/// @brief Reports an internal error that prevents further execution of the current test case.
 600/// The current testcase is always aborted afterwards.
 601///
 602/// @param  message    The message to output to the history.
 603/// @param  setFlagOnly (optional, default: 0) If set to zero it will call abort at the end of
 604///                     the execution. If set to something different to zero it will only set
 605///                     the abort flag.
 0606static Function ReportErrorAndAbort(message, [setFlagOnly])
 607  string   message
 608  variable setFlagOnly
 609
 0610  setFlagOnly = ParamIsDefault(setFlagOnly) ? 0 : !!setFlagOnly
 611
 0612  ReportError("Fatal: " + message, incrGlobalErrorCounter = 1)
 0613  IUTF_Basics#setAbortFlag()
 0614  if(!setFlagOnly)
 0615    Abort
 0616  endif
 0617End