!******************************************************************************!
! Tests the Convert functions.
!
! Arguments: None
!
! @bug      None
! @since    NeXtMidas 1.5.7
! @author:  J. Hallam
!******************************************************************************!
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)
  switch DEBUG       debug    GET DEF=TRUE  SDEF=TRUE

  set  L:numLinesInAirports 727
  calc L:numAirports numLinesInAirports 1 -

  call setDatDir

  fname blueMaster   area=test name=blue_master   ext=prm
  fname ieeeMaster   area=test name=ieee_master   ext=prm
  fname eeeiMaster   area=test name=eeei_master   ext=prm
  fname vaxMaster    area=test name=vax_master    ext=prm
  fname intMaster    area=test name=int_master    ext=prm
  fname byteMaster   area=test name=byte_master   ext=prm
  fname longMaster   area=test name=long_master   ext=prm
  fname floatMaster  area=test name=float_master  ext=prm
  fname doubleMaster area=test name=double_master ext=prm
  fname tbl2bMaster  area=test name=tbl2b_master  ext=prm

  ! test malformed xml input file with xml2tab
  call test_bad_xml
  
  !Convert from the local format to other formats
  call test_format

  ! Convert the MASTER blue file to each of the three formats
  call test_eeei
  call test_ieee
  call test_vax

  call test_packed  ! Convert master type files to all other types
  call test_int
  call test_double
  call test_float
  call test_byte
  call test_long
  call test_xml2blue  ^testFile    ! Convert an XML file into a blue file
  call test_blue2xml  ^blueMaster  ! Convert a BLUE file into an XML file
  call test_text2blue              ! Convert the a text file into a Data File
  call test_text2blue_cities       ! Convert the cities.txt file into a Data File
  call test_text2blue_cities_256ascii   ! Convert the cities_256ascii.txt file into a Data File
  call test_csv                    ! Convert Comma-separated values
  call test_tbl2HTML               ! Test converting from a TABLE (TBL) to HTML
  call test_table2blue             ! Test converting from a TABLE (TBL) to BLUE (1000 or 3000)
  call test_lla2xxx                ! Tests the LLA2ECR & LLA2ECI functions
  call test_refframe               ! Tests the ECI, ECR, TOP & TOPOCENT functions
  call test_coordsys               ! Tests the CARTESIAN, SPHERICAL, CYLINDRIC, ELLIPSOID & GEODETIC functions

  ! Since 3.8.0
  if ^{env.NMROOT} EQS "classpath:" then
    warn "SKIPPING ^reg.main.name test_sv2blue since zip files are not copied into SYS JAR file"
  else
    call test_sv2blue                ! Tests SV2BLUE
  endif

  ! Bug 2903 - test BLUE2XML and XML2BLUE conversion on ALL supported BLUE FILE TYPES
  call test_blue2xml ^{datDir}.test1000.prm         !1000
  ! TODO: re-enable after fixing BUG 2953 !  call test_blue2xml ^{datDir}.world.prm            !1999
  call test_blue2xml ^{datDir}.test2000_cf.prm      !2000
  call test_blue2xml ^{datDir}.test3000_eeei.prm    !3000 EEEI
  call test_blue2xml ^{datDir}.test3000_ieee.prm    !3000 IEEE
  call test_blue2xml ^{datDir}.cone5000.prm         !5000
  call test_blue2xml ^{datDir}.ellipse5000.prm      !5001
  call test_blue2xml ^{datDir}.events.prm           !5011
  call test_blue2xml ^{datDir}.capital_cities.prm   !5010
  call test_blue2xml ^{datDir}.test6000.prm         !6000
  ! TODO: re-enable after fixing XML to BLUE type 6000   call test_blue2xml nxm.sys.test.t6000_xm.prm        !6000
  ! Create 5000 with 'Z' 256 ASCII type = NXM-3570
  nxm.sys.test.plotellipsetester/DIAGONAL/COLOR=4/NOTEMODETYPE=4Z/RT/RATE=500/STARTTIME="2007:01:02::00:00:00" OUT=ram:type_5000_z_type ELEM=20
  !call test_blue2xml ram:type_5000_z_type
  call test_blue2xml_temp ram:type_5000_z_type        ! Using test_blue2xml_temp for plotellipsetester until NXM-3670 is addressed 

  ! Due to Bug 2725 we need to do the SVINTERP tests in a separate macro that we call multiple times.
  %test_convert_svinterp "TEST_1" /interactive=^interAct
  %test_convert_svinterp "TEST_2" /interactive=^interAct
  %test_convert_svinterp "TEST_3" /interactive=^interAct

  ! Test converting a table from IEEE/EEEI to native format and back (This should test for DR 509717-1)
  call test_byte_format

  ! Test evaluating numbers and Strings within parentheses (Bug 2314)
  call test_num_parens

  ! All XML to TABLE and TABLE to XML conversion functions
  %test_convert_xml_table/debug=^debug

  ! Test PLAT2BLUE and KWCONV
  %test_convert_keywords

  ! Test CSV2TBL with multi-line CSV files as well as CVS files without LF at end (NXM-2931,NXM-3155)
  %test_convert_csv
  
  ! Test instanceof DataFile code in Convert
  %test_convert_child_datafile

  if interAct then
    ! call blue2img test case
    %test_convert_blue2img  ! Bug 1958
  endif
endmacro

!******************************************************************************!
! 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

!******************************************************************************!
procedure test_format
!
!  Convert "SPECIAL" numbers from local REP to foreign back to local
!
if     "^env.osrep" EQS "EEEI" then
  set otherReps "IEEE,VAX"
elseif "^env.osrep" EQS "IEEE" then
  set otherReps "EEEI,VAX"
elseif "^env.osrep" EQS "VAX" then
  set otherReps "IEEE,EEEI"
else
  beep 3
  assert/text="^reg.main.name: unrecognized OS REP = ^env.osrep" "FALSE"
endif

