!******************************************************************************!
! Tests the CALL intrinsic.
!
! Version: $Id: test_call.mm,v 1.9 2011/06/01 14:11:21 ntn Exp $
!******************************************************************************!
startmacro
  switch INTERACTIVE interAct GET DEF=TRUE  SDEF=TRUE  ! for normal interactive test(s)
  switch BASELINE    baseline GET DEF=FALSE SDEF=TRUE  ! for defects or more obscure test case(s)

  ! DR #926 -- Support for boolean
  set expectException ""
  set z:myTrue true
  set z:myFalse false
  call booleanProc myTrue myFalse

  global globalResult

  remove macroResult
  result macroResult "SUBROUTINE should not have access, PROCEDURE should"
  result myTable {ONE=1,TWO=2}
  call testScopeProc
  call testScopeSub myTable reg.main.name
  assert/text="^reg.main.name: SUBROUTINE pass by reference" myTable.TEN eq 10

  result answer "default"
  result text "^reg.main.name: call PROCEDURE with default"
  call myproc

  result answer "newString"
  result text "^reg.main.name: call PROCEDURE, override default"
  call myproc "^answer"

  result globalResult 1
  result test2 2

  ! have the procedure modify the results values
  call incBy10

  ! are the answers correct ?
  assert/text="^reg.main.name: incBy10 ^globalResult" globalResult eq 11
  assert/text="^reg.main.name: incBy10 ^test2" test2 eq 12

  ! have the procedure modify the results values again
  call incBy10

  assert/text="^reg.main.name: incBy10 ^globalResult" globalResult eq 21
  assert/text="^reg.main.name: incBy10 ^test2" test2 eq 22

  call test_passStringWithDefault

  remove/global globalResult test2

  ! Call a procedure that does not exist to get warning
  set expectException "DOES_NOT_EXIST"
  call doesNotExist
  set expectException "SUB_ALREADY_IN_USE"
  mess send MAIN,,CALLSUBROUTINE

  ! DR #926 -- Support for boolean
  set expectException ""
  set z:myTest true
  call booleanProc myTest

endmacro

!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: Can send messages from a SUBROUTINE" msg.data eqss "PASS"
    pipe stop
  elseif msg.name eqs "CALLSUBROUTINE" then
    call subCalledFromProcessMessage
  else
    say "^reg.main.name: Unhandled message name: ^msg.name data: ^msg.data"
  endif
return

!******************************************************************************!
procedure processException
  ! This is an expected exception with the name of the procedure in the error

  if expectException NEQS "" then
    if expectException EQS "DOES_NOT_EXIST" then
      assert/text="^reg.main.name: expect DOESNOTEXIST error for unknown procedure" &
            "DOESNOTEXIST" SUBS "^emsg.data"
    else
      assert/noop="KnownDR"/text="^reg.main.name: call subroutine from processMessage and get..."
      assert/noop=" "/text="  ... ^emsg.data"
    endif

  else  ! FAIL on unknown exception
    assert/text="^reg.main.name: exception ^emsg.data" "FALSE"
  endif
return

!******************************************************************************!
subroutine testScopeSub t:tbl s:mcrName
  assert/noop="KnownDR"/text="^reg.main.name: SUBROUTINEs should NOT see LOCAL macro results" macroResult NREXISTS
  assert/text="^reg.main.name: Parameter passed to SUBROUTINE" tbl.one REXISTS AND tbl.one eq 1
  assert/text="^reg.main.name: SUBROUTINE can see REGISTRY" reg.main.name eqs mcrName

  set tbl.ten 10
return

!******************************************************************************!
subroutine subCalledFromProcessMessage
  result resultSetInSubroutine "This is a result that should not be visible to entire macro"
return

!******************************************************************************!
procedure testScopeProc
  res text "^reg.main.name: PROCs should have access to LOCAL macro result"
  assert/text="^text" macroResult REXISTS
return

!******************************************************************************!
procedure myproc s:stringin["default"]
  assert/text="^text" stringin EQS "^answer"
return

!******************************************************************************!
procedure incBy10
!  Each time called, increment both variables by 10
  result globalResult globalResult+10
  result test2 test2+10
return

!******************************************************************************!
procedure test_passStringWithDefault &
           S:inStringQ["A23456789"]  &
           S:inStringUQ[A23456789]   &
           S:inStringQLC["abcdefg"]  &
           S:inStringUQLC[abcdefg]
!
!  Expect the quotes to be stripped off of the input string
!

result procStatus "PASS"
result testName "^reg.main.name: string DEFAULT: quoted UPPERCASE, = '^inStringQ'"
assert/text="^testName" inStringQ eqs "A23456789"

result testName "^reg.main.name: string DEFAULT: unquoted UPPERCASE, = '^inStringUQ'"
assert/text="^testName" inStringUQ eqs "A23456789"

result testName "^reg.main.name: string DEFAULT: quoted LOWERCASE, = '^inStringQLC'"
assert/text="^testName" inStringQLC eqs "abcdefg"

result testName "^reg.main.name: string DEFAULT: unquoted LOWERCASE, = '^inStringUQLC'"
assert/text="^testName" inStringUQLC eqs "ABCDEFG"

return

!******************************************************************************!
procedure booleanProc z:boolTrue z:boolFalse
  assert/text="^reg.main.name: procedure with TRUE boolean argument"  boolTrue
  assert/text="^reg.main.name: procedure with FALSE boolean argument" boolFalse isFalse
return
