!******************************************************************************!
! Tests smart versioning of DataFiles and the role of 'Z' type data
! Makes sure BLUE VER is bumped to 1.2 if 'Z' Format Type is included
! Shows 'A' and 'Z' are not valid Keyword Types - they become 'S' String
! Shows that Keyword data that is Table String can contain 'A' ASCII & 'z' boolean, but not 'Z' 256 ASCII
!
! Arguments: Test to call
!
! @bug      NXM-3570 'Z' Data Type
! @since    3.9.4
! @author:  Jeanette McCall
!******************************************************************************!
startmacro s:func[""]
  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)

  invoke ASCII    nxm.sys.inc.DataTypes.ASCII
  invoke ASCII256 nxm.sys.inc.DataTypes.ASCII256
  res expectedException ""

  call setDatDir
  ! Allow some of the tests to run in a thinned NeXtMidas by skipping only ones needing missing dependencies - 4.0.0
  invoke convertExists reg.shell.M.dictionary.isDictionaryEntry(CONVERT)

  res test_output ram:test_256ascii_out.tmp
  res test_inout  ram:test_256ascii_inout.tmp

  if func NEQS "" then
    call test_^{func}
  else
    if convertExists then call test_blue_ver
    call test_valid_keywords
    call test_invalid_z_bool_keyword
    call test_invalid_z_bool_keyword_typed
    call test_invalid_Z_ASCII_keyword_typed
  endif


endmacro

!******************************************************************************!
! Main process message for this macro. Should be right after the ENDMACRO.
!******************************************************************************!
procedure processMessage m:msg
  if msg.name eqs "MAIN" then
    assert/text="^reg.main.name: User indicated tests" msg.data eqss "PASS"
    pipe stop
  else
    say "Unhandled message name: ^msg.name from fid: ^msg.fid data: ^msg.data"
  endif
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

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

!******************************************************************************!
! NOOP of 1.1 file creates 1.1 file unless input file has 'Z' type
!******************************************************************************!
procedure noopFile fn:inputFile fn:outputFile S:expectedBlueVer S:description

  noop inputFile outputFile
  keyword outputFile get name=ver value=blueVer

  assert/text="^reg.main.name: ^description" blueVer EQS expectedBlueVer

return

!******************************************************************************!
! Tests that the DataFile gets the proper BLUE VER (1.1 or 1.2)
!******************************************************************************!
procedure test_blue_ver

  ! creation of file without 'Z' data should produce 1.1 file
  waveform test_output
  key test_output get name=VER value=blueVer
  assert/text="^reg.main.name: waveform creates 1.1 file" blueVer EQS "1.1"

  ! 1.1 file NOOP should create 1.1
  call noopFile ^{datDir}.cities.prm test_output "1.1" "NOOP of 1.1 creates 1.1"

  ! creation of file with 'Z' data should produce 1.2 file
  convert nxm.sys.test.cities_256ascii.txt T2B test_inout d4|2x|d10|4x|d12|1x|z256 3
  key test_inout get name=VER value=blueVer
  assert/text="^reg.main.name: file created with 'Z' is 1.2 file" blueVer EQS "1.2"

  ! 1.2 file NOOP should create 1.2
  call noopFile test_inout test_output "1.2" "NOOP of 1.2 creates 1.2"

return

!******************************************************************************!
! Tests / Illustrates allowed Keyword types
!******************************************************************************!
procedure test_valid_keywords

  waveform test_output
  new nxm.sys.lib.Data(hellothereeveryone) adata
  res Z:truebool true
  new nxm.sys.lib.Data(truetruetrue,truebool) zData
  res B:zType zData.type
  assert/text="^reg.main.name: created 'Z' data object" zType EQ ASCII256
  
  keyword test_output add myakey    adata
  keyword test_output add a:myakey2 adata
  keyword test_output add myzkey    zdata
  keyword test_output add mytablekey {myakey=adata,A:myakey2=adata,Z:myzboolkey=^truebool,myzboolkey2=^truebool,myzasciikey=^zData}

  ! All Strings of all types get stored as 'S' type
  keyword test_output get name=myakey  value=myavalue
  assert/text="^reg.main.name: 'A' Data becomes 'S' KEYWORD type" myavalue instanceof java.lang.String
  keyword test_output get name=myakey2  value=myavalue2
  assert/text="^reg.main.name: A:KEY 'A' Data becomes 'S' KEYWORD type" myavalue2 instanceof java.lang.String
  keyword test_output get name=myzkey  value=myzvalue
  assert/text="^reg.main.name: 'Z' Data becomes 'S' KEYWORD type" myzvalue instanceof java.lang.String

  ! Table does allow 'A' type, but unless directly typed it becomes 'S'
  ! A directly typed 'Z' in a table is assumed to be 'z' boolean type
  keyword test_output get name=mytablekey value=T:mykwtable
  res tbl_myavalue mykwtable.myakey
  assert/text="^reg.main.name: 'A' Data in table defaults to 'S' type" tbl_myavalue instanceof java.lang.String
  res tbl_myavalue2 mykwtable.myakey2
  res B:tbl_myavalue2_type tbl_myavalue2.type
  assert/text="^reg.main.name: A:KEY 'A' Data in table keeps 'A' type" tbl_myavalue2_type EQ ASCII
  res tbl_myzboolvalue mykwtable.myzboolkey
  assert/text="^reg.main.name: Z:Key 'z' Data in table is Boolean" tbl_myzboolvalue instanceof java.lang.Boolean
  res tbl_myzboolvalue2 mykwtable.myzboolkey2
  assert/text="^reg.main.name: 'z' Boolean Data in table become 'S' String" tbl_myzboolvalue2 instanceof java.lang.String
  res tbl_myzasciivalue mykwtable.myzasciikey
  assert/text="^reg.main.name: 'Z' ASCII Data in table becomes 'S' String" tbl_myzasciivalue instanceof java.lang.String

return

!******************************************************************************!
! Tests boolean 'z' Data can not be directly stored in Keyword
!******************************************************************************!
procedure test_invalid_z_bool_keyword_typed

  info "Testing invalid setting of Keyword to type 'Z' when value 'z' boolean result" 
  res expectedException "Illegal Keyword Data type: true"
  res Z:truebool true
  keyword test_output add Z:myzkey truebool

return

!******************************************************************************!
! Tests boolean 'z' Data can not be directly stored in Keyword
!******************************************************************************!
procedure test_invalid_Z_ASCII_keyword_typed

  info "Testing invalid setting of Keyword to type 'Z' when value 'Z' 256 ASCII" 
  res expectedException "Unable to convert ASCII256_data to type Z"
  new nxm.sys.lib.Data(ASCII256_data,truebool) zData
  keyword test_output add Z:myzkey zData

return


!******************************************************************************!
! Tests KeyWord type can not be forced to 'Z' ASCII
!******************************************************************************!
procedure test_invalid_z_bool_keyword

  info "Testing invalid setting of Keyword value to 'z' boolean result" 
  res expectedException "Illegal Keyword Data type: true"
  res Z:truebool true
  keyword test_output add myzkey truebool

return
