/**
  Tests for INDEX function
*/

USING OpenEdge.Core.Assert.

ROUTINE-LEVEL ON ERROR UNDO, THROW.

CLASS unittests.FIndex:

   /**
    * Tests for succesfull INDEX function invocation for CHARACTER arguments
    */
   @Test.
   METHOD PUBLIC VOID TestCharacterSuccess():
      DEFINE VARIABLE undef AS CHARACTER NO-UNDO.
      undef = ?.      
      DEFINE VARIABLE undefIdx AS INTEGER NO-UNDO.
      undefIdx = ?.      
      
      // If any of arguments is undefined, return undefined
      Assert:IsNull(INDEX(undef, "c")).
      Assert:IsNull(INDEX("asdf", undef)).
      Assert:IsNull(INDEX("asdf", "c", undefIdx)).
      
      Assert:Equals(3, INDEX("abcd", "c")).
      Assert:Equals(1, INDEX("cbcd", "c")).

      Assert:Equals(0, INDEX("cbcd", "c", 5)).
      Assert:Equals(0, INDEX("cbcd", "c", 4)).
      Assert:Equals(3, INDEX("cbcd", "c", 3)).
      Assert:Equals(3, INDEX("cbcd", "c", 2)).
      Assert:Equals(1, INDEX("cbcd", "c", 1)).
      Assert:Equals(0, INDEX("cbcd", "c", 32000)).
      
      Assert:Equals(1, INDEX("ab", "ab")).
      Assert:Equals(0, INDEX("ab", "ab", 2)).
      Assert:Equals(1, INDEX("ab", "ab", 1)).
      
      // Not found cases
      Assert:Equals(0, INDEX("abcd", "e")).
      Assert:Equals(0, INDEX("cbcd", "e")).
      
      // Empty string cases
      Assert:Equals(0, INDEX("", "e")).
      Assert:Equals(0, INDEX("cbcd", "")).
   END METHOD.

   /**
    * Tests for succesfull INDEX function invocation for LONGCHAR arguments
    */
   @Test.
   METHOD PUBLIC VOID TestLongcharSuccess():
      DEFINE VARIABLE undef AS LONGCHAR NO-UNDO.
      undef = ?.
      
      Assert:IsNull(INDEX(undef, "c")).
      Assert:IsNull(INDEX("asdf", undef)).
      
      DEFINE VARIABLE searchIn AS LONGCHAR NO-UNDO.
      DEFINE VARIABLE searchString AS LONGCHAR NO-UNDO.
      searchIn = "abcd".
      searchString = "c".

      Assert:Equals(3, INDEX(searchIn, "c")).
      Assert:Equals(3, INDEX("abcd", searchString)).
      Assert:Equals(3, INDEX(searchIn, searchString)).

      Assert:Equals(0, INDEX(searchIn, "c", 1073741823)).
      
      // Not found cases
      Assert:Equals(0, INDEX(searchIn, "e")).
      Assert:Equals(0, INDEX("qwerty", searchString)).
      
      // Empty string cases
      searchString = "".
      Assert:Equals(0, INDEX(searchString, "e")).
      Assert:Equals(0, INDEX("cbcd", searchString)).
      
   END METHOD.

   /**
    * Tests for failed INDEX function invocation for CHARACTER arguments
    */
   @Test.
   METHOD PUBLIC VOID TestCharacterFailure():
      DEFINE VARIABLE idx AS INTEGER NO-UNDO.
      idx = INDEX("cbcd", "c", 0) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      idx = INDEX("cbcd", "c", -1) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      idx = INDEX("cbcd", "c", -32000) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      idx = INDEX("cbcd", "c", 32001) NO-ERROR. testFailure(). Assert:Equals(0, idx).
   END METHOD.

   /**
    * Tests for failed INDEX function invocation for LONGCHAR arguments
    */
   @Test.
   METHOD PUBLIC VOID TestLongcharFailure():
      DEFINE VARIABLE searchIn AS LONGCHAR NO-UNDO.
      DEFINE VARIABLE searchString AS LONGCHAR NO-UNDO.
      searchIn = "abcd".
      searchString = "c".

      DEFINE VARIABLE idx AS INTEGER NO-UNDO.
      idx = INDEX(searchIn, "c", 0) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      idx = INDEX("abcd", searchString, 0) NO-ERROR. testFailure(). Assert:Equals(0, idx).

      idx = INDEX(searchIn, "c", -1) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      idx = INDEX("abcd", searchString, -1) NO-ERROR. testFailure(). Assert:Equals(0, idx).

      idx = INDEX(searchIn, "c", 1073741823 + 1) NO-ERROR. testFailure(). Assert:Equals(0, idx).
      
      // Despite the official docs say, the second arg of LONGCHAR type does not increase the index limit!
      idx = INDEX("abcd", searchString, 1073741823) NO-ERROR. testFailure(). Assert:Equals(0, idx).
   END METHOD.

   /**
    * Test outcome of a failed INDEX call
    */
   METHOD PRIVATE VOID testFailure():
      Assert:IsTrue(ERROR-STATUS:ERROR).
      Assert:Equals(1, ERROR-STATUS:NUM-MESSAGES).
      Assert:Equals("The third argument to INDEX or R-INDEX must be in the range 1 to 32000 (for CHARACTER) or 1 to 1073741823 (for LONGCHAR). (4687)", ERROR-STATUS:GET-MESSAGE(1)).
   END METHOD.
END CLASS.
