! Test for the INVOKE intrinsic
!
! @author  J. Czechowski IV / J. Hallam / John Marsh / Neon Ngo
! @version $Id: test_invoke.mm,v 1.11 2012/08/28 12:25:22 jwb Exp $
!
startmacro
  result eFlag 0

  call basicTests
  call parserTests
  call singleArgTests
  call multiArgTests
  call testDR1441
  call testDR1640
  call testDR2092
endmacro

!**************************************************************************************************!
procedure basicTests
!
! Basic tests added before NeXtMidas 2.1.3
!
  ! Call a static method in Shell from the registry
  result answer "^env.nmroot"
  remove str
  invoke str reg.shell.getnmroot
  assert/text="^reg.main.name: STATIC method: reg.shell.getnmroot" str EQS answer

  !...same as above but with a shorthand syntax
  remove str
  invoke str shell.nmroot
  assert/text="^reg.main.name: STATIC method: shell.nmroot" str EQS answer

  ! Get a static variable (PI) from Java
  result D:answer 3.141592653589793
  invoke D:pi java.lang.Math.pi
  assert/text="^reg.main.name: STATIC method: java.lang.Math.pi" pi EQ answer

  ! ..use PI in a call to a static method Java
  result D:answer 0.0
  remove dval
  invoke D:dval java.lang.Math.sin(pi)
  assert/text="^reg.main.name: STATIC method: java.lang.Math.sin(pi)" dval LT 1e-15

  ! Test a quoted, comma separated string
  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","X|Y",2)
  assert/text="^reg.main.name: nxm.sys.lib.KeyObject.mask w/ QUOTED COMMA arg" &
        maskVal EQ 3

  ! Parser.mask DEFAULT
  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","X|Z",2)
  assert/text="^reg.main.name: nxm.sys.lib.Parser.mask X|Z" maskVal EQ 5

  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","DEF",2)
  assert/text="^reg.main.name: nxm.sys.lib.Parser.mask DEF" maskVal EQ 2

  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","DEFAULT",2)
  assert/text="^reg.main.name: nxm.sys.lib.Parser.mask DEFAULT" maskVal EQ 2

  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","ALL",2)
  assert/text="^reg.main.name: nxm.sys.lib.Parser.mask ALL" maskVal EQ 7

  invoke L:maskVal nxm.sys.lib.Parser.mask("X,Y,Z","NONE",2)
  assert/text="^reg.main.name: nxm.sys.lib.Parser.mask NONE" maskVal EQ 0

  ! JC4: This next test added in NeXtMidas 2.1.0
  invoke newInteger java.lang.Integer.<init>(4)
  assert/text="^reg.main.name: Constructor for java.lang.Integer(4)" &
           "^{newInteger.class}" eqs "class java.lang.Integer" and ^newInteger eq 4

return

!**************************************************************************************************!
procedure parserTests
!
! Basic tests added to test Bug 458 / DR 500867-5 (INVOKE: Parsing needs to be fixed)
!
  ! checkMalformed is turned off so that the String is not converted to Table form (i.e. {A=L:1,B=L:2} )
  TABLE ,, GETDEFAULTFLAGS test_origTblDef    ! keep track of orginal settings
  env set DEFAULTTABLEFLAGS -checkMalformed   ! turn off checkMalformed (since 3.3.0 - Bug 85)
  
  ! Parsing tables...
  res t:tbl {A=1,b=2}
  invoke tblStr1 nxm.sys.lib.StringUtil.toString(tbl)       ! Works in 2.1.2
  invoke tblStr2 nxm.sys.lib.StringUtil.toString({A=1,b=2}) ! Fails in 2.1.2

  assert/text="^reg.main.name: Correctly called StringUtil.toString(tbl)"       tblStr1 eqs "{A=1,B=2}"
  assert/text="^reg.main.name: Correctly called StringUtil.toString({A=1,b=2})" tblStr2 eqs "{A=1,B=2}"

  ! restore Table settings
  env set DEFAULTTABLEFLAGS ^test_origTblDef

  ! Parsing with extra white space...
  invoke str1 nxm.sys.lib.StringUtil.toString(ABC)     ! Works in 2.1.2
  invoke str2 nxm.sys.lib.StringUtil.toString("ABC")   ! Works in 2.1.2
  invoke str3 nxm.sys.lib.StringUtil.toString( "ABC" ) ! Fails in 2.1.2
  invoke str4 nxm.sys.lib.StringUtil.toString(  "ABC") ! Fails in 2.1.2
  invoke str5 nxm.sys.lib.StringUtil.toString("ABC"  ) ! Fails in 2.1.2

  assert/text="^reg.main.name: Correctly called StringUtil.toString(ABC)"     str1 eqs ""ABC""
  assert/text="^reg.main.name: Correctly called StringUtil.toString('ABC')"   str2 eqs ""ABC""
  assert/text="^reg.main.name: Correctly called StringUtil.toString( 'ABC' )" str3 eqs ""ABC""
  assert/text="^reg.main.name: Correctly called StringUtil.toString(  'ABC')" str4 eqs ""ABC""
  assert/text="^reg.main.name: Correctly called StringUtil.toString('ABC'  )" str5 eqs ""ABC""

