!******************************************************************************!
! Test tables with dots in keys and related commands
!
! Arguments: None
!
! @bug      NXM-3772
! @since    NeXtMidas 4.0.1
! @author : Jeanette McCall

!******************************************************************************!
startmacro

  invoke convertExists reg.shell.M.dictionary.isDictionaryEntry(CONVERT)

  table myTab create {EASY={STILLEASY={BONUS=EASY}}}

  ! When getting or setting with a table with dotted keys, there are a few general things to consider:
  ! 1. RES is useless for getting or putting dotted key entries, since RES puts and gets entries 
  !    with respect to the results table, which does NOT have +AllowDotsInKeys
  !    RES can be used to get a nested table only if the levels of nesting contain non-dotted keys
  ! 2. The inner table in which the dotted key resides grabbed via RES,
  !    but then TABLE sETKEY or GETKEY must be used to actual get or set any values
  !    underneath a dotted key
  ! 3. Any table containing the dotted key should have +AllowDotsInKeys
  !    enabled before adding dotted keys. This includes tables that are going to
  !    be inner tables
  !    NOTE: setflag does NOT PROPAGATE to inner tables within an outer table

  ! RES will work with non-dotted keys
  res bonus myTab.easy.stilleasy.bonus
  assert/text="Using RES, BONUS=EASY" bonus eqs "EASY"

  ! When setting a dotted key in a table, setkey must be used
  res stillEasy myTab.easy.stilleasy        ! Use RES to reference the inner table directly
  table stillEasy setflags +AllowDotsInKeys ! Set flag specifically for inner table to enable dotted keys
  table stillEasy setkey now.hard here      ! myTab = {EASY={STILLEASY={BONUS=EASY,NOW.HARD=HERE}}}
  assert/text="With setkey, Table = {EASY={STILLEASY={BONUS=\"EASY\",NOW.HARD=\"HERE\"}}}" &
                                    "^myTab" eqs "{EASY={STILLEASY={BONUS=\"EASY\",NOW.HARD=\"HERE\"}}}"

  ! When getting a dotted key from a table, getkey must be used
  table stillEasy getkey now.hard nowHard
  assert/text="With getkey, now.hard = \"HERE\"" nowHard eqs "HERE"

  ! When adding a new inner table containing dotted keys, the inner/outer table
  ! containing the dotted keys must have +allowDotsInKeys enabled
  table nowMedium create
  table nowMedium setflags +AllowDotsInKeys
  table nowMedium setkey STILL.MEDIUM MEDIUM ! nowMedium = {STILL.MEDIUM=MEDIUM}
  assert/text="With setkey, new Table = {STILL.MEDIUM=\"MEDIUM\"}" "^nowMedium" eqs "{STILL.MEDIUM=\"MEDIUM\"}"
  res easy myTab.easy
  table easy setflags +AllowDotsInKeys
  table easy setkey NOW.MEDIUM nowMedium ! myTab = {EASY={STILLEASY={BONUS=EASY,NOW.HARD=HERE},NOW.MEDIUM={STILL.MEDIUM=MEDIUM}}}
  assert/text="With setkey, Table = {EASY={STILLEASY={BONUS=\"EASY\",NOW.HARD=\"HERE\"},NOW.MEDIUM={STILL.MEDIUM=\"MEDIUM\"}}}" &
                                    "^myTab" eqs "{EASY={STILLEASY={BONUS=\"EASY\",NOW.HARD=\"HERE\"},NOW.MEDIUM={STILL.MEDIUM=\"MEDIUM\"}}}"

  ! Additional tests for testing dotted-key behavior
  if convertExists then
    call test_keymod_from_dot_key
    call test_keymod_to_dot_key
  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

!******************************************************************************!
!  Test using KEYMOD to replace dots in keys with <DOT>
!******************************************************************************!
procedure test_keymod_from_dot_key

  convert nxm.sys.test.test_convert_dot_in_key.xml xml2tab tab_actual
  table tab_actual KEYMOD "\\." "<DOT>"
  TABLE tab_expected CREATE {RELEASE<DOT>SERIES_1={VERSION<DOT>NUMBER = 4.0.X,TYPE<DOT>OF<DOT>RELEASE = "stable series"},&
                     RELEASE<DOT>SERIES_2={VERSION<DOT>NUMBER = 4.1.X,TYPE<DOT>OF<DOT>RELEASE = "beta series"}}
  TABLE tab_actual EQUALS tab_expected tabequal
  assert/text="^reg.main.name: KEYMOD '.' -> <DOT>" tabequal isTrue

return

!******************************************************************************!
!  Test using KEYMOD to replace <DOT> in keys with dots
!******************************************************************************!
procedure test_keymod_to_dot_key

  TABLE tab_actual CREATE {RELEASE<DOT>SERIES_1={VERSION<DOT>NUMBER = 4.0.X,TYPE<DOT>OF<DOT>RELEASE = "stable series"},&
                     RELEASE<DOT>SERIES_2={VERSION<DOT>NUMBER = 4.1.X,TYPE<DOT>OF<DOT>RELEASE = "beta series"}}
  table tab_actual KEYMOD "<DOT>" "."
  convert nxm.sys.test.test_convert_dot_in_key.xml xml2tab tab_expected
  TABLE tab_actual EQUALS tab_expected tabequal
  assert/text="^reg.main.name: KEYMOD <DOT> -> '.'" tabequal isTrue

return
