! Tests macro parsing and execution
!
! Author:  J. Czechowski IV
! Since:   NeXtMidas 2.3.0
startmacro

  call setDatDir
  invoke maxminExists reg.shell.M.dictionary.isDictionaryEntry(MAXMIN)

  set errors {BAD1="Unbalanced STARTMACRO/ENDMACRO block",&
              BAD2="PROCEDURE definition found inside STARTMACRO/ENDMACRO around line 12 text: procedure junk",&
              BAD3="Unbalanced STARTMACRO/ENDMACRO block",&
              BAD4="Duplicate STARTMACRO found before ENDMACRO around line 11 text: startmacro",&
              BAD5="Exception inside processException handler",&
              BAD_ELSE="Expected ELSEIF (no space): else,if,1,eq,1,then",&
              BAD_DO="Unclosed DO/ENDDO block",&
              BAD_FOREACH="Unclosed FOREACH/ENDFOR block",&
              BAD_LOOP="Unclosed LOOP/ENDLOOP block",&
              BAD_WHILE="Unclosed WHILE/ENDWHILE block",&
              NOTEST_IF="No test condition specified for IF statement around line 13",&
              NOTEST_IFTHEN="No test condition specified for IF statement around line 13",&
              NOTEST_ELSEIF="No test condition specified for ELSEIF statement around line 14",&
              NOTEST_ELSEIFTHEN="No test condition specified for ELSEIF statement around line 14",&
              NOTEST_WHILE="No test condition specified for WHILE statement around line 13"}

  %test_macro_bad_1
  %test_macro_bad_2
  %test_macro_bad_3
  %test_macro_bad_4
  %test_macro_bad_5
  %test_macro_bad_else          ! using "else if" in place of "elseif" (no space)
  %test_macro_bad_do            ! Missing ENDDO
  %test_macro_bad_foreach       ! Missing ENDFOR
  %test_macro_bad_loop          ! Missing ENDLOOP
  %test_macro_bad_while         ! Missing ENDWHILE
  %test_macro_notest_if         ! Missing test case with IF
  %test_macro_notest_ifthen     ! Missing test case with IF ... THEN
  %test_macro_notest_elseif     ! Missing test case with ELSEIF
  %test_macro_notest_elseifthen ! Missing test case with ELSEIF ... THEN
  %test_macro_notest_while      ! Missing test case with WHILE
  %test_macro_comments
  %test_macro_parsetext         ! Bug 2491 (Bang in the middle of text string)
  %test_macro_pipe_section      ! Bug 2725 (Can only run one pipe section per macro)
  %test_macro_parsing_defaults  ! Bug 2934 (Args: Incorrect parsing of percent macro defaults)
  %test_macro_parsing_defaults p5NoDefVal=5 /TESTNAMEPREFIX=" #2" /P5_VAL=5
  %test_macro_args              ! NXM-4063 Macros not handling variable number of arguments
  if maxminExists then call test_macro_arg_abbrev
  call test_null_table_argument
endmacro

procedure processException m:emsg
  set foundKey ""

  foreach key intable errors
    if "^emsg.data" eqs "nxm.sys.lib.MidasException: ^{errors.^{key}}" then
      set foundKey key
    endif
  endfor

  if foundKey eqs "" then
    assert/text="Got unexpected error: '^emsg.data'" false isTrue
  else
    assert/text="Caught: '^{errors.^{foundKey}}'" true isTrue
    rem errors.^{foundKey}
  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

! DR 1419
procedure test_macro_arg_abbrev
  ! Tags for MAXMIN are MAXOUT and MINOUT. Make sure they can be abbreviated
  maxmin ^{datDir}.apenny.prm max=max min=min
  assert/test=pass ^max eq 127.0
  assert/test=pass ^min eq -127.0
  ! Shorten, but do not make ambiguous (avoids warning) - since 3.7.3
  maxmin ^{datDir}.apenny.prm ma=mmm
  assert/test=pass ^mmm eq 127.0

  ! Make sure CM and CMAP do not collide
  nxm.sys.test.argabbrev PREFIX="ARGABBREV_" cmap="RED" cm="IMAG"
  assert/text="MACRO_PARSING: tag abbreviation CMAP then CM" &
                   ARGABBREV_CMAP EQS "RED" AND &
                   ARGABBREV_CM   EQS "IMAG"
  nxm.sys.test.argabbrev PREFIX="ARGABBREV_" cm="IMAG" cmap="RED"
  assert/text="MACRO_PARSING: tag abbreviation CM then CMAP" &
                   ARGABBREV_CMAP EQS "RED" AND &
                   ARGABBREV_CM   EQS "IMAG"
return

! Part of test case for BUG 696 (support for Java's null...) AND 1856 (Args.getTable(..) to ERROR on invalid table)
! At least user project returns a null for a configuration Table when operator clicks on cancel button.
! Since we don't support null directly (BUG 696), it is converted to the "NULL" string, which can cause
! call a procedure with that result to ERROR (BUG 1856) - so a minor change was made in Macro.java
! so that we DO NOT ERROR out on invalid tables inside Macro.argsToResults(..)
procedure test_null_table_argument
  set z:myProcedureCalled false
  ! NTN: one way to get a Java's null in the macro (as of NeXtMidas 2.7.1 it is still converted to a "NULL" string)
  invoke mynulltable this.args.getTable("NON_EXISTING_NAME_FOR_TEST")
  assert/text="^{reg.main.name}: got a null results" mynulltable isNULL
  call myproc_with_table_argument mynulltable
  assert/text="^{reg.main.name}: called procedure with null (Table) parameter" myProcedureCalled isTrue
return

! Part of test case for BUG 696 (support for Java's null) and 1856 (Args.getTable(..) to ERROR on invalid table)
! Only should be called by test_null_table_argument
procedure myproc_with_table_argument t:tab
  set z:myProcedureCalled true
  assert/text="^{reg.main.name}: calling procedure with null (Table) parameter isNull" tab isNULL
return
