Home | History | Annotate | Download | only in android
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "PhoneticStringUtils.h"
     18 
     19 #include <stdio.h>
     20 #include <stdlib.h>
     21 #include <string.h>
     22 
     23 #include <utils/String8.h>
     24 
     25 using namespace android;
     26 
     27 class TestExecutor {
     28  public:
     29   TestExecutor() : m_total_count(0), m_success_count(0), m_success(true) {}
     30   bool DoAllTests();
     31  private:
     32   void DoOneTest(void (TestExecutor::*test)());
     33 
     34   void testUtf32At();
     35   void testGetUtf8FromUtf32();
     36   void testGetNormalizedString();
     37   void testLongString();
     38 
     39   // Note: When adding a test, do not forget to add it to DoOneTest().
     40 
     41   int m_total_count;
     42   int m_success_count;
     43 
     44   bool m_success;
     45 };
     46 
     47 #define ASSERT_EQ_VALUE(input, expected)                                \
     48   ({                                                                    \
     49     if ((expected) != (input)) {                                        \
     50       printf("0x%X(result) != 0x%X(expected)\n", input, expected);      \
     51       m_success = false;                                                \
     52       return;                                                           \
     53     }                                                                   \
     54   })
     55 
     56 #define EXPECT_EQ_VALUE(input, expected)                                \
     57   ({                                                                    \
     58     if ((expected) != (input)) {                                        \
     59       printf("0x%X(result) != 0x%X(expected)\n", input, expected);      \
     60       m_success = false;                                                \
     61     }                                                                   \
     62   })
     63 
     64 
     65 bool TestExecutor::DoAllTests() {
     66   DoOneTest(&TestExecutor::testUtf32At);
     67   DoOneTest(&TestExecutor::testGetUtf8FromUtf32);
     68   DoOneTest(&TestExecutor::testGetNormalizedString);
     69   DoOneTest(&TestExecutor::testLongString);
     70 
     71   printf("Test total: %d\nSuccess: %d\nFailure: %d\n",
     72          m_total_count, m_success_count, m_total_count - m_success_count);
     73 
     74   bool success = m_total_count == m_success_count;
     75   printf("\n%s\n", success ? "Success" : "Failure");
     76 
     77   return success;
     78 }
     79 
     80 void TestExecutor::DoOneTest(void (TestExecutor::*test)()) {
     81   m_success = true;
     82 
     83   (this->*test)();
     84 
     85   ++m_total_count;
     86   m_success_count += m_success ? 1 : 0;
     87 }
     88 
     89 #define TEST_GET_UTF32AT(src, index, expected_next, expected_value)     \
     90   ({                                                                    \
     91     size_t next;                                                        \
     92     int32_t ret = utf32_from_utf8_at(src, strlen(src), index, &next);   \
     93     if (ret < 0) {                                                      \
     94       printf("getUtf32At() returned negative value (src: %s, index: %d)\n", \
     95              (src), (index));                                           \
     96       m_success = false;                                                \
     97     } else if (next != (expected_next)) {                               \
     98       printf("next is unexpected value (src: %s, actual: %u, expected: %u)\n", \
     99              (src), next, (expected_next));                             \
    100     } else {                                                            \
    101       EXPECT_EQ_VALUE(ret, (expected_value));                           \
    102     }                                                                   \
    103    })
    104 
    105 void TestExecutor::testUtf32At() {
    106   printf("testUtf32At()\n");
    107 
    108   TEST_GET_UTF32AT("a", 0, 1, 97);
    109   // Japanese hiragana "a"
    110   TEST_GET_UTF32AT("\xE3\x81\x82", 0, 3, 0x3042);
    111   // Japanese fullwidth katakana "a" with ascii a
    112   TEST_GET_UTF32AT("a\xE3\x82\xA2", 1, 4, 0x30A2);
    113 
    114   // 2 PUA
    115   TEST_GET_UTF32AT("\xF3\xBE\x80\x80\xF3\xBE\x80\x88", 0, 4, 0xFE000);
    116   TEST_GET_UTF32AT("\xF3\xBE\x80\x80\xF3\xBE\x80\x88", 4, 8, 0xFE008);
    117 }
    118 
    119 
    120 #define EXPECT_EQ_CODEPOINT_UTF8(codepoint, expected)                   \
    121   ({                                                                    \
    122     char32_t codepoints[1] = {codepoint};                                \
    123     status_t ret = string8.setTo(codepoints, 1);                        \
    124     if (ret != NO_ERROR) {                                              \
    125       printf("GetUtf8FromCodePoint() returned false at 0x%04X\n", codepoint); \
    126       m_success = false;                                                \
    127     } else {                                                            \
    128       const char* string = string8.string();                            \
    129       if (strcmp(string, expected) != 0) {                              \
    130         printf("Failed at codepoint 0x%04X\n", codepoint);              \
    131         for (const char *ch = string; *ch != '\0'; ++ch) {              \
    132           printf("0x%X ", *ch);                                         \
    133         }                                                               \
    134         printf("!= ");                                                  \
    135         for (const char *ch = expected; *ch != '\0'; ++ch) {            \
    136           printf("0x%X ", *ch);                                         \
    137         }                                                               \
    138         printf("\n");                                                   \
    139         m_success = false;                                              \
    140       }                                                                 \
    141     }                                                                   \
    142   })
    143 
    144 void TestExecutor::testGetUtf8FromUtf32() {
    145   printf("testGetUtf8FromUtf32()\n");
    146   String8 string8;
    147 
    148   EXPECT_EQ_CODEPOINT_UTF8('a', "\x61");
    149   // Armenian capital letter AYB (2 bytes in UTF8)
    150   EXPECT_EQ_CODEPOINT_UTF8(0x0530, "\xD4\xB0");
    151   // Japanese 'a' (3 bytes in UTF8)
    152   EXPECT_EQ_CODEPOINT_UTF8(0x3042, "\xE3\x81\x82");
    153   // Kanji
    154   EXPECT_EQ_CODEPOINT_UTF8(0x65E5, "\xE6\x97\xA5");
    155   // PUA (4 byets in UTF8)
    156   EXPECT_EQ_CODEPOINT_UTF8(0xFE016, "\xF3\xBE\x80\x96");
    157   EXPECT_EQ_CODEPOINT_UTF8(0xFE972, "\xF3\xBE\xA5\xB2");
    158 }
    159 
    160 #define EXPECT_EQ_UTF8_UTF8(src, expected)                              \
    161   ({                                                                    \
    162     if (!GetNormalizedString(src, &dst, &len)) {                        \
    163       printf("GetNormalizedSortableString() returned false.\n");      \
    164       m_success = false;                                                \
    165     } else {                                                            \
    166       if (strcmp(dst, expected) != 0) {                                 \
    167         for (const char *ch = dst; *ch != '\0'; ++ch) {                 \
    168           printf("0x%X ", *ch);                                         \
    169         }                                                               \
    170         printf("!= ");                                                  \
    171         for (const char *ch = expected; *ch != '\0'; ++ch) {            \
    172           printf("0x%X ", *ch);                                         \
    173         }                                                               \
    174         printf("\n");                                                   \
    175         m_success = false;                                              \
    176       }                                                                 \
    177       free(dst);                                                        \
    178     }                                                                   \
    179    })
    180 
    181 void TestExecutor::testGetNormalizedString() {
    182   printf("testGetNormalizedString()\n");
    183   char *dst;
    184   size_t len;
    185 
    186   // halfwidth alphabets/symbols -> keep it as is.
    187   EXPECT_EQ_UTF8_UTF8("ABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%^&'()",
    188                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$%^&'()");
    189   EXPECT_EQ_UTF8_UTF8("abcdefghijklmnopqrstuvwxyz[]{}\\@/",
    190                       "abcdefghijklmnopqrstuvwxyz[]{}\\@/");
    191 
    192   // halfwidth/fullwidth-katakana -> hiragana
    193   EXPECT_EQ_UTF8_UTF8(
    194       "\xE3\x81\x82\xE3\x82\xA4\xE3\x81\x86\xEF\xBD\xB4\xE3\x82\xAA",
    195       "\xE3\x81\x82\xE3\x81\x84\xE3\x81\x86\xE3\x81\x88\xE3\x81\x8A");
    196 
    197   // whitespace -> keep it as is.
    198   EXPECT_EQ_UTF8_UTF8("    \t", "    \t");
    199 }
    200 
    201 void TestExecutor::testLongString() {
    202   printf("testLongString()\n");
    203   char * dst;
    204   size_t len;
    205   EXPECT_EQ_UTF8_UTF8("Qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqtttttttttttttttttttttttttttttttttttttttttttttttttgggggggggggggggggggggggggggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
    206       "Qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqtttttttttttttttttttttttttttttttttttttttttttttttttggggggggggggggggggggggggggggggggggg");
    207 }
    208 
    209 
    210 int main() {
    211   TestExecutor executor;
    212   if(executor.DoAllTests()) {
    213     return 0;
    214   } else {
    215     return 1;
    216   }
    217 }
    218