!******************************************************************************!
! Tests the ASSERT command.
!
! These test cases need to be done in a very specail manner in order to avoid messing up the
! normal ASSERT counting. To do this, "call runTests" is called ONCE and it is the ONLY place
! where ASSERT is used.
!
! All non-interactive sample test cases start with:
!  assert/ltext=60/debug=^{show}/text="    ..."
!
! All interactive sample test cases start with:
!  ASSERT
!
! All real test cases start with:
!  assert/text="^reg.main.name: ..."
!
! Author:  J. Czechowski IV
!******************************************************************************!
startmacro
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE
  switch DEBUGALL    show     GET DEF=FALSE SDEF=TRUE

  set L:exceptionCount 0
  set L:maxExceptions  1
  set T:exceptions     {1="Illegal logical test: 123"}

  call setDatDir


  if interAct then
    res inst "Should see the output from multiple tests:\n&
              \n&
              Test 1:\n - should say PASS\n&
              \n&
              Test 2:\n - should say FAIL\n&
              \n&
              Test 3:\n - no output for 'f.xstart EQ 0'\n &
                        - should say FAIL for 'f.xdelta EQ 999'\n &
                        - should say '[PASS=1 FAIL=1]' and FAIL\n &
              \n&
              Ignore any output below the line."

    pipe on
      panel/msgid=MAIN/setup/controls=gc
      gcontrol label  macro   "MACRO"
      gcontrol menu main "Exit with Status = " "PASS,FAIL" /tleft
      set gc.main.itemColors {PASS=GREEN,FAIL=RED}
      gcontrol text idtext "INSTRUCTIONS" "^inst" 24 24 /title

      ! shellgui/attach needs to be included in runTests
      call runTests
    pipe off

    switch DEBUG origDebug DEL
    %test_assert_os_prompt ! NXM-4107
  else
    call runTests
  endif
endmacro

!******************************************************************************!
procedure processMessage m:msg
  !say "msg.name ^msg.name, info ^msg.info, data ^msg.data"

  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: Tests for EXPLAIN" msg.data eqss "PASS"
    pipe stop
  else
    say "^reg.main.name: Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
return

!******************************************************************************!
procedure processException m:emsg
  !say "emsg.name ^emsg.name, info ^emsg.info, data ^emsg.data"
  calc L:exceptionCount exceptionCount 1 +
  if exceptionCount <= maxExceptions AND "^{exceptions.^{exceptionCount}}" subs "^{emsg.data}" then
    !info "Caught expected exception: ^emsg.data" ! <-- Can not use assert here
  else
    error "Caught unexpected exception: ^emsg.data" ! <-- Can not use assert here
    calc L:exceptionCount exceptionCount 1000 +set  ! <-- Make it invalid so we can catch later
  endif
return

!******************************************************************************!
! Set the dat directory
!******************************************************************************!
procedure setDatDir
  invoke nxmMajor env.nmversion.subString(0,1)
  invoke major java.lang.Integer.valueOf(nxmMajor)
  if major GE 4 then
    invoke s:datDir           nxm.sys.test.DatLocator.getDatDirLocation()
    invoke s:datDirSlash      nxm.sys.test.DatLocator.getDatDirSlashLocation()
    invoke z:sysDatFull       nxm.sys.test.DatLocator.sysDatFull()
    invoke z:sysTestDatExists nxm.sys.test.DatLocator.sysTestDatExists()
  else
    set s:datDir           "nxm.sys.dat"
    set s:datDirSlash      "nxm/sys/dat"
    set z:sysDatFull       true
    set z:sysTestDatExists false
  endif
return

!******************************************************************************!
! Some basic test cases, tests accounting
procedure runTests
  set L:exceptionCount 0
  set L:maxExceptions  1
  set T:exceptions     {1="Illegal logical test: 123"}
  set hidefail TEST(show,isFalse)  ! need to negate this for /hidefail= switch

  ! ==== START SAMPLE TEST CASES
  ! need to clear any "stale" test counts
  assert/ltext=60/debug=^{show}/text="    Test set 0"/total="RESET"/label="TEST0"

  ! ------ BASIC TESTS (test set 1)
  assert/ltext=60/debug=^{show}/text="    assert 123 eq  123" 123 eq  123             /stat=passTest ! <-- PASS
  assert/ltext=60/debug=^{show}/text="    assert 123 neq 123 (Forced FAIL for testing)" 123 neq 123  /stat=failTest /HIDEFAIL=^{hidefail} ! <-- FAIL
  assert/ltext=60/debug=^{show}/text="    Test /NOOP='MISS'"             /noop="MISS" /stat=missTest ! <-- MISS
  assert/ltext=60/debug=^{show}/text="    Test /NOOP='QRST'"             /noop="QRST" /stat=qrstTest ! <-- QRST (noop)
  assert/ltext=60/debug=^{show}/text="    Test /NOOP='NOOP'"             /noop=""     /stat=noopTest ! <-- N/A (noop)

  assert/ltext=60/debug=^{show}/text="    Test set 1"/total="RESET"/label="TEST1"

  ! ------ ALL PASS (test set 2)
  assert/ltext=60/debug=^{show}/text="    assert 123 eq 123" 123 eq  123
  assert/ltext=60/debug=^{show}/text="    assert 123 eq 3.1" 123 neq 3.1

  assert/ltext=60/debug=^{show}/text="    Test set 2"/total="RESET"/label="TEST2"

  ! ------ INVALID INPUT (test set 3)
  assert/ltext=60/debug=^{show}/text="    invalid test case" eq  123 ! <-- Invalid, throws "Illegal logical test: 123" exception

  assert/ltext=60/debug=^{show}/text="    Test set 3"/total="RESET"/label="TEST3"

  ! ------ /GROUP= AND /SUMMARY (test set 4)
  res t:myTestGroup {TEXT="Tests for apenny.prm"}
  file open f ^{datDir}.apenny.prm
    assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/label="TEST4"/group=myTestGroup/test f.xstart EQ 0
    assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/label="TEST4"/group=myTestGroup/test f.xdelta EQ 999
    assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/label="TEST4"/group=myTestGroup/test f.ystart EQ 123 /NOOP="MISS"
    assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/label="TEST4"/group=myTestGroup/test f.ydelta EQ 456 /NOOP="SKIP"
  file close f
  assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/label="TEST4"/group=myTestGroup/summary
  assert/ltext=60/debug=^{show}/HIDEFAIL=^{hidefail}/text="    Test set 4"/total="RESET"/label="TEST4"

  ! ------ INTERACTIVE TESTS (test set 5)
  if interAct then
    shellgui/id=idshellgui/attach
    say ""
    ! 2012-06-01: Remove /DEBUG=0 (false) switch for when running via CONFIDENCE/baseline.
    !             So that /DEBUG=true will force the results of the test to be displayed
    switch DEBUG origDebug DEL

    say   "nM> ASSERT/TEXT='Test 1' 123 EQ 123"
    ASSERT/DEBUG=true/TEXT="Test 1" 123 EQ 123
    say   "nM> ASSERT/TEXT='Test 2' 123 EQ 456"
    ASSERT/DEBUG=true/TEXT="Test 2" 123 EQ 456
    say ""
    say ""

    say "nM> RES T:myTestGroup {TEXT=Tests for apenny.prm}"
    res t:myTestGroup {TEXT="Test 3"}
    file open f ^{datDir}.apenny.prm
      say "nM> ASSERT/DEBUG=TRUE/GROUP=myTestGroup/TEST f.xstart EQ 0"
      ASSERT/DEBUG=NULL/GROUP=myTestGroup/test f.xstart EQ 0
      say "nM> ASSERT/DEBUG=TRUE/GROUP=myTestGroup/TEST f.xdelta EQ 999"
      ASSERT/DEBUG=TRUE/GROUP=myTestGroup/test f.xdelta EQ 999
    file close f
    say "nM> ASSERT/DEBUG=TRUE/GROUP=myTestGroup/SUMMARY"
    ASSERT/DEBUG=TRUE/GROUP=myTestGroup/SUMMARY
    
    if origDebug nIsNull then
      ! 2012-06-01: restore original /DEBUG switch value if it was set
      switch DEBUG origDebug SET
    endif

    say "========================================================="
    say "INTERACTIVE TESTS ARE ABOVE THIS LINE"
    say "========================================================="
  endif
  assert/ltext=60/debug=^{show}/text="    Test set 4"/total="RESET"/label="TEST5"

  ! ==== DONE SAMPLE TEST CASES
  ! ------ BASIC TESTS (test set 1)
  assert/text="^reg.main.name: Check for /STAT= with PASS" passTest eqs "PASS"
  assert/text="^reg.main.name: Check for /STAT= with FAIL" failTest eqs "FAIL"
  assert/text="^reg.main.name: Check for /STAT= with N/A"  missTest eqs "N/A"
  assert/text="^reg.main.name: Check for /STAT= with N/A"  qrstTest eqs "N/A"
  assert/text="^reg.main.name: Check for /STAT= with N/A"  noopTest eqs "N/A"

  assert/text="^reg.main.name: Test set 1 total for MSG"        TEST1.MSG        eqs "FAILED SOME TESTS"
  assert/text="^reg.main.name: Test set 1 total for STATUS"     TEST1.STATUS     eq -1
  assert/text="^reg.main.name: Test set 1 total for TEST_COUNT" TEST1.TEST_COUNT == 5
  assert/text="^reg.main.name: Test set 1 total for PASS_COUNT" TEST1.PASS_COUNT == 1
  assert/text="^reg.main.name: Test set 1 total for FAIL_COUNT" TEST1.FAIL_COUNT == 1
  assert/text="^reg.main.name: Test set 1 total for MISS_COUNT" TEST1.MISS_COUNT == 1
  assert/text="^reg.main.name: Test set 1 total for NOOP_COUNT" TEST1.NOOP_COUNT == 2

  ! ------ ALL PASS (test set 2)
  assert/text="^reg.main.name: Test set 2 total for MSG"        TEST2.MSG        eqs "PASSED ALL TESTS"
  assert/text="^reg.main.name: Test set 2 total for STATUS"     TEST2.STATUS     eq 1
  assert/text="^reg.main.name: Test set 2 total for TEST_COUNT" TEST2.TEST_COUNT == 2
  assert/text="^reg.main.name: Test set 2 total for PASS_COUNT" TEST2.PASS_COUNT == 2
  assert/text="^reg.main.name: Test set 2 total for FAIL_COUNT" TEST2.FAIL_COUNT == 0
  assert/text="^reg.main.name: Test set 2 total for MISS_COUNT" TEST2.MISS_COUNT == 0
  assert/text="^reg.main.name: Test set 2 total for NOOP_COUNT" TEST2.NOOP_COUNT == 0

  ! ------ INVALID INPUT (test set 3)
  assert/text="^reg.main.name: Test set 3 caught expected exceptions" exceptionCount eq maxExceptions

  ! ------ /GROUP TESTS (test set 4)
  assert/text="^reg.main.name: Test set 4 total for MSG"        TEST4.MSG        eqs "FAILED SOME TESTS"
  assert/text="^reg.main.name: Test set 4 total for STATUS"     TEST4.STATUS     eq -1
  assert/text="^reg.main.name: Test set 4 total for TEST_COUNT" TEST4.TEST_COUNT == 5
  assert/text="^reg.main.name: Test set 4 total for PASS_COUNT" TEST4.PASS_COUNT == 1
  assert/text="^reg.main.name: Test set 4 total for FAIL_COUNT" TEST4.FAIL_COUNT == 2
  assert/text="^reg.main.name: Test set 4 total for MISS_COUNT" TEST4.MISS_COUNT == 1
  assert/text="^reg.main.name: Test set 4 total for NOOP_COUNT" TEST4.NOOP_COUNT == 1

return