return

!**************************************************************************************************!
procedure singleArgTests
!
! In NeXtMidas 2.5.0, added ability to use a single argument (for void return methods)
!
  ! Given a return value not named LABEL or FUNC, make sure it is set
  ! with res=func syntax
  remove maskVal0 ! Make sure the result is not already there
  invoke L:maskVal0=nxm.sys.lib.Parser.mask("X,Y,Z","NONE",2)
  assert/text="^reg.main.name: SINGLE ARGUMENT ( maskVal0=... )" maskVal0 EQ 0

  ! Make sure the original LABEL=, FUNC= tags for single args are treated as results in
  ! single argument mode
  remove label func ! Make sure results do not exist
  result D:answer 3.141592653589793
  invoke D:LABEL=java.lang.Math.pi
  assert/text="^reg.main.name: SINGLE ARGUMENT - LABEL=..." LABEL EQ answer
  invoke D:FUNC=java.lang.Math.pi
  assert/text="^reg.main.name: SINGLE ARGUMENT - FUNC=..." FUNC EQ answer

  ! Make sure I can use a single argument positionally
  new nxm.sys.lib.DataFile dfRef
  invoke dfRef.setSize(100)
  assert/text="^reg.main.name: SINGLE ARGUMENT - POSITIONAL" dfRef.getSize() EQ 100

return

!**************************************************************************************************!
procedure multiArgTests
! In NeXtMidas 2.5.0, added ability to use multiple res=func() arguments
!
  remove maskVal0 maskVal7 ! Make sure the results are not already there
  invoke L:maskVal0=nxm.sys.lib.Parser.mask("X,Y,Z","NONE",2) &
         L:maskVal7=nxm.sys.lib.Parser.mask("X,Y,Z","ALL",2)

  assert/text="^reg.main.name: MULTIPLE ARGS ( res1=func1() res2=func2() )" maskVal0 EQ 0 AND &
                                                                            maskVal7 EQ 7

return

!**************************************************************************************************!
procedure testDR1441
! Bug 1441 fix changes exception for invoking ImageFile.readImage on an unopened
! file from NULL pointer exception to a MidasException with a helpful message
!
  result eFlag 1441
  new nxm.sys.lib.ImageFile iFile
  invoke iFile.readImage()

  assert/text="^reg.main.name: INVOKE exception (DR 1441)" eFlag EQ 0

return

!**************************************************************************************************!
procedure testDR1640
! Bug 1640 fix changes exception for invoking with a semi-colon at end
!
  result eFlag 1640
  results x 1.0
  invoke  y x.getFormat();

  assert/text="^reg.main.name: INVOKE with semi-colon at end (DR 1640) got error" eFlag EQ 0

return

!**************************************************************************************************!
procedure testDR2092
! Bug 2092 Invoke and result return different values for Table getSize
!
  set t:tab {x=2}
  res    sizeViaRes    tab.getsize
  invoke sizeViaInvoke tab.getSiZe()

  ! using eqs since, invoke returns NULL when it fails
  assert/text="^reg.main.name: invoke vs results for Table.getSize (DR 2092)" sizeViaRes eqs sizeViaInvoke
return

!**************************************************************************************************!
!
!   Trap exceptions during INVOKE testing, and ensure they correspond to
!   expected error conditions
!
procedure processException m:emsg

  if eFlag == 1441 then
    assert/text="DR1441: ImageFile.readImage INVOKEd before file is open" &
      "MidasException" SUBS ^emsg.data AND "has not been opened" SUBS ^emsg.data
  elseif eFlag == 1640 then
    assert/text="DR1640: INVOKE with semi-colon at end (friendly error message)" &
      "Missing closing right parenthesis" SUBS ^emsg.data
  else
    assert/text="UNEXPECTED INVOKE exception" false
  endif
  result eFlag 0

return
