/* Test DATETIME/DATETIME-TZ FORMAT validation with STRING(DATETIME, FORMAT)    */
/* Focus: time/timezone part validation                                         */
/* Date part of formats is not tested and always valid.                         */

ROUTINE-LEVEL ON ERROR UNDO, THROW.

USING OpenEdge.Core.Assert FROM PROPATH.

CLASS unittests.base.datetime.TestFormatValidation:

   /**
    * Helper method to test invalid datetime(-tz) formats or values that do not fit.
    *
    * @param fmt       The format string (time/timezone part only)
    * @param val       A valid datetime value string
    * @param errorNo   Expected error number from STRING() call
    */
   METHOD PRIVATE VOID handleTestFailure(
      INPUT fmt     AS CHARACTER,
      INPUT val     AS CHARACTER,
      INPUT errorNo AS INTEGER):

      DEFINE VARIABLE result AS CHARACTER NO-UNDO FORMAT 'X(128)'.

      result = STRING(DATETIME(val), fmt) NO-ERROR.

      Assert:IsTrue(ERROR-STATUS:ERROR, "STRING() should raise an error").
      Assert:Equals(errorNo, ERROR-STATUS:GET-NUMBER(1)).
   END METHOD.

   @Before.
   METHOD PUBLIC VOID BeforeClass():
      SESSION:SET-NUMERIC-FORMAT(",",".").
      SESSION:DATE-FORMAT = "mdy".
   END METHOD.

   @Test.
   METHOD PUBLIC VOID testTimeFailures():
      /* All tests expect format error 22 "Character number N of format F is invalid." */

      handleTestFailure("H", "01/02/2000 01:02", 22). /* 'H' offending */

      /* Tests currently failing in FWD (no error raised) */
      handleTestFailure("99/99/9999 HHH:a", "01/02/2000 01:02", 22).  /* 'a' offending */
      handleTestFailure("99/99/9999 HHH::", "01/02/2000 01:02", 22).  /* double colon offending */
      handleTestFailure("99/99/9999 HHH:MH", "01/02/2000 01:02", 22). /* last 'H' offending */
      handleTestFailure("99/99/9999 H P",   "01/02/2000 01:02", 22).  /* 'P' offending */
      
      handleTestFailure("99/99/9999 HH:MM:SSSSSS",   "01/02/2000 01:02", 14312).  /* Too many S */
      handleTestFailure("99/99/9999 HH:MM:SSSSSS",   "01/02/2000 01:02", 14312).  /* Too many S */
      handleTestFailure("99/99/9999 HH:MM:SSSS.SS",   "01/02/2000 01:02", 14312).  /* Too many S */
      handleTestFailure("99/99/9999 HH:MM:SSS+HH:MMSSS",   "01/02/2000 01:02", 14312).  /* Too many S */
      handleTestFailure("99/99/9999 SHH:MSSM:SS+HH:MM",   "01/02/2000 01:02", 22).
      handleTestFailure("99/99/9999 SSSSHH:MM:SS+HH:MM",   "01/02/2000 01:02", 14312).
      
   END METHOD.

   @Test.
   METHOD PUBLIC VOID testTimezoneOffsetFailures():
      /* Tests currently failing in FWD (no error raised) */
      handleTestFailure("99/99/9999 HH:MM +",  "01/02/2000 01:02", 22). /* '+' without space */
      handleTestFailure("99/99/9999 HH:MM+a",  "01/02/2000 01:02", 22). /* 'a' offending */
   END METHOD.

   @Test.
   METHOD PUBLIC VOID testSuccess():
      /* All tests expect error 74 "Value S cannot be displayed using F." */

      /* Tests currently failing in FWD (format validation error 22 raised instead) */
      handleTestFailure(" H",       "01/02/2000 01:02", 74).
      handleTestFailure(" HH:MM",   "01/02/2000 01:02", 74).
   END METHOD.
      
END CLASS.
