!******************************************************************************!
! Test Changes in Convert that use BigDecimal to avoid losing precision on XLONG results
!
! Arguments: None
!
! @bug      2833 Convert.o2x losing precision for numbers > 2^53
! @author:  Jeanette McCall
! @version: $Id: test_results_xlong.mm,v 1.1 2014/09/18 14:33:52 jtm 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)
  
  !*********************************************************************************************
  ! Indirect testing:
  !********************************************************************************************* 
  ! ArgsTest getX() testing exercises these new/updated Convert methods to some degree
  !  includes:
  !    1) s2o (String string, char newType, Object ref)
  !    2) s2xl(byte[] buffer, int index1, int index2, Object ref)
  !    3) s2BigDecimal (byte[] buffer, int index1, int index2, BigDecimalValue bigDecimalVal, Object ref)
  !    4) s2BigDecimal_number (byte[] buffer, int index, int index2, BigDecimalValue bdVal, Object ref) 
  !    5) o2x (Object obj)
  ! NeXtMidas builds use s2o (String string, char newType, Object ref) & o2x (Object obj) entry paths
  
  !**********************************************************************************************
  ! Test XLONG arrays (tests s2o (String string, char newType, Object ref) entry point)
  !**********************************************************************************************
  
  result X:array (6362923255675387860,6362923255675387861,6362923255675387862,6362923255675387863,6362923255675387864)
  result S:array0 ^{array(0)}
  result S:arraydot0 ^{array.0}
  result S:array4 ^{array(4)}
  result S:arraydot4 ^{array.4}
  assert/text="%TEST_RESULTS_XLONG: ARRAYS get first element with () syntax " array0 EQS "6362923255675387860"
  assert/text="%TEST_RESULTS_XLONG: :ARRAYS get first element with . syntax " arraydot0 EQS "6362923255675387860"
  assert/text="%TEST_RESULTS_XLONG: ARRAYS get last element with () syntax " array4 EQS "6362923255675387864"
  assert/text="%TEST_RESULTS_XLONG: ARRAYS get last element with . syntax " arraydot4 EQS "6362923255675387864"
  
  !********************************************************************************************
  ! Basic Calculations (o2o (Object obj, char newType, Object ref) is entry point from Results)
  !********************************************************************************************
  !  includes:
  !   1) o2o (Object obj, String format, Object ref)
  !   2) s2o (String string, char newType, Object ref)
  !   3) s2xl(byte[] buffer, int index1, int index2, Object ref)
  !   4) s2BigDecimal (byte[] buffer, int index1, int index2, BigDecimalValue bigDecimalVal, Object ref)
  !   5) s2BigDecimal_number (byte[] buffer, int index, int index2, BigDecimalValue bdVal, Object ref)
  !   6) s2BigDecimal_paren (byte[] buffer, int index, int size, BigDecimalValue bdVal, Object ref)
  !   7) s2BigDecimal_result (byte[] buffer, int index, int size, BigDecimalValue bdVal, Object ref)
  !   8) s2BigDecimal_switch (byte[] buffer, int index, int size, BigDecimalValue bdVal, Object ref)
  !   9) o2BigDecimal (Object obj) where obj is a Data
  
  ! Test Addition
  !res x 1+(1/2)
  result X:resadd 6012340123401234012+2012340123401234012
  result S:resadd_s ^resadd
  assert/text="%TEST_RESULTS_XLONG: ADDITION " resadd_s EQS "8024680246802468024"
  
  ! Test Subtraction 
  result X:ressub 8024680246802468024-6012340123401234012
  result S:ressub_s ^ressub
  assert/text="%TEST_RESULTS_XLONG: SUBTRACTION " ressub_s EQS "2012340123401234012"
   
  ! Test multiplication
  result X:resmult 2012340123401234012*2.2
  result S:resmult_s ^resmult
  assert/text="%TEST_RESULTS_XLONG: MULTIPLICATION " resmult_s EQS "4427148271482714826"
  
  ! Test division  (including MathContext working)
  result X:resdiv 6363636369633396961/3
  result S:resdiv_s ^resdiv
  assert/text="%TEST_RESULTS_XLONG: DIVISION " resdiv_s EQS "2121212123211132320"
  
  ! Test power with integer power (uses BigDecimal.pow)
  result X:respow 2522624897**2
  result S:respow_s ^respow
  assert/text="%TEST_RESULTS_XLONG: POWER using BigDecimal.pow " respow_s EQS "6363636370964260609"
  ! Test power with fractional power (uses Math.pow)
  result X:respow 20000002**2.5
  assert/text="%TEST_RESULTS_XLONG: POWER using Math.pow " respow EQT 1788854829213460700
  
  ! Test more complex expressions
  res X:resexpr1 2522624897**(6362923255675387862-6362923255675387860)
  res S:resexpr1_s ^resexpr1
  assert/text="%TEST_RESULTS_XLONG: EXPRESSION using - & **" resexpr1_s EQS "6363636370964260609"
  res X:resexpr2 6363636369633396961/(6362923255675387862-6362923255675387860+1)*3
  res S:resexpr2_s ^resexpr2
  assert/text="%TEST_RESULTS_XLONG: EXPRESSION using - + / & **" resexpr2_s EQS "6363636369633396960"
  
  ! Test using a result value
  result X:rescopy resadd
  result S:rescopy_s ^rescopy
  assert/text="%TEST_RESULTS_XLONG: using RESULTS in equation " rescopy_s EQS "8024680246802468024"
  result X:resres resadd-ressub
  result S:resres_s ^resres
  assert/text="%TEST_RESULTS_XLONG: using RESULTS in equation " resres_s EQS "6012340123401234012"
       
  ! Test with a SWITCH value
  switch name="MYSWITCH"  value=15  func=set
  res X:resswitchval //MYSWITCH
  assert/text="%TEST_RESULTS_XLONG: putting the value of a /SWITCH in a result" resswitchval EQ 15
  res X:resswitch //MYSWITCH*614891469123651700
  res S:resswitch_s ^resswitch
  assert/text="%TEST_RESULTS_XLONG: Using a /SWITCH in the calculation" resswitch_s EQS "9223372036854775500"
  
  
  !**********************************************************************************************
  ! Test XLONG MAX and MIN
  !**********************************************************************************************
  result X:resmax 9223372036854775800+7
  result S:resmax_s ^resmax
  assert/text="%TEST_RESULTS_XLONG: XLONG MAXIMUM value " resmax_s EQS "9223372036854775807"
  result X:resmin -9223372036854775800-8
  result S:resmin_s ^resmin
  assert/text="%TEST_RESULTS_XLONG: XLONG MINIMUM value " resmin_s EQS "-9223372036854775808"


  !**********************************************************************************************
  ! Test cases that do not fit in XLONG
  !
  ! Note: Even through the Convert.s2o code will place these in type=DOUBLE, RESULTS will cast 
  ! these back to the specified type XLONG
  !**********************************************************************************************
  result X:resaddnotfit 9223372036854775800+10
  res S:resaddnotfit_s ^resaddnotfit
  assert/text="%TEST_RESULTS_XLONG: XLONG > XLONG_MAXIMUM set to MAX " resaddnotfit_s EQS "9223372036854775807"
  result X:ressubnotfit -9223372036854775800-10
  res S:ressubnotfit_s ^ressubnotfit
  assert/text="%TEST_RESULTS_XLONG: XLONG < XLONG_MINIMUM set to MIN " ressubnotfit_s EQS "-9223372036854775808"
  res X:resnan NaN
  assert/text="%TEST_RESULTS_XLONG: XLONG NaN set to 0" resnan EQ 0
  res X:resinf INFINITY
  res S:resinf_s ^resinf
  assert/text="%TEST_RESULTS_XLONG: XLONG INFINITY set to XLONG_MAXIMUM" resinf_s EQS "9223372036854775807"
  res X:resneginf -INFINITY
  res S:resneginf_s ^resneginf
  assert/text="%TEST_RESULTS_XLONG: XLONG -INFINITY set to XLONG_MAXIMUM" resneginf_s EQS "-9223372036854775808"
  
  !****************************************************************************************
  ! Tests o2x (Object obj) and follow-on methods
  !  1) obj instance of other than Number of Data (also later uses instance of Number)
  !      includes:
  !       s2BigDecimal (String string)
  !       s2BigDecimal (String string, Object ref)
  !  2) obj instance of Data (see junit ConvertTest.testO2x())
  !     (also uses instance of Number after Data.toX() and new method Data.toNumber())
  !      includes:
  !       o2o (Object obj, String form, int newSize, int newSPA, char newMode, char newType, Object ref)
  !****************************************************************************************
  invoke X:reso2xother=nxm.sys.lib.Convert.o2x("6362923255675387864")
  res S:reso2xother_s ^reso2xother
  assert/text="%TEST_RESULTS_XLONG: o2x(Object) with instance of not Data or Number " reso2xother_s EQS "6362923255675387864"
  
  !****************************************************************************************
  ! Tests o2x (Object obj, Object ref)) and follow-on methods
  !  1) obj instance of String (also later uses instance of Number)
  !       includes:
  !        s2xl (String string, Object ref)
  !  2) obj instance of Data (see junit ConvertTest.testO2x())
  !     (also uses instance of Number after Data.toX() and new method Data.toNumber())
  !      includes:
  !       o2o (Object obj, String form, int newSize, int newSPA, char newMode, char newType, Object ref)
  !       
  !  3) obj instance of other (tested in junit ConvertTest.testO2x for null, Time, & XMValue)
  !      includes:
  !       s2BigDecimal (String string)
  !****************************************************************************************
  invoke X:reso2xostring=nxm.sys.lib.Convert.o2x("6362923255675387864",null)
  res S:reso2xostring_s ^reso2xostring
  assert/text="%TEST_RESULTS_XLONG: o2x(Object,Object) with instance of String" reso2xostring_s EQS "6362923255675387864"
 
  !****************************************************************************************
  ! Test s2xl
  !  includes:
  !   s2xl (String string)
  !   s2xl (String string, Object ref) 
  !****************************************************************************************
  invoke X:ress2xl=nxm.sys.lib.Convert.s2xl("6362923255675387866")
  res S:ress2xl_s ^ress2xl
  assert/text="%TEST_RESULTS_XLONG: s2xl" ress2xl_s EQS "6362923255675387866"
  
  !*****************************************************************************************
  ! Places doubles are still used with XLONG:
  ! 1) inLineCalc(MidasReference ref, String clac) returns a double, but the examples I see
  !    for in-line calculator also do not specify a result name/type
  ! 2) Math.pow, which returns a double,  will still be used with XLONG when the exponent is not
  !    an integer, as BigDecimal only supports integer exponents
  !******************************************************************************************
  
endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg

    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"

return

!******************************************************************************!
! If an unexpected exception is caught, mark test as failed, unless it is expected
!******************************************************************************!
procedure processException m:emsg
  if expectedException REXISTS then
    assert/text="^reg.main.name: Expected ERROR starts with: ^{expectedException}" expectedException EQSS emsg.data.message
    remove expectedException
  else
    assert/text="^reg.main.name: Caught unexpected exception ^{emsg.data}" "FALSE" isTrue
    if "Trace" SUBS ENV.DEBUG then invoke ,, emsg.data.printStackTrace()
  endif
return


