blob: 2f0e9ac9277bcdc9c04d70be889413048e2106aa [file] [log] [blame]
The Android Open Source Project455ed292009-03-13 13:04:22 -07001/*
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
Daisuke Miyakawae919af52009-06-26 22:58:32 +090023#include <utils/String8.h>
24
The Android Open Source Project455ed292009-03-13 13:04:22 -070025using namespace android;
26
27class 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
Daisuke Miyakawa1ec1f3d2009-07-09 14:03:07 +090034 void testUtf32At();
Daisuke Miyakawae919af52009-06-26 22:58:32 +090035 void testGetUtf8FromUtf32();
Daisuke Miyakawad28cdc42009-05-18 14:51:52 +090036 void testGetNormalizedString();
Jeff Hamiltoncc6719f2009-09-01 00:29:12 -050037 void testLongString();
The Android Open Source Project455ed292009-03-13 13:04:22 -070038
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
65bool TestExecutor::DoAllTests() {
Daisuke Miyakawa1ec1f3d2009-07-09 14:03:07 +090066 DoOneTest(&TestExecutor::testUtf32At);
Daisuke Miyakawae919af52009-06-26 22:58:32 +090067 DoOneTest(&TestExecutor::testGetUtf8FromUtf32);
Daisuke Miyakawad28cdc42009-05-18 14:51:52 +090068 DoOneTest(&TestExecutor::testGetNormalizedString);
Jeff Hamiltoncc6719f2009-09-01 00:29:12 -050069 DoOneTest(&TestExecutor::testLongString);
The Android Open Source Project455ed292009-03-13 13:04:22 -070070
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
80void 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
Daisuke Miyakawae919af52009-06-26 22:58:32 +090089#define TEST_GET_UTF32AT(src, index, expected_next, expected_value) \
90 ({ \
91 size_t next; \
Daisuke Miyakawa1ec1f3d2009-07-09 14:03:07 +090092 int32_t ret = utf32_at(src, strlen(src), index, &next); \
Daisuke Miyakawae919af52009-06-26 22:58:32 +090093 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 })
The Android Open Source Project455ed292009-03-13 13:04:22 -0700104
Daisuke Miyakawa1ec1f3d2009-07-09 14:03:07 +0900105void TestExecutor::testUtf32At() {
106 printf("testUtf32At()\n");
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900107
108 TEST_GET_UTF32AT("a", 0, 1, 97);
The Android Open Source Project455ed292009-03-13 13:04:22 -0700109 // Japanese hiragana "a"
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900110 TEST_GET_UTF32AT("\xE3\x81\x82", 0, 3, 0x3042);
The Android Open Source Project455ed292009-03-13 13:04:22 -0700111 // Japanese fullwidth katakana "a" with ascii a
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900112 TEST_GET_UTF32AT("a\xE3\x82\xA2", 1, 4, 0x30A2);
The Android Open Source Project455ed292009-03-13 13:04:22 -0700113
114 // 2 PUA
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900115 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);
The Android Open Source Project455ed292009-03-13 13:04:22 -0700117}
118
The Android Open Source Project455ed292009-03-13 13:04:22 -0700119
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900120#define EXPECT_EQ_CODEPOINT_UTF8(codepoint, expected) \
The Android Open Source Project455ed292009-03-13 13:04:22 -0700121 ({ \
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900122 char32_t codepoints[1] = {codepoint}; \
123 status_t ret = string8.setTo(codepoints, 1); \
124 if (ret != NO_ERROR) { \
The Android Open Source Project455ed292009-03-13 13:04:22 -0700125 printf("GetUtf8FromCodePoint() returned false at 0x%04X\n", codepoint); \
126 m_success = false; \
The Android Open Source Project455ed292009-03-13 13:04:22 -0700127 } else { \
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900128 const char* string = string8.string(); \
129 if (strcmp(string, expected) != 0) { \
The Android Open Source Project455ed292009-03-13 13:04:22 -0700130 printf("Failed at codepoint 0x%04X\n", codepoint); \
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900131 for (const char *ch = string; *ch != '\0'; ++ch) { \
The Android Open Source Project455ed292009-03-13 13:04:22 -0700132 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
Daisuke Miyakawae919af52009-06-26 22:58:32 +0900144void TestExecutor::testGetUtf8FromUtf32() {
145 printf("testGetUtf8FromUtf32()\n");
146 String8 string8;
The Android Open Source Project455ed292009-03-13 13:04:22 -0700147
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");
The Android Open Source Project455ed292009-03-13 13:04:22 -0700158}
159
160#define EXPECT_EQ_UTF8_UTF8(src, expected) \
161 ({ \
Daisuke Miyakawad28cdc42009-05-18 14:51:52 +0900162 if (!GetNormalizedString(src, &dst, &len)) { \
Daisuke Miyakawa560b9512010-03-17 10:32:46 +0900163 printf("GetNormalizedSortableString() returned false.\n"); \
Daisuke Miyakawad28cdc42009-05-18 14:51:52 +0900164 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
181void 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
Jeff Hamiltoncc6719f2009-09-01 00:29:12 -0500201void TestExecutor::testLongString() {
202 printf("testLongString()\n");
203 char * dst;
204 size_t len;
205 EXPECT_EQ_UTF8_UTF8("Qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqtttttttttttttttttttttttttttttttttttttttttttttttttgggggggggggggggggggggggggggggggggggggggbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
206 "Qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqtttttttttttttttttttttttttttttttttttttttttttttttttggggggggggggggggggggggggggggggggggg");
207}
208
209
The Android Open Source Project455ed292009-03-13 13:04:22 -0700210int main() {
211 TestExecutor executor;
212 if(executor.DoAllTests()) {
213 return 0;
214 } else {
215 return 1;
216 }
217}