! Tests calls to SUBROUTINE.
!
! Author:  Neon Ngo
! Version: $Id: test_subroutine.mm,v 1.6 2009/03/20 23:18:02 ntn Exp $
!
startmacro
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE

  res macro_res_s "Defined in MACRO"      ! string result
  res macro_res_t {a="^macro_res_s",b=2}  ! table result
  res exp_table   macro_res_t
  res macro_res_x 1.0                     ! numeric result
  res Z:exceptionExpected false ! only use to ignore Exceptions for Known DRs during testing

  ! santity check (pre conditions) to make sure sub_res_s, sub_res_x, and sub_str are NOT defined results
  assert/text="TEST_SUBROUTINE: PRECOND: sub_res_s, sub_res_x & sub_str NREXISTS" &
    sub_res_s NREXISTS AND sub_res_x NREXISTS AND sub_str NREXISTS

  call testsub macro_res_s macro_res_t macro_res_x

  ! test post conditions after call to subroutine
  assert/text="^{reg.main.name}: Subroutine scoped results NREXISTS" &
    sub_res_s NREXISTS AND sub_res_x NREXISTS AND sub_str NREXISTS
  assert/text="^{reg.main.name}: Pass by reference inner value was changed" macro_res_t.a NEQS macro_res_s
  assert/text="^{reg.main.name}: Macro results reference to table NOT changed " macro_res_t OEQ exp_table
  assert/text="^{reg.main.name}: Macro results NOT changed - string" macro_res_s EQS "Defined in MACRO"
  assert/text="^{reg.main.name}: Macro results NOT changed - double" macro_res_x EQ   1.0

  assert/text="^{reg.main.name}: Subroutine scoped parameters NREXISTS" &
    sub_param_s NREXISTS AND sub_param_t NREXISTS AND sub_param_x NREXISTS /NOOP="KnownDR"

  ! begin tests for Bug 1775 Can not call a SUBROUTINE from a SUBROUTINE more than once
  call secondsubtocall "1st" 1.1
  assert/text="^{reg.main.name}: Subroutine was called once" macro_res_x EQ 1.1
  call secondsubtocall "2nd" 2.2
  assert/text="^{reg.main.name}: Subroutine was called twice" macro_res_x EQ 2.2
  ! end tests for Bug 1775 Can not call a SUBROUTINE from a SUBROUTINE more than once

  !===== Tests calling subroutines in the background after calling them normally (Known Issue) ====
if baseline then
  res Z:exceptionExpected true   ! <---- TODO: remove this line and comment before endif, when we fix this KnownDR
  res timeTol 1.0   ! time to give subroutine to complete
  ! call subroutine in background in it's own thread
  call/bg secondsubtocall "4th (1st /bg)" 4.1
  pause timeTol
  assert/text="^{reg.main.name}: Backgrounded subroutine was called once" macro_res_x EQ 4.1  /NOOP="KnownDR"

  call/bg secondsubtocall "5th (2nd /bg)" 5.2
  pause timeTol
  assert/text="^{reg.main.name}: Backgrounded subroutine was called twice" macro_res_x EQ 5.2 /NOOP="KnownDR"
  !**** NTN: DON'T PUT ANYMORE TESTS AFTER THIS unless this KnownDR is fixed, put THEM above this if/endif block
endif

endmacro

! we should NOT get any exceptions (specifically "Subroutine already in use")
! for calling secondsubtocall subroutine
procedure processException m:emsg
  if exceptionExpected then
    assert/text="^reg.main.name: Exception ^{emsg.data}" "FALSE" /NOOP="KnownDR"
  else
    assert/text="^reg.main.name: Exception ^{emsg.data}" "FALSE"
  endif
!  invoke ,, this.M.printStackTrace(emsg.data)  ! DEBUG
return

! Tests access to registry from subroutine and its input parameters.
! Set some local scoped results variable (so that we can check that they DO NOT
! get put into macro's results table.
subroutine testsub s:sub_param_s t:sub_param_t d:sub_param_x
  ! create some locally scoped results (the main macro should NOT be able to see these)
  results sub_res_s "Defined in SUBROUTINE"
  results sub_res_x  2.0

  ! test access to registry from subroutine
  assert/text="TEST_SUBROUTINE: ACCESS TO REGISTRY" reg.main.name REXISTS

  ! Test for Known Bug 271 (Should not have read access to macro's results)
  assert/text="^{reg.main.name}: No access to macro scoped results string" macro_res_s NREXISTS /NOOP="KnownDR"
  ! TODO: enable next two lines once we fix Bug 271
  !assert/text="^{reg.main.name}: No access to macro scoped results table"  macro_res_t NREXISTS /NOOP="KnownDR"
  !assert/text="^{reg.main.name}: No access to macro scoped results double" macro_res_x NREXISTS /NOOP="KnownDR"

  ! test for read access to subroutine parameters
  assert/text="^{reg.main.name}: Read access to subroutine parameter - string" sub_param_s REXISTS
  assert/text="^{reg.main.name}: Read access to subroutine parameter - table"  sub_param_t REXISTS
  assert/text="^{reg.main.name}: Read access to subroutine parameter - double" sub_param_x REXISTS

  ! test for write access to subroutine parameters
  results sub_str     "Changed in Subroutine"
  results sub_param_s   sub_str
  results sub_param_t.a sub_str   ! <--- pass by reference, so macro_res_t.x should be updated
  results sub_param_x 999
  assert/text="^{reg.main.name}: Write access to subroutine parameter - string" sub_param_s   EQS sub_str
  assert/text="^{reg.main.name}: Write access to subroutine parameter - table"  sub_param_t.a EQS sub_str
  assert/text="^{reg.main.name}: Write accces to subroutine parameter - double" sub_param_x   EQ  999

  ! local scoped results with same name as macro's results SHOULD NOT change macro's results
  results macro_res_x 888
  results macro_res_s ^sub_str
  results macro_res_t {s="^sub_str"}
return

! subroutine to be call after first one to test that we can call multiple
! subroutines from here. It will also change macr_res_x via results/parent
! so that we can verify in the main macro that this subroutine was called
! @bug 1775 Can not call a SUBROUTINE from a SUBROUTINE more than once
subroutine secondsubtocall s:nthcall d:newval_x
  assert/text="^{reg.main.name}: Subroutine called ^{nthcall} time" TRUE
  results/parent macro_res_x d:newval_x
  call sub_called_in_another_sub "1 (^{nthcall})" -1.1
  assert/text="^{reg.main.name}: Sub-Subroutine was called once (^{nthcall})"  sub_res_y EQ -1.1
  call sub_called_in_another_sub "2 (^{nthcall})" -2.2
  assert/text="^{reg.main.name}: Sub-Subroutine was called twice (^{nthcall})" sub_res_y EQ -2.2
return

! subroutine to be call by another subroutine (secondsubtocall).
! It change sub_res_y via results/parent so that we can verify in
! the calling subroutine (parent) that this sub-subroutine was called
! @bug 1775 Can not call a SUBROUTINE from a SUBROUTINE more than once
subroutine sub_called_in_another_sub s:subnote d:newval_y
  assert/text="^{reg.main.name}: Subroutine called within another subroutine ^{subnote}" TRUE
  results/parent sub_res_y newval_y
return
