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:
TestExecutor()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
DoAllTests()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
DoOneTest(void (TestExecutor::* test)())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
testUtf32At()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
testGetUtf8FromUtf32()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
testGetNormalizedString()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
testLongString()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
main()210 int main() {
211 TestExecutor executor;
212 if(executor.DoAllTests()) {
213 return 0;
214 } else {
215 return 1;
216 }
217 }
218