!**************************************************************************************************!
!  Purpose:  Test convert XML2TAB, TAB2XML, XML2TBL and TBL2XML functions
!
!  Author :  J. Hallam
!**************************************************************************************************!
startmacro

  set macroName "TEST_CONVERT"
  call setDatDir

  ! Original test using known input/output files
  call test_xml2table_and_table2xml

  ! Test the XML2TAB conversion
  call test_xml2tab

  ! Test XML2TAB / TBL2XML as a pair
  call test_xml2tab_tab2xml

  ! Convert a table to an XML text file and back
  call test_tbl2XML_xml2tbl_textfile

  ! Convert a table to an XML text file and back
  call test_tbl2XML_xml2tbl_string

  ! test conversion of XML with single tics
  call test_xml2tbl_withsingletics

  ! test conversion of XML with '.' in key name
  call test_xml2tab_dot_key

  ! test conversion of Type 5000 point in time to a KML file
  call test_sv2kml   ! Bug 2561
  

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

!******************************************************************************!
! Test conversions using xml2tbl and tbl2xml
!******************************************************************************!
procedure test_xml2table_and_table2xml S:testFile
  !DO NOT ERASE THESE XML FILES - they are in CVS!!!
  fname inXMLFile area=test name=test_xml ext=xml
  fname outXMLFile area=aux.write name=test_xml2 ext=xml opt=aux
  result myStatus 1
  result testName "XML2TBL/TBL2XML"
  if inXMLFile FEXISTS
    convert inXMLFile XML2TBL txml
    convert txml TBL2XML outXMLFile

    assert/TEXT="^macroName: ^testName: Num entries in table"/stat=status txml.getsize EQ 3
    if status eqs "PASS"
      assert/TEXT="^macroName: ^testName: Found TABLE result 1" txml.table REXISTS
      assert/TEXT="^macroName: ^testName: Found TABLE result 2" txml.table__1 REXISTS
      assert/TEXT="^macroName: ^testName: Found TABLE__2 result 3" txml.table__2 REXISTS
    endif
  else
    assert/TEXT="^macroName: ^testName: Can not find XML input file ^inXMLFile" false
  endif

  !DO NOT ERASE THE INPUT XML FILES!!!
  erase/all outXMLFile
return

!******************************************************************************!
!  Test conversions using xml2tab
!******************************************************************************!
procedure test_xml2tab
  !!!!!!!!!!! Unique names
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <FOO A='1' B='2'/>"
  file write filetag "</XML>"
  file close filetag

  CONVERT temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize}  " 1 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table FOO.A=^{tab.foo.a} " 1 eq ^{tab.foo.a}
  assert/text="^macroName: XML2TAB table FOO.B=^{tab.foo.b} " 2 eq ^{tab.foo.b}


  !!!!!!!!!!! Duplicate names
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <FOO a='1' b='2'/>"
  file write filetag "  <FOO a='3' b='4'/>"
  file write filetag "  <FOO a='5' b='6'/>"
  file write filetag "</XML>"
  file close filetag

  CONVERT temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize} " 3 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table FOO_1.A=^{tab.foo_1.a} " 1 eq ^{tab.foo_1.a}
  assert/text="^macroName: XML2TAB table FOO_1.B=^{tab.foo_1.b} " 2 eq ^{tab.foo_1.b}
  assert/text="^macroName: XML2TAB table FOO_2.A=^{tab.foo_2.a} " 3 eq ^{tab.foo_2.a}
  assert/text="^macroName: XML2TAB table FOO_2.B=^{tab.foo_2.b} " 4 eq ^{tab.foo_2.b}
  assert/text="^macroName: XML2TAB table FOO_3.A=^{tab.foo_3.a} " 5 eq ^{tab.foo_3.a}
  assert/text="^macroName: XML2TAB table FOO_3.B=^{tab.foo_3.b} " 6 eq ^{tab.foo_3.b}


  !!!!!!!!!!! Normal CDATA
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <FOO A='1' B='2'>"
  file write filetag "    &lt;Hello World&gt;"
  file write filetag "  </FOO>"
  file write filetag "</XML>"
  file close filetag

  CONVERT temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize}  " 1 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table FOO.A=^{tab.foo.a} " 1 eq ^{tab.foo.a}
  assert/text="^macroName: XML2TAB table FOO.B=^{tab.foo.b} " 2 eq ^{tab.foo.b}
  assert/text="^macroName: XML2TAB table FOO.CDATA=^{tab.foo.cdata} " "<Hello World>" eqs "^{tab.foo.cdata}"

  !!!!!!!!!!! Special CDATA Section
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <FOO A='1' B='2'>"
  file write filetag "    <![CDATA[<Hello World>]]>"
  file write filetag "  </FOO>"
  file write filetag "</XML>"
  file close filetag

  CONVERT temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize}  " 1 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table FOO.A=^{tab.foo.a} " 1 eq ^{tab.foo.a}
  assert/text="^macroName: XML2TAB table FOO.B=^{tab.foo.b} " 2 eq ^{tab.foo.b}
  assert/text="^macroName: XML2TAB table FOO.CDATA=^{tab.foo.cdata} " "<Hello World>" eqs "^{tab.foo.cdata}"

  !!!!!!!!!!! Test compression
  CONVERT/COMP=F "<XML><GREETING>Hello</GREETING></XML>"        xml2tab/s tab1
  CONVERT/COMP=T "<XML><GREETING>Hello</GREETING></XML>"        xml2tab/s tab2
  CONVERT/COMP=T "<XML><GREETING ID='2'>Hello</GREETING></XML>" xml2tab/s tab3

  assert/text="^macroName: XML2TAB /COMP=F (no ID=) GREETING.CDATA=^{tab1.GREETING.CDATA}" &
                                                 "Hello" eqs "^{tab1.GREETING.CDATA}"
  assert/text="^macroName: XML2TAB /COMP=T (no ID=) GREETING=^{tab2.GREETING}" &
                                                 "Hello" eqs "^{tab2.GREETING}"
  assert/text="^macroName: XML2TAB /COMP=T (ID='2') GREETING.CDATA=^{tab3.GREETING.CDATA}" &
                                                 "Hello" eqs "^{tab3.GREETING.CDATA}"


  !!!!!!!!!!! Other special tags #1 (Example 1 in Section 2.8 of "Extensible Markup
  !!!!!!!!!!! Language (XML) 1.0 (Third Edition)" http://www.w3.org/TR/REC-xml/)
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<?xml version="1.0"?>"
  file write filetag "<!DOCTYPE greeting SYSTEM 'hello.dtd'>"
  file write filetag "<greeting>Hello, world!</greeting>"
  file close filetag

  CONVERT/comp temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize}" 1 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table GREETING=^{tab.GREETING}" "Hello, world!" eqs "^{tab.GREETING}"


  !!!!!!!!!!! Other special tags #2 (Example 2 in Section 2.8 of "Extensible Markup
  !!!!!!!!!!! Language (XML) 1.0 (Third Edition)" http://www.w3.org/TR/REC-xml/)
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<?xml version="1.0"?>"
  file write filetag "<!DOCTYPE greeting ["
  file write filetag "  <!ELEMENT greeting (#PCDATA)>"
  file write filetag "]>"
  file write filetag "<greeting>Hello, world!</greeting>"
  file close filetag

  CONVERT/comp temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB table size=^{tab.getsize}" 1 eq ^{tab.getsize}
  assert/text="^macroName: XML2TAB table GREETING=^{tab.GREETING}" "Hello, world!" eqs "^{tab.GREETING}"


  !!!!!!!!!!! Test useRootForRes switch
  !!!!!!!!!!!
  file open/t/n filetag temp_convert.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <FOO A='1' B='2'>"
  file write filetag "  </FOO>"
  file write filetag "</XML>"
  file close filetag

  CONVERT/useRootForRes temp_convert.xml xml2tab tab

  assert/text="^macroName: XML2TAB useRootForRes table size=^{xml.getsize}  " 1 eq ^{xml.getsize}
  assert/text="^macroName: XML2TAB useRootForRes table FOO.A=^{xml.foo.a} " 1 eq ^{xml.foo.a}
  assert/text="^macroName: XML2TAB useRootForRes table FOO.B=^{xml.foo.b} " 2 eq ^{xml.foo.b}

  erase/quiet/warn=n temp_convert.xml

return

!******************************************************************************!
!  Test conversions using xml2tab/tab2xml
!******************************************************************************!
procedure test_xml2tab_tab2xml
  ! Duplicate names and normal CDATA
  !
  file open/t/n filetag temp_convert_xml2tab_tab2xml_in.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <INNER>"
  file write filetag "    <FOO a='1' b='2'/>"
  file write filetag "    <FOO a='3' b='4'/>"
  file write filetag "    <FOO a='5' b='6'/>"
  file write filetag "    <FOO>Hello World</FOO>"
  file write filetag "  </INNER>"
  file write filetag "</XML>"
  file close filetag

  !
  ! Table to XML without new lines
  !
  CONVERT temp_convert_xml2tab_tab2xml_in.xml xml2tab tab1    ! XML to a Table
  CONVERT tab1 tab2xml temp_convert_xml2tab_tab2xml_out /NEWLINES=F  ! Table to XML
  file open/t filetag temp_convert_xml2tab_tab2xml_out.xml{FLAGS=FORCEABORT}
    file read filetag xml
  file close filetag

  assert/text="^macroName: TAB2XML - test 1" "^xml" EQS &
     "<XML><INNER><FOO A="1" B="2"/><FOO A="3" B="4"/><FOO A="5" B="6"/><FOO>Hello World</FOO></INNER></XML>"

  !
  ! Back from XML to table
  !
  CONVERT temp_convert_xml2tab_tab2xml_out.xml xml2tab tab2
  TABLE tab1 EQUALS tab2 same
  assert/text="^macroName: XML2TAB - duplicate names and CDATA" same istrue

  ! Make sure we can treat A='1' as a double
  res S:aval tab2.inner.foo_1.a
  assert/text="^macroName: XML2TAB - access to values TAB2.INNER.FOO_1.A" aval EQS "1"

  erase/quiet/warn=n temp_convert_xml2tab_tab2xml_in.xml
  erase/quiet/warn=n temp_convert_xml2tab_tab2xml_out.xml

  !
  !
  !
  res xml "<XML></XML>"  ! Make sure the output is picked untranslated
  set tab {ROW1={a=1,b=2},CDATA="ASTRING",ROW2={}}
  CONVERT tab tab2xml/s xml /newlines=f  ! Table to XML

  assert/text="^macroName: TAB2XML - test 2" "^xml" EQS &
    "<XML><ROW1 A="1" B="2"/>ASTRING<ROW2/></XML>"

  res tab {ROW_____1={X=1,Y=2}}
  convert/delim="_____" tab tab2xml temp_convert_tab2xml_out
  convert temp_convert_tab2xml_out.xml xml2tab tab2
  assert/text="^macroName: TAB2XML - long delimiter" tab2 CONTAINS "ROW"

  erase/all temp_convert_tab2xml_out.xml

return

!******************************************************************************!
! Convert table WITH an INNER table to XML and then back
!******************************************************************************!
procedure test_tbl2XML_xml2tbl_textfile
  result S:testFile "test_convert_tbl2xml.xml"
  remove tab
  result tab {}
  result tab.innertable {SNR=1,FREQ=2}
  convert tab TBL2XML testFile
  remove tabout
  convert testFile XML2TBL tabout

  assert/TEXT="^macroName: TBL2XML/XML2TBL(TextFile,w/inner): table found"/stat=status &
         tabout.innertable.snr REXISTS AND tabout.innertable.freq REXISTS
  if status eqs "PASS" then
    assert/TEXT="^macroName: TBL2XML/XML2TBL(TextFile,w/inner)" &
           tab.innertable.snr eq tabout.innertable.snr AND &
           tab.innertable.freq eq tabout.innertable.freq
  endif
  erase/all testFile

!
!  Convert a table WITHOUT an inner table to XML and back
!
  result testFile "test_convert_tbl2xml_no_inner.xml"
  result tab {SNR=1,FREQ=2}
  convert tab TBL2XML testFile
  remove tabout
  convert testFile XML2TBL tabout
  if tabout.snr REXISTS AND tabout.freq REXISTS then
    assert/TEXT="^macroName: TBL2XML/XML2TBL (TextFile,w/o inner )" &
         tab.snr eq tabout.snr AND tab.freq EQ tabout.freq
  else
    assert/TEXT="^macroName: TBL2XML/XML2TBL (TextFile,w/o inner); NO out table" false
  endif
  erase/all testFile

!
!  Convert a LARGE table to XML and then back to a table
!
  result testFile "test_convert_tbl2xml_large.xml"
  set tab {}
  do i 1 1000
    set tab.x^i i
  enddo
  convert tab TBL2XML testfile
  convert testfile XML2TBL tabout
  if testfile FEXISTS then
    if tab.getsize EQ tabout.getsize then
      set notSame "FALSE"
      foreach key INTAB tab
        if tab.^key NEQ tabout.^key then
          set notSame "TRUE"
        endif
      endfor
      assert/TEXT="^macroName: TBL2XML/XML2TBL large; in TABLE = out TABLE" NOTSAME EQS "FALSE"
    else
      assert/TEXT="^macroName: TBL2XML/XML2TBL large; same size" false
    endif
  else
    assert/TEXT="^macroName: TBL2XML/XML2TBL large; FEXISTS" false
  endif
  erase testfile

return

!******************************************************************************!
! Convert a table WITH an inner table to an XML string and back
!******************************************************************************!
procedure test_tbl2xml_xml2tbl_string
  ! Convert to XML
  remove tabTruth
  result tabTruth {INNERTABLE={SNR=1,FREQ=2}}
  remove xmlTruth
  result s:xmlTruth "<XML><INNERTABLE SNR="1" FREQ="2" /></XML>"
  convert tabTruth TBL2XML/S stringOut
  assert/TEXT="^macroName: TBL2XML/S (String,with inner)" stringOut EQS xmlTruth

  ! Convert back to table
  remove tabout
  convert xmlTruth XML2TBL/S tabout
  assert/TEXT="^macroName: XML2TBL(String,with inner)" &
         tabTruth.innertable.snr eq tabout.innertable.snr AND &
         tabTruth.innertable.freq eq tabout.innertable.freq

!
! Convert a table WITHOUT an inner table to an XML string and back
!
  ! Convert to XML
  remove tabTruth
  result tabTruth {SNR="1",FREQ="2"}
  remove xmlTruth
  result s:xmlTruth "<XML SNR="1" FREQ="2" />"
  remove stringOut
  convert tabTruth TBL2XML/S stringOut
  assert/TEXT="^macroName: TBL2XML/S (String,without inner)" stringOut EQS xmlTruth

  ! Convert back to table
  remove tabout
  convert xmlTruth XML2TBL/S tabout
  assert/TEXT="^macroName: XML2TBL(String,without inner)" &
         tabTruth.snr eqs tabout.snr AND tabTruth.freq eqs tabout.freq
return

!******************************************************************************!
!  Test conversions using xml2tbl where the XML contains single tics
!******************************************************************************!
procedure test_xml2tbl_withsingletics
  ! Simple XML with single tics surrounding values
  !
  file open/t/n filetag temp_convert_xml2tbl_single_tics.xml{FLAGS=FORCEABORT}
  file write filetag "<XML>"
  file write filetag "  <INNER>"
  file write filetag "    <FOO a='1' b='2'/>"
  file write filetag "    <FOO a='3' b='4'/>"
  file write filetag "    <FOO a='5' b='6'/>"
  file write filetag "    <FOO>Hello World</FOO>"
  file write filetag "  </INNER>"
  file write filetag "</XML>"
  file close filetag

  remove tbl
  CONVERT temp_convert_xml2tbl_single_tics.xml xml2tbl tbl    ! XML to a Table

  ! Make sure we can treat A='1' and B='2' as doubles
  res D:aval tbl.inner.foo.a
  res D:bval tbl.inner.foo.b
  assert/text="^macroName: XML2TBL - XML with single tics A='1' and B='2' " aval EQ 1 AND bval EQ 2

  erase temp_convert_xml2tbl_single_tics.xml

return

!******************************************************************************!
!  Test conversions using xml2tbl where the XML contains keys with '.'in name
!******************************************************************************!
procedure test_xml2tab_dot_key

  call createDotKeyTable2Entries tab_rel1 VERSION.NUMBER 4.0.X TYPE.OF.RELEASE "stable series"
  call createDotKeyTable2Entries tab_rel2 VERSION.NUMBER 4.1.X TYPE.OF.RELEASE "beta series"
  call createDotKeyTable2Entries tab_exp RELEASE.SERIES_1 tab_rel1 RELEASE.SERIES_2 tab_rel2

  convert nxm.sys.test.test_convert_dot_in_key.xml xml2tab tab_actual

  TABLE tab_exp getKey RELEASE.SERIES_1 S:expStr
  TABLE tab_actual getKey RELEASE.SERIES_1 S:actStr
  assert/TEXT="^macroName: XML2TBL - XML with '.' in keys" expStr EQS actStr

return

!******************************************************************************!
!   Creates a +AllowDotsInKey with two entries
!******************************************************************************!
procedure createDotKeyTable2Entries name key1 U:value1 key2 U:value2
  TABLE ^name CREATE
  table ^name setflags "+AllowDotsInKeys"
  if ^value1 instanceof java.lang.String then
    table ^name setkey ^key1 "^value1"
  else 
    table ^name setkey ^key1 ^value1
  endif
  if ^value2 instanceof java.lang.String then
    table ^name setkey ^key2 "^value2"
  else
    table ^name setkey ^key2 ^value2
  endif
return

!******************************************************************************!
!   Tests the conversion of state vectors from a Type 5000 file into a KML
!   formatted output file
!******************************************************************************!
procedure test_sv2kml

assert/text="SV2KML -> Experimental functionality, test case is invalid" /NOOP=MISS
return

  ! Assert that converting to a POINT format matches expected output
  CONVERT ^{datDir}.sv3.prm SV2KML testkml1.kml OPTIONS={time=3000}

  assert/TEXT="^macroName: SV2KML - KML with a POINT format" testkml1.kml feq nxm.sys.test.test_point.kml

  CONVERT  ^{datDir}.sv3.prm SV2KML/S mykmlstring OPTIONS={time=3000}

  ! test above, but in String (result) form
  FILE open/T tag1 nxm.sys.test.test_point.kml
    res str1 tag1.readall()
  FILE close tag1

  assert/TEXT="^macroName: SV2KML/S - KML with a POINT format" mykmlstring EQS str1


  ! Assert that converting to a LINESTRING format matches expected output
  CONVERT ^{datDir}.sv3.prm SV2KML testkml2.kml OPTIONS={format=linestring,iconscale=4,&
                   iconcolor=FFFF0000,begin=3000,end=4300,href="icon56.png"}

  ! convert to a table and get the coords values for checking
  convert testkml2.kml XML2TAB tab
  res s:cdata  ^{tab.document.placemark.linestring.coordinates.cdata}  ! get data
  sedit cdata cdata "GSUBS" "\n" ","  ! remove line breaks
  sedit cdata data "PARSEALL"         ! parse into an array
  res gold (-139.64975036180772,33.710040131442234,2.342334304574854E7,-139.6634677558201,35.372970077382526,&
            2.321361779621529E7,-139.60615314095176,37.04646121373031,2.2997705597763248E7,-139.4690132777146,&
            38.72962030792267,2.2775772912276145E7,-139.24195589673337,40.42121579698329,2.2548000699409988E7)

  ! asserts below are to use tolerence when checking the coordinate values generated
  assert/text="^macroName: Check interpolated coords POSX1" data(0) eqt gold(0)
  assert/text="^macroName: Check interpolated coords POSY1" data(1) eqt gold(1)
  assert/text="^macroName: Check interpolated coords POSZ1" data(2) eqt gold(2)
  assert/text="^macroName: Check interpolated coords POSX2" data(3) eqt gold(3)
  assert/text="^macroName: Check interpolated coords POSY2" data(4) eqt gold(4)
  assert/text="^macroName: Check interpolated coords POSZ2" data(5) eqt gold(5)
  assert/text="^macroName: Check interpolated coords POSX3" data(6) eqt gold(6)
  assert/text="^macroName: Check interpolated coords POSY3" data(7) eqt gold(7)
  assert/text="^macroName: Check interpolated coords POSZ3" data(8) eqt gold(8)
  assert/text="^macroName: Check interpolated coords POSX4" data(9) eqt gold(9)
  assert/text="^macroName: Check interpolated coords POSY4" data(10) eqt gold(10)
  assert/text="^macroName: Check interpolated coords POSZ4" data(11) eqt gold(11)
  assert/text="^macroName: Check interpolated coords POSX5" data(12) eqt gold(12)
  assert/text="^macroName: Check interpolated coords POSY5" data(13) eqt gold(13)
  assert/text="^macroName: Check interpolated coords POSZ5" data(14) eqt gold(14)

  !  check below commented out because the coordinates do not get created exactly the same on every box
  !assert/TEXT="^macroName: SV2KML - KML with a LINESTRING format" testkml2.kml feq nxm.sys.test.test_linestring.kml


  ! Assert that converting to a MODEL format matches expected output
  CONVERT ^{datDir}.sv3.prm SV2KML testkml3.kml OPTIONS={format="MODEL",time=(8000,9000),xscale=4000,&
          yscale=4000,zscale=4000,href="http://nextmidas.com/nextmidas/imgs/35a.dae"}

  assert/TEXT="^macroName: SV2KML - KML with a MODEL format" testkml3.kml feq nxm.sys.test.test_model.kml

  erase testkml1.kml testkml2.kml testkml3.kml

return