! Build a local rep file with the special numbers
set localrepfile   "temp_convert_localrep"
set localrepfileOut "temp_convert_localrep_out"
if localrepfile FEXISTS erase/all localrepfile
header/create localrepfile FORM=SD
set specialNumbers "380.2875,380.4125,380.9125,381.1625"
set L:offset 0
foreach sval INLIST specialNumbers
  set D:val ^sval
  set FILE(^{localrepfile}).data(offset) ^sval
  calc offset offset 1 +
endfor

! Convert file from local rep to other reps
foreach rep INLIST otherReps
  sedit rep rep_locase "LOCASE"
  set foreignRepFile "temp_convert_^{rep_locase}"
  if foreignRepFile FEXISTS erase/all foreignRepFile
  convert localrepfile "^rep" foreignRepFile
  convert foreignRepFile "^env.osrep" localrepfileOut

  set L:badConversions 0
  set L:offset 0
  foreach sval INLIST specialNumbers
    if FILE(^{foreignRepFile}).data(offset) NEQ ^sval then
      calc L:badConversions badConversions 1 +
    endif
    calc offset offset 1 +
  endfor
  set text "^reg.main.name: ^{env.osrep}-^{rep}-^{env.osrep}, ^badConversions bad conversions"
  assert/text="^text" badConversions EQ 0
  erase/all foreignRepFile localrepfileOut
endfor

erase localrepfile

return

!******************************************************************************!
procedure test_eeei
  CONVERT blueMaster EEEI eeei_blue
  ASSERT/TEXT="^reg.main.name: BLUE-to-EEEI"/stat=status_eeei &
      eeei_blue FEQ eeeiMaster

  if status_eeei EQS "PASS" then

    ! CONVERT from BLUE to EEEI then check CONVERT from EEEI to IEEE
    !
    CONVERT eeei_blue IEEE ieee_blue
    ASSERT/TEXT="^reg.main.name: EEEI-to-IEEE" ieee_blue FEQ ieeeMaster
    erase ieee_blue

    ! CONVERT from BLUE to EEEI then check CONVERT from EEEI to VAX
    !
    CONVERT eeei_blue VAX vax_blue
    ASSERT/TEXT="^reg.main.name: EEEI-to-VAX" vax_blue FEQ vaxMaster
    erase vax_blue
  endif

  erase eeei_blue

return

!******************************************************************************!
procedure test_ieee
  CONVERT blueMaster IEEE ieee_blue
  ASSERT/TEXT="^reg.main.name: BLUE-to-IEEE"/stat=status_ieee &
        ieee_blue FEQ ieeeMaster

  if status_ieee EQS "PASS" then
    ! CONVERT from BLUE to IEEE then check CONVERT from IEEE to EEEI
    !
    CONVERT ieee_blue EEEI eeei_blue
    ASSERT/TEXT="^reg.main.name: IEEE-to-EEEI" eeei_blue FEQ eeeiMaster
    erase eeei_blue

    ! CONVERT from BLUE to IEEE then check CONVERT from IEEE to VAX
    !
    CONVERT ieee_blue VAX vax_blue
    ASSERT/TEXT="^reg.main.name: IEEE-to-VAX" vax_blue FEQ vaxMaster
    erase vax_blue
  endif

  erase ieee_blue

return

!******************************************************************************!
procedure test_vax
  CONVERT blueMaster VAX vax_blue
  ASSERT/TEXT="^reg.main.name: BLUE-to-VAX" vax_blue FEQ vaxMaster /stat=status_vax
  if status_vax EQS "PASS" then

    ! CONVERT from BLUE to VAX then check CONVERT from VAX to EEEI
    !
    CONVERT vax_blue EEEI eeei_blue
    ASSERT/TEXT="^reg.main.name: VAX-to-EEEI" eeei_blue FEQ/B eeeiMaster
    erase eeei_blue

    ! CONVERT from BLUE to VAX then check CONVERT from VAX to IEEE
    !
    CONVERT vax_blue IEEE ieee_blue
    ASSERT/TEXT="^reg.main.name: VAX-to-IEEE" ieee_blue FEQ/B ieeeMaster
    erase ieee_blue
  endif

  erase vax_blue
return

!******************************************************************************!
procedure test_packed

  ! convert from PACKED to BYTE, INT, LONG, FLOAT, DOUBLE
  res packedwave ram:test_convert_sp_master.tmp
  waveform packedwave FORM=SP ELEM=32 MEAN=0.5 AMP=0.5 SHAPE=square FREQ=.1
  convert packedwave BYTE byte
  call check_packed byte "Byte"
  convert packedwave INT int
  call check_packed int "Int"
  convert packedwave LONG long
  call check_packed long "Long"
  convert packedwave FLOAT float
  call check_packed float "Float"
  convert packedwave DOUBLE double
  call check_packed double "Double"

  ! TODO convert them back to PACKED and check them using check_packed
  assert/text="^reg.main.name: missing test for conversion from types to PACKED"/noop=MISS false

  erase byte.tmp
  erase int.tmp
  erase long.tmp
  erase float.tmp
  erase double.tmp
return

!******************************************************************************!
procedure check_packed fn:filename CS:type

  res i:expect (0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,1,1,1,1,1,0)
  res lastidx 31 ! 32 elements - index 0 to 31
  file open/d tag filename
  res errormsg ""
  DO idx 0 lastidx 1
    res i:act tag.getdata(^idx)
    res i:exp expect.^idx
    if act NEQ exp then
      res errormsg "^{errormsg}, index:^{idx} exp:^{exp} act:^{act}"
    endif
    !say "val:^val exp:^exp"
  ENDDO

  file close tag

  ASSERT/TEXT="^reg.main.name: Scalar Packed-to-^{type}^errormsg" errormsg EQS ""


return
!******************************************************************************!
procedure test_int
!
! convert from INT to BYTE,LONG,FLOAT,DOUBLE
!
  CONVERT intMaster FLOAT float
  CONVERT intMaster BYTE byte
  CONVERT intMaster LONG long
  CONVERT intMaster DOUBLE double

  ASSERT/TEXT="^reg.main.name: Scalar Integer-to-Float" float FEQ/D floatMaster
  ASSERT/TEXT="^reg.main.name: Scalar Integer-to-Byte" byte FEQ/D byteMaster
  ASSERT/TEXT="^reg.main.name: Scalar Integer-to-Long" long FEQ/D longMaster
  ASSERT/TEXT="^reg.main.name: Scalar Integer-to-Double" double FEQ/D doubleMaster

  ERASE byte.tmp
  ERASE long.tmp
  ERASE float.tmp
  ERASE double.tmp

return

!******************************************************************************!
procedure test_double
!
! convert from DOUBLE to BYTE, INT, LONG, FLOAT
!
  CONVERT doubleMaster FLOAT float
  CONVERT doubleMaster BYTE byte
  CONVERT doubleMaster INT int
  CONVERT doubleMaster LONG long

  ASSERT/TEXT="^reg.main.name: Scalar Double-to-Float" float FEQ/D floatMaster
  ASSERT/TEXT="^reg.main.name: Scalar Double-to-Byte" byte FEQ/D byteMaster
  ASSERT/TEXT="^reg.main.name: Scalar Double-to-Int" int FEQ/D intMaster
  ASSERT/TEXT="^reg.main.name: Scalar Double-to-Long" long FEQ/D longMaster

  ERASE int.tmp
  ERASE byte.tmp
  ERASE long.tmp
  ERASE float.tmp

return

!******************************************************************************!
procedure test_float
!
! convert from FLOAT to BYTE, INT, LONG, DOUBLE
!
  CONVERT floatMaster INT int
  CONVERT floatMaster BYTE byte
  CONVERT floatMaster LONG long
  CONVERT floatMaster DOUBLE double

  ASSERT/TEXT="^reg.main.name: Scalar Float-to-Int" int FEQ/D intMaster
  ASSERT/TEXT="^reg.main.name: Scalar Float-to-Byte" byte FEQ/D byteMaster
  ASSERT/TEXT="^reg.main.name: Scalar Float-to-Long" long FEQ/D longMaster
  ASSERT/TEXT="^reg.main.name: Scalar Float-to-Double" double FEQ/D doubleMaster

  ERASE int.tmp
  ERASE byte.tmp
  ERASE long.tmp
  ERASE double.tmp

return
!******************************************************************************!
procedure test_long
!
! convert from LONG to BYTE, INT, FLOAT, DOUBLE
!
  CONVERT longMaster FLOAT float
  CONVERT longMaster BYTE byte
  CONVERT longMaster INT int
  CONVERT longMaster DOUBLE double

  ASSERT/TEXT="^reg.main.name: Scalar Long-to-Float" float FEQ/D floatMaster
  ASSERT/TEXT="^reg.main.name: Scalar Long-to-Byte" byte FEQ/D byteMaster
  ASSERT/TEXT="^reg.main.name: Scalar Long-to-Int" int FEQ/D intMaster
  ASSERT/TEXT="^reg.main.name: Scalar Long-to-Double" double FEQ/D doubleMaster

  ERASE int.tmp
  ERASE byte.tmp
  ERASE float.tmp
  ERASE double.tmp

return
!******************************************************************************!
procedure test_byte
!
! convert from BYTE to INT, LONG, FLOAT, DOUBLE
!
  CONVERT byteMaster FLOAT float
  CONVERT byteMaster INT int
  CONVERT byteMaster LONG long
  CONVERT byteMaster DOUBLE double

  ASSERT/TEXT="^reg.main.name: Scalar Byte-to-Float" float FEQ/D floatMaster
  ASSERT/TEXT="^reg.main.name: Scalar Byte-to-Int" int FEQ/D intMaster
  ASSERT/TEXT="^reg.main.name: Scalar Byte-to-Long" long FEQ/D longMaster
  ASSERT/TEXT="^reg.main.name: Scalar Byte-to-Double" double FEQ/D doubleMaster

  ERASE int.tmp
  ERASE long.tmp
  ERASE float.tmp
  ERASE double.tmp

return

!******************************************************************************!
procedure test_table2blue
  result g_tbl2b {row1={},row2={},row3={}}
  do l:ii 1 9 1
    do l:jj 1 3 1
      if ii eq 10
        result g_tbl2b.row^{jj}.val^ii ^{jj}.1000000001
      else
        result g_tbl2b.row^{jj}.val^ii ^{jj}.^ii
      endif
    enddo
  enddo
  CONVERT g_tbl2b TBL2B g_tbl2b_m3kFile FORM="VAL1=SD|VAL2=SD|VAL3=SD"
  ASSERT/TEXT="^reg.main.name: Table-to-Blue (TBL2B)" g_tbl2b_m3kFile FEQ/d tbl2bMaster

  ERASE g_tbl2b_m3kFile

return

!******************************************************************************!
procedure test_csv
!
!    Test conversions using csv2tbl and csv2xml
!
res csvfile "^{datDir}.airports.csv"
set qualifiers {HEADERROWS=1,ROWNAME=AIRPORT,COLUMNNAMES="NAME|CODE|SF:LAT|SF:LON"}
CONVERT ^{datDir}.airports.csv^qualifiers csv2tbl tab
assert/text="^reg.main.name: CSV2TBL - size " tab.getSize EQ numAirports

assert/stat=status/text="^reg.main.name: CSV2TBL - first row tag names" &
                                                  tab.AIRPORT_1 REXISTS AND &
                                                  tab.AIRPORT_^numAirports REXISTS

if status then
assert/text="^reg.main.name: CSV2TBL - first row values " &
                               "^tab.AIRPORT_1.name" EQS "Abu Dhabi" AND &
                                 tab.AIRPORT_1.code EQS "AUH"        AND &
                                 tab.AIRPORT_1.lat  EQT  24.43333    AND &
                                 tab.AIRPORT_1.lon  EQT  54.65

endif
file open/t/n filetag temp_convert.csv{FLAGS=FORCEABORT}
file write filetag "X,Y"
file write filetag "0,4"
file write filetag "1,3"
file write filetag "2,2"
file write filetag "3,1"
file write filetag "4,0"
file close filetag

set quals {HEADERROWS=1,COLUMNNAMES="L:XVAL|L:YVAL"}
CONVERT temp_convert.csv^quals csv2xml temp_convert    ! .xml extension removed from OUT for Bug 1972
CONVERT temp_convert.csv^{quals} csv2tbl tbl1
CONVERT temp_convert.xml xml2tab tbl2

foreach key INTABLE tbl1
  assert/text="^reg.main.name: CSV2XML row=^{key}" &
                               ^{tbl1.^{key}.XVAL} EQ ^{tbl2.^{key}.XVAL} AND &
                               ^{tbl1.^{key}.YVAL} EQ ^{tbl2.^{key}.YVAL}
endfor

CONVERT ^{datDir}.airports.csv^qualifiers CSV2XML temp_convert.xml
CONVERT temp_convert.xml XML2TAB tab
assert/text="^reg.main.name: CSV2XML/XML2TAB - size " tab.getSize EQ numAirports

assert/stat=status/text="^reg.main.name: CSV2XML/XML2TAB - first row tag names" &
                                                  tab.AIRPORT_1 REXISTS AND &
                                                  tab.AIRPORT_^numAirports REXISTS

if status then
assert/text="^reg.main.name: CSV2XML/XML2TAB - first row values " &
                               "^tab.AIRPORT_1.name" EQS "Abu Dhabi" AND &
                                 tab.AIRPORT_1.code EQS "AUH"        AND &
                                 tab.AIRPORT_1.lat  EQT  24.43333    AND &
                                 tab.AIRPORT_1.lon  EQT  54.65

endif
erase/quiet/warn=n temp_convert.csv
erase/quiet/warn=n temp_convert.xml

return

!******************************************************************************!
procedure processException m:emsg
  !say "Got Exception: EMSG=^emsg  FROM=^emsg.from DATA=^emsg.data MESSAGE=^emsg.data.message"
  if emsg.data instanceof nxm.sys.lib.MidasException
     assert/text="^reg.main.name: Expected ERROR is instance of: ^{expectException}" TRUE
    remove expectException
  else
    ! Otherwise we should NOT get any exceptions
    assert/text="^reg.main.name: Unexpected ^emsg.data" "FALSE"
  endif
  
return

!******************************************************************************!
procedure test_bad_xml

! test xml2tab with malformed xml file
result testFile "temp2_convert.xml{FLAGS=FORCEABORT}"

file open/n/t tag testFile
file write tag "ML>"
file write tag "<PERSDATA>"
file write tag "<LOC NAME="HOMER"  SSN="123-45-6789" CITY="SPRINGFIELD" ZIP="12321" />"
file write tag "<LOC NAME="MARGE"  SSN="123-45-6780" CITY="SPRINGFIELD" ZIP="12321" />"
file write tag "</PERSDATA>"
file write tag "</XML>"
file close tag

res expectException "MidasException"
convert temp2_convert.xml xml2tab tbl2
assert/text="Malformed XML file should ERROR" expectException NREXIST

return

!******************************************************************************!
procedure test_xml2blue S:testFile

result testFile "test_convert_xml2blue.xml{FLAGS=FORCEABORT}"
result outFile "test_convert_xml2blue.tmp{FLAGS=FORCEABORT}"

file open/n/t tag testFile
file write tag "<XML>"
file write tag "<PERSDATA>"
file write tag "<LOC NAME="HOMER"  SSN="123-45-6789" CITY="SPRINGFIELD" ZIP="12321" />"
file write tag "<LOC NAME="MARGE"  SSN="123-45-6780" CITY="SPRINGFIELD" ZIP="12321" />"
file write tag "</PERSDATA>"
file write tag "</XML>"
file close tag
convert /xmlkey="xml|persdata" testFile XML2B outFile

if outFile FEXISTS then
  remove size numsubrecs
  status outFile size=size nsr=numsubrecs
  if size EQ 2 AND numsubrecs EQ 4 then
    file open/d tag outfile
    result firstName tag.getData(0,"NAME")
    result L:zipcode tag.getData(0,"ZIP")
    file close tag
    if firstName EQS "HOMER" then
      assert/TEXT="^reg.main.name: XML2BLUE - expected zip = 12321, got ^zipcode" zipCode EQ 12321
    else
      assert/TEXT="^reg.main.name: XML2BLUE - expected name = HOMER, got ^firstname" false
    endif
  else
    assert/TEXT="^reg.main.name: XML2BLUE - size or NSR of blue file incorrect" false
  endif
else
  assert/TEXT="^reg.main.name: XML2BLUE - ^outfile does not exist" false
endif
erase/all testFile
erase/all outFile

return

!******************************************************************************!
procedure test_blue2xml FN:testFile
!TODO: RDB - fix format of test back to ASSERTS vs. nested if-else-endif
if testFile FEXISTS then

  status testFile mimetype=mimeType

  if mimeType EQS "application/octet-stream" then
    status testFile type=midasType TypeCodeClass=typeClass
    if typeClass EQ 1 OR typeClass EQ 2 OR typeClass EQ 3 OR typeClass EQ 5 OR typeClass EQ 6 then

    result outFileXML "test_convert_blue2xml_^{env.pid}.xml"

    convert testFile BLUE2XML outFileXML
    

    if outFileXML FEXISTS then

      status outFileXML mimetype=mimeType
      if mimeType EQS "text/xml" then
      result outFilePRM "ram:convert_xml2blue.tmp"

      convert outFileXML "XML2BLUE" outFilePRM

      if outFilePRM FEXISTS then
        assert/TEXT="^reg.main.name: BLUE2XML --- Header - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/H outFilePRM
        assert/TEXT="^reg.main.name: BLUE2XML ----- Data - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/D outFilePRM
        assert/TEXT="^reg.main.name: BLUE2XML ----- Size - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/S outFilePRM
        if midasType neqs "6000" then
         assert/TEXT="^reg.main.name: BLUE2XML - Keywords - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/K outFilePRM
        endif

        erase/all outFilePRM
      else
        assert/TEXT="^reg.main.name: BLUE2XML - FAILED to create file ^outFilePRM -- does not exist" false
      endif

      erase/all outFileXML
      else
        assert/TEXT="^reg.main.name: BLUE2XML - bad MIME type on converted file (^mimeType)" false
      endif
    else
      assert/TEXT="^reg.main.name: BLUE2XML - FAILED to create file ^outFileXML -- does not exist" false
    endif
    else
      assert/TEXT="^reg.main.name: BLUE2XML - unsupported MIDAS type (^midasType)" false
    endif
  else
    assert/TEXT="^reg.main.name: BLUE2XML - bad MIME type (^mimeType)" false
  endif
else
  assert/TEXT="^reg.main.name: BLUE2XML - ^testFile does not exist" false
endif
  erase/all/warn=n outFileXML outFilePRM
return

!******************************************************************************!
procedure test_blue2xml_temp FN:testFile
!TODO: RDB - fix format of test back to ASSERTS vs. nested if-else-endif
if testFile FEXISTS then

  status testFile mimetype=mimeType

  if mimeType EQS "application/octet-stream" then
    status testFile type=midasType TypeCodeClass=typeClass
    if typeClass EQ 1 OR typeClass EQ 2 OR typeClass EQ 3 OR typeClass EQ 5 OR typeClass EQ 6 then

    result outFileXML "test_convert_blue2xml_^{env.pid}.xml"

    convert testFile BLUE2XML outFileXML
    

    if outFileXML FEXISTS then

      status outFileXML mimetype=mimeType
      if mimeType EQS "text/xml" then
      result outFilePRM "ram:convert_xml2blue.tmp"

      convert outFileXML "XML2BLUE" outFilePRM

      if outFilePRM FEXISTS then
        assert/TEXT="^reg.main.name: BLUE2XML --- Header - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/H outFilePRM
        assert/TEXT="^reg.main.name: BLUE2XML ----- Data - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/D outFilePRM
        assert/TEXT="^reg.main.name: BLUE2XML ----- Size - TYPE ^midasType - ^{testFile.basename}" testFile FEQ/S outFilePRM
        if midasType neqs "6000" then
          key/scope=ext ^testFile tget before_conv
          key/scope=ext ^outFilePRM tget after_conv
          info "^reg.main.name: BLUE2XML - Keywords - TYPE ^midasType - ^{testFile.basename}"
          info "Expect to see a warning about mismatched keywords after converting a blue file to and from XML:"
          warn "Desired:  ^before_conv \n      Expected: ^after_conv \n      See JIRA issue NXM-3670 for more details"
        endif

        erase/all outFilePRM
      else
        assert/TEXT="^reg.main.name: BLUE2XML - FAILED to create file ^outFilePRM -- does not exist" false
      endif

      erase/all outFileXML
      else
        assert/TEXT="^reg.main.name: BLUE2XML - bad MIME type on converted file (^mimeType)" false
      endif
    else
      assert/TEXT="^reg.main.name: BLUE2XML - FAILED to create file ^outFileXML -- does not exist" false
    endif
    else
      assert/TEXT="^reg.main.name: BLUE2XML - unsupported MIDAS type (^midasType)" false
    endif
  else
    assert/TEXT="^reg.main.name: BLUE2XML - bad MIME type (^mimeType)" false
  endif
else
  assert/TEXT="^reg.main.name: BLUE2XML - ^testFile does not exist" false
endif
  erase/all/warn=n outFileXML outFilePRM
return

!******************************************************************************!
procedure test_tbl2HTML
  results root {}
  results root.branch1 {}
  results root.branch2 {}
  results root.branch1.value1 "-1"
  results root.branch1.value2 "FAILED SOME TESTS"
  results root.branch1.value3 "1"
  results root.branch1.value4 "PASSED ALL TESTS"
  results root.branch2.value1 "-1"
  results root.branch2.value2 "VALUE TWO"
  results root.branch2.value3 "VALUE THREE"
  results root.branch2.value4 "VALUE FOUR"

!
!  Set up the filenames:
!    1) outHTMLFile =>  generated .html file to nxm.sys.test directory
!    2) HTMLMaster  =>  Master .html file in nxm.sys.test directory
!
  result S:outHTMLFile test_convert_tbl2html.html
  fname HTMLMaster area=test name=HTMLMaster ext=html
!
!  Convert the nxm Table "root" to a .html file
!
  convert root TBL2HTML ^outHTMLFile
!
!  Since the files are textfiles, compare with a binary comparison
!
  ASSERT/TEXT="^reg.main.name: Table-to-HTML" ^HTMLMaster FEQ/D ^outHTMLFile
  erase ^outHTMLFile

return

!******************************************************************************!
procedure test_text2blue
  fname intxtFile area=test name=interesting_numbers ext=txt
  CONVERT inTXTFile T2B t2b_blue B4|1x|I6|1x|L11|1x|F19|1x|D29 2
  ASSERT/TEXT="^reg.main.name: Text-to-Blue (T2B)" t2b_blue FEQ/d blueMaster
  erase t2b_blue

return

!******************************************************************************!
procedure test_text2blue_cities
  result testName "Text-to-Blue (T2B - CITIES)"

  res inTXTFile "^{datDir}.cities.txt"
  fname outDataFile area=aux.write name=test_convert_t2b ext=tmp opt=aux
  convert inTXTFile T2B outDataFile d4|2x|d10|4x|d12|1x|a8 3
  status outDataFile size=size nsr=numsubrecs
  assert/TEXT="^reg.main.name: ^testName; size and numsrecs"/stat=tempStatus &
                    size EQ 606 AND numsubrecs EQ 4
  if tempStatus EQS "PASS" then
    file open/d tag ^outDataFile
    result firstCityName tag.getData(0,"TR04")
    result lastCityName tag.getData(size-,"TR04")
    file close tag
    assert/TEXT="^reg.main.name: ^testName; first and last" &
                     "^firstCityName" EQS "Murmansk" AND "^lastCityName" EQS "Singapor"
  endif
  erase/all outDataFile
return


!******************************************************************************!
procedure test_text2blue_cities_256ascii
  result testName "Text-to-Blue (T2B - CITIES_256ASCII)"

  fname inTXTFile area=test name=cities_256ascii ext=txt
  fname outDataFile area=aux.write name=test_convert_t2b ext=tmp opt=aux
  convert inTXTFile T2B outDataFile d4|2x|d10|4x|d12|1x|z256 3
  status outDataFile size=size nsr=numsubrecs SR(4)=srtbl
  assert/TEXT="^reg.main.name: ^testName; 1Z format" srtbl.format EQS 1Z
  if tempStatus EQS "PASS" then
    file open/d tag ^outDataFile
    result firstCityName tag.getData(0,"TR04")
    file close tag
    assert/TEXT="^reg.main.name: ^testName; first 'city'" &
                     "^firstCityName" EQS "Murmansk                      Z                                              Z"
  endif
  erase/all outDataFile
return

!******************************************************************************!
! Test converting a table from IEEE/EEEI to native format and back
!   (This should test for DR 509717-1)
procedure test_byte_format

  ! Type 3000
  call byte_format_tests ^{datDir}.test3000_ieee.prm ^{datDir}.test3000_eeei.prm "Type 3000"

  ! Type 5000
  if baseline isTrue then
    warn "No tests for Type 5000 IEEE<->EEEI conversions"
  endif
return

!******************************************************************************!
procedure byte_format_tests s:ieeeFile s:eeeiFile s:type
  res temp1 "temp_test_convert_1"
  res temp2 "temp_test_convert_2"

  noop ieeeFile temp1
  noop eeeiFile temp2
  assert/text="^reg.main.name: ^type IEEE/EEEI->^{ENV.OSREP} with NOOP" temp1 FEQ ieeeFile
  assert/text="^reg.main.name: ^type IEEE/EEEI->^{ENV.OSREP} with NOOP" temp2 FEQ eeeiFile
  assert/text="^reg.main.name: ^type IEEE/EEEI->^{ENV.OSREP} with NOOP" temp1 FEQ temp2


  convert ieeeFile IEEE temp1
  convert ieeeFile EEEI temp2
  assert/text="^reg.main.name: ^type IEEE->IEEE (equals IEEE)" temp1 FEQ ieeeFile
  assert/text="^reg.main.name: ^type IEEE->IEEE (equals EEEI)" temp1 FEQ eeeiFile
  assert/text="^reg.main.name: ^type IEEE->EEEI (equals IEEE)" temp2 FEQ ieeeFile
  assert/text="^reg.main.name: ^type IEEE->EEEI (equals EEEI)" temp2 FEQ eeeiFile

  convert eeeiFile IEEE temp1
  convert eeeiFile EEEI temp2
  assert/text="^reg.main.name: ^type EEEI->IEEE (equals IEEE)" temp1 FEQ ieeeFile
  assert/text="^reg.main.name: ^type EEEI->IEEE (equals EEEI)" temp1 FEQ eeeiFile
  assert/text="^reg.main.name: ^type EEEI->EEEI (equals IEEE)" temp2 FEQ ieeeFile
  assert/text="^reg.main.name: ^type EEEI->EEEI (equals EEEI)" temp2 FEQ eeeiFile

  erase temp1
  erase temp2
  remove temp1
  remove temp2
return

!******************************************************************************!
! Test handling of nested or multiple parentheses (Bug 2314)
procedure test_num_parens

 res testParens1 (1+4)/(4+1)    ! calls Convert.s2o, Convert.s2d and Convert.s2d_p
 res testParens2 ((1+4)/(4+1))  ! calls Convert.s2o, Convert.s2d and Convert.s2d_p
 res testParens3 ((one))        ! calls Convert.s2o, Convert.s2d and Convert.s2d_p

 assert/text="^reg.main.name: Nested Parens" testParens1 eq 1
 assert/text="^reg.main.name: Double Nested Parens" testParens2 eq 1
 assert/text="^reg.main.name: Double Nested Parens String" testParens3 eqs "((ONE))"

return

!******************************************************************************!
! Test the LLA2ECR & LLA2ECI functions
procedure test_lla2xxx
  res T:WASH_MONUMENT {LON=-77'02'06.86378,LAT=+38'53'22.08377,ALT=0}
  res D:START_TIME    2012:11:09::00:00:00
  res D:TIME_DELTA    300.0
  res D:ELEMENTS      288

  convert WASH_MONUMENT LLA2ECR ram:svlla_ecr &
            OPTIONS={START=^{START_TIME},DELTA=^{TIME_DELTA},ELEM=^{ELEMENTS}} &
            EPOCH=^{START_TIME}
  convert WASH_MONUMENT LLA2ECI ram:svlla_eci &
            OPTIONS={START=^{START_TIME},DELTA=^{TIME_DELTA},ELEM=^{ELEMENTS}} &
            EPOCH=^{START_TIME}

  ! CHECK ECR OUTPUT ===========================================================
  ! Do this first since it is the easy one where all of the positions match the
  ! basic conversion from GEODETIC used, so just convert once and VEL/ACC are
  ! all zero.
  res T:fileTests {TEXT="LLA2ECR"}
  file open f ram:svlla_ecr
    res recDefs f.RecordDefs

    assert/group=fileTests/test START_TIME EQ f.time
    assert/group=fileTests/test 0.0        EQ f.start
    assert/group=fileTests/test TIME_DELTA EQ f.delta
    assert/group=fileTests/test ELEMENTS   EQ f.size

    call _checkRecDefPRM fileTests recDefs "POS"  "VD"  0 "CARTESIAN" "DISTANCE_M"
    call _checkRecDefPRM fileTests recDefs "VEL"  "VD" 24 "CARTESIAN" "SPEED_M_S"
    call _checkRecDefPRM fileTests recDefs "ACC"  "VD" 48 "CARTESIAN" "ACCELERATION_M_S2"
    call _checkRecDefPRM fileTests recDefs "TIME" "SD" 72 "SCALAR"    "TIME_S"

    invoke p   nxm.sys.lib.Position.fromGeo(WASH_MONUMENT.ALT,WASH_MONUMENT.LAT,WASH_MONUMENT.LON)
    invoke pos p.toTable()

    do i 0 f.size-1 1
      calc time   START_TIME TIME_DELTA i * +
      res  actTbl f.getDataTable(i)
      res  expTbl {D:POS=(^{POS.X},^{POS.Y},^{POS.Z}),&
                   D:VEL=(0,0,0),&
                   D:ACC=(0,0,0),&
                   D:TIME=^{time}}

      assert/group=fileTests/test/text="row ^i" expTbl.TIME EQ/V actTbl.TIME
      assert/group=fileTests/test/text="row ^i" expTbl.POS  EQ/V actTbl.POS
      assert/group=fileTests/test/text="row ^i" expTbl.VEL  EQ/V actTbl.VEL
      assert/group=fileTests/test/text="row ^i" expTbl.ACC  EQ/V actTbl.ACC
    enddo
  file close f
  assert/group=fileTests/summary

  ! CHECK ECI OUTPUT ===========================================================
  ! 1. Check file format
  res T:fileTests {TEXT="LLA2ECI"}
  file open f ram:svlla_eci
    res recDefs f.RecordDefs

    assert/group=fileTests/test START_TIME EQ f.time
    assert/group=fileTests/test 0.0        EQ f.start
    assert/group=fileTests/test TIME_DELTA EQ f.delta
    assert/group=fileTests/test ELEMENTS   EQ f.size

    call _checkRecDefPRM fileTests recDefs "POS"  "VD"  0 "CARTESIAN" "DISTANCE_M"
    call _checkRecDefPRM fileTests recDefs "VEL"  "VD" 24 "CARTESIAN" "SPEED_M_S"
    call _checkRecDefPRM fileTests recDefs "ACC"  "VD" 48 "CARTESIAN" "ACCELERATION_M_S2"
    call _checkRecDefPRM fileTests recDefs "TIME" "SD" 72 "SCALAR"    "TIME_S"
  file close f

  ! 2. Check file data by converting to ECR and comparing to LLA2ECR output. This
  !    assumes that the ECR is tested separately.
  convert ram:svlla_eci ECR ram:svlla_ecef

  file OPEN expFile ram:svlla_ecr
    file OPEN actFile ram:svlla_ecef
      do i 0 expFile.size-1 1
        invoke expRow expFile.getDataTable(i)
        invoke actRow actFile.getDataTable(i)

        assert/group=fileTests/test/text="row ^i" expTbl.TIME EQ/V   actTbl.TIME
        assert/group=fileTests/test/text="row ^i" expTbl.POS  EQ/V/T actTbl.POS   /TOL=1e-3
        assert/group=fileTests/test/text="row ^i" expTbl.VEL  EQ/V/T actTbl.VEL   /TOL=1e-6
        assert/group=fileTests/test/text="row ^i" expTbl.ACC  EQ/V/T actTbl.ACC   /TOL=1e-9
      enddo
    file CLOSE actFile
  file CLOSE expFile
  assert/group=fileTests/summary
return


!******************************************************************************!
! Test the ECI, ECR, TOP & TOPOCENT functions
procedure test_refframe
  ! Note that we do the conversion tests in alphabetical order, but it should be
  ! noted that a number of the tests assume their counterparts are correct:
  !
  !    TEST         ASSUMES
  !
  ! Note that the files in the DAT area (sv1.prm, sv2.prm, sv3.prm) are all in
  ! ECR and do not include an ACC column, so tests involving them only test POS
  ! and VEL.
  !
  ! Among the files, any files with the same KEY are presumed to be identical,
  ! except for a change in reference frame.
  set T:sampleFilesECR {SV1="^{datDir}.sv1.prm",&
                        SV2="^{datDir}.sv2.prm",&
                        SV3="^{datDir}.sv3.prm",&
                        SV3_ACC="nxm.sys.test.sv1_acc.prm"}

  ! ECI -> ECI =================================================================
  assert/text="ECI -> ECI" /NOOP=MISS

  ! ECI -> ECR =================================================================
  assert/text="ECI -> ECR" /NOOP=MISS

  ! ECI -> TOP =================================================================
  assert/text="ECI -> TOP" /NOOP=MISS

  ! ECI -> TOPOCENT ============================================================
  assert/text="ECI -> TOPOCENT" /NOOP=MISS

  ! ECR -> ECI =================================================================
  assert/text="ECR -> ECI" /NOOP=MISS

  ! ECR -> ECR =================================================================
  !   ECR doesn't have any variations in form, so any ECR->ECR conversion simply
  !   returns its self.
  for key inTable sampleFilesECR
    convert sampleFilesECR.^{KEY} ECR ram:test_sv
    assert/text="ECR -> ECR (^{KEY})" sampleFilesECR.^{KEY} FEQ/D/H ram:test_sv
  endfor

  ! ECR -> TOP =================================================================
  assert/text="ECR -> TOP" /NOOP=MISS

  ! ECR -> TOPOCENT ============================================================
  assert/text="ECR -> TOPOCENT" /NOOP=MISS

  ! TOP -> ECI =================================================================
  assert/text="TOP -> ECI" /NOOP=MISS

  ! TOP -> ECR =================================================================
  assert/text="TOP -> ECR" /NOOP=MISS

  ! TOP -> TOP =================================================================
  assert/text="TOP -> TOP" /NOOP=MISS

  ! TOP -> TOPOCENT ============================================================
  assert/text="TOP -> TOPOCENT" /NOOP=MISS

  ! TOPOCENT -> ECI ============================================================
  assert/text="TOPOCENT -> ECI" /NOOP=MISS

  ! TOPOCENT -> ECR ============================================================
  assert/text="TOPOCENT -> ECR" /NOOP=MISS

  ! TOPOCENT -> TOP ============================================================
  assert/text="TOPOCENT -> TOP" /NOOP=MISS

  ! TOPOCENT -> TOPOCENT =======================================================
  assert/text="TOPOCENT -> TOPOCENT" /NOOP=MISS

return


!******************************************************************************!
! Test the CARTESIAN, SPHERICAL, CYLINDRIC, ELLIPSOID & GEODETIC functions
procedure test_coordsys
  assert/text="CARTESIAN" /NOOP=MISS
  assert/text="SPHERICAL" /NOOP=MISS
  assert/text="CYLINDRIC" /NOOP=MISS
  assert/text="ELLIPSOID" /NOOP=MISS
  assert/text="GEODETIC"  /NOOP=MISS
return

!******************************************************************************!
! Test the SV2BLUE function
procedure test_sv2blue
  ! We keep the test file zipped up since it reduces the size by ~70%
  fname zipFile OPT=SYS AREA=test NAME="nga17212.sp3.zip"
  res   sp3File "jar:file:^{zipFile}!/nga17212.sp3"

  convert sp3file{SELECTED=4} sv2blue ram:sv4_none
  convert sp3file{SELECTED=4} sv2blue ram:sv4_time{TIME_NAME=TIME}

  file open fn ram:sv4_none
    file open ft ram:sv4_time
      file open f sp3file{SELECTED=4}
        res T:fnTests {TEXT="SV2BLUE for SP3 file (no time)"}
        res T:ftTests {TEXT="SV2BLUE for SP3 file (w/ time)"}

        invoke recDefNone fn.getRecordDefs()
        invoke recDefTime ft.getRecordDefs()

        assert/group=fnTests/test 2013:01:01::00:00:00 EQ  fn.time
        assert/group=fnTests/test f.size               EQ  fn.size
        assert/group=fnTests/test 5001                 EQ  fn.type
        assert/group=fnTests/test 0.0                  EQ  fn.xstart
        assert/group=fnTests/test 300.0                EQ  fn.xdelta
        assert/group=fnTests/test 1                    EQ  fn.xunits ! 1=TIME_S
        call _checkRecDefPRM fnTests recDefNone "POS"  "VD"  0 "CARTESIAN" "DISTANCE_M"
        call _checkRecDefPRM fnTests recDefNone "VEL"  "VD" 24 "CARTESIAN" "SPEED_M_S"

        assert/group=ftTests/test 2013:01:01::00:00:00 EQ  ft.time
        assert/group=ftTests/test f.size               EQ  ft.size
        assert/group=ftTests/test 5001                 EQ  ft.type
        assert/group=ftTests/test 0.0                  EQ  ft.xstart
        assert/group=ftTests/test 300.0                EQ  ft.xdelta
        assert/group=ftTests/test 1                    EQ  ft.xunits ! 1=TIME_S
        call _checkRecDefPRM ftTests recDefTime "POS"  "VD"  0 "CARTESIAN" "DISTANCE_M"
        call _checkRecDefPRM ftTests recDefTime "VEL"  "VD" 24 "CARTESIAN" "SPEED_M_S"
        call _checkRecDefPRM ftTests recDefTime "TIME" "SD" 48 "SCALAR"    "TIME_S"

        do i 0 f.size-1
          invoke exp      f.getDataTable(i)
          invoke actNone fn.getDataTable(i)
          invoke actTime ft.getDataTable(i)

          assert/group=fnTests/test/text="row ^i" ^exp.POS  EQ/V/T ^actNone.POS  /DELTA=0.001
          assert/group=fnTests/test/text="row ^i" ^exp.VEL  EQ/V/T ^actNone.VEL  /DELTA=0.001

          assert/group=ftTests/test/text="row ^i" ^exp.POS  EQ/V/T ^actTime.POS  /DELTA=0.001
          assert/group=ftTests/test/text="row ^i" ^exp.VEL  EQ/V/T ^actTime.VEL  /DELTA=0.001
          assert/group=ftTests/test/text="row ^i" ^exp.TIME EQ/V/T ^actTime.TIME /DELTA=0.001
        enddo
        assert/group=fnTests/summary
        assert/group=ftTests/summary
      file close f
    file close ft
  file close fn
return


!******************************************************************************!
! Taken from %TEST_FILE
procedure _checkRecDefPRM T:testGroup T:recDef S:expName S:expFormat L:expOffset S:expType S:expUnits
  assert/group=testGroup/test recDef.^{expName}.NAME   EQS expName
  assert/group=testGroup/test recDef.^{expName}.FORMAT EQS expFormat
  assert/group=testGroup/test recDef.^{expName}.OFFSET EQ  expOffset
  assert/group=testGroup/test recDef.^{expName}.TYPE   EQS expType
  assert/group=testGroup/test recDef.^{expName}.UNITS  EQS expUnits
return


!******************************************************************************!
! Taken from %TEST_FILE
procedure checkRecDefPRM s:descr T:recDef S:expName S:expFormat L:expOffset S:expType S:expUnits
  assert/text="^{descr} got ^{expName}.NAME"   recDef.^{expName}.NAME   EQS expName
  assert/text="^{descr} got ^{expName}.FORMAT" recDef.^{expName}.FORMAT EQS expFormat
  assert/text="^{descr} got ^{expName}.OFFSET" recDef.^{expName}.OFFSET EQ  expOffset
  assert/text="^{descr} got ^{expName}.TYPE"   recDef.^{expName}.TYPE   EQS expType
  assert/text="^{descr} got ^{expName}.UNITS"  recDef.^{expName}.UNITS  EQS expUnits
return

! Taken from %TEST_FILE
procedure checkRecDefCSV s:descr T:recDef S:expName S:expFormat
  assert/text="^{descr} got ^{expName}.NAME"   recDef.^{expName}.NAME   EQS expName

  if (expFormat EQS "") then
    ! Should be omitted
  else
    assert/text="^{descr} got ^{expName}.FORMAT" recDef.^{expName}.FORMAT EQS expFormat
  endif
return


