- add sources.
[platform/framework/web/crosswalk.git] / src / ppapi / tests / test_char_set.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ppapi/tests/test_char_set.h"
6
7 #include "ppapi/c/dev/ppb_char_set_dev.h"
8 #include "ppapi/c/trusted/ppb_char_set_trusted.h"
9 #include "ppapi/cpp/dev/memory_dev.h"
10 #include "ppapi/cpp/module.h"
11 #include "ppapi/tests/testing_instance.h"
12
13 REGISTER_TEST_CASE(CharSet);
14
15 TestCharSet::TestCharSet(TestingInstance* instance)
16     : TestCase(instance),
17       char_set_interface_(NULL) {
18 }
19
20 bool TestCharSet::Init() {
21   char_set_interface_ = static_cast<const PPB_CharSet_Dev*>(
22       pp::Module::Get()->GetBrowserInterface(PPB_CHAR_SET_DEV_INTERFACE));
23   char_set_trusted_interface_ = static_cast<const PPB_CharSet_Trusted*>(
24       pp::Module::Get()->GetBrowserInterface(PPB_CHARSET_TRUSTED_INTERFACE));
25   return char_set_interface_ && char_set_trusted_interface_;
26 }
27
28 void TestCharSet::RunTests(const std::string& filter) {
29   RUN_TEST(UTF16ToCharSetDeprecated, filter);
30   RUN_TEST(UTF16ToCharSet, filter);
31   RUN_TEST(CharSetToUTF16Deprecated, filter);
32   RUN_TEST(CharSetToUTF16, filter);
33   RUN_TEST(GetDefaultCharSet, filter);
34 }
35
36 // TODO(brettw) remove this when the old interface is removed.
37 std::string TestCharSet::TestUTF16ToCharSetDeprecated() {
38   // Empty string.
39   std::vector<uint16_t> utf16;
40   utf16.push_back(0);
41   uint32_t utf8result_len = 0;
42   pp::Memory_Dev memory;
43   char* utf8result = char_set_interface_->UTF16ToCharSet(
44       instance_->pp_instance(), &utf16[0], 0, "latin1",
45       PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
46   ASSERT_TRUE(utf8result);
47   ASSERT_TRUE(utf8result[0] == 0);
48   ASSERT_TRUE(utf8result_len == 0);
49   memory.MemFree(utf8result);
50
51   // Try round-tripping some English & Chinese from UTF-8 through UTF-16
52   std::string utf8source("Hello, world. \xe4\xbd\xa0\xe5\xa5\xbd");
53   utf16 = UTF8ToUTF16(utf8source);
54   utf8result = char_set_interface_->UTF16ToCharSet(
55       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
56       "Utf-8", PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
57   ASSERT_TRUE(utf8source == std::string(utf8result, utf8result_len));
58   memory.MemFree(utf8result);
59
60   // Test an un-encodable character with various modes.
61   utf16 = UTF8ToUTF16("h\xe4\xbd\xa0i");
62
63   // Fail mode.
64   utf8result_len = 1234;  // Test that this gets 0'ed on failure.
65   utf8result = char_set_interface_->UTF16ToCharSet(
66       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
67       "latin1", PP_CHARSET_CONVERSIONERROR_FAIL, &utf8result_len);
68   ASSERT_TRUE(utf8result_len == 0);
69   ASSERT_TRUE(utf8result == NULL);
70
71   // Skip mode.
72   utf8result = char_set_interface_->UTF16ToCharSet(
73       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
74       "latin1", PP_CHARSET_CONVERSIONERROR_SKIP, &utf8result_len);
75   ASSERT_TRUE(utf8result_len == 2);
76   ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == 'i' &&
77               utf8result[2] == 0);
78   memory.MemFree(utf8result);
79
80   // Substitute mode.
81   utf8result = char_set_interface_->UTF16ToCharSet(
82       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
83       "latin1", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
84   ASSERT_TRUE(utf8result_len == 3);
85   ASSERT_TRUE(utf8result[0] == 'h' && utf8result[1] == '?' &&
86               utf8result[2] == 'i' && utf8result[3] == 0);
87   memory.MemFree(utf8result);
88
89   // Try some invalid input encoding.
90   utf16.clear();
91   utf16.push_back(0xD800);  // High surrogate.
92   utf16.push_back('A');  // Not a low surrogate.
93   utf8result = char_set_interface_->UTF16ToCharSet(
94       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
95       "latin1", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
96   ASSERT_TRUE(utf8result_len == 2);
97   ASSERT_TRUE(utf8result[0] == '?' && utf8result[1] == 'A' &&
98               utf8result[2] == 0);
99   memory.MemFree(utf8result);
100
101   // Invalid encoding name.
102   utf8result = char_set_interface_->UTF16ToCharSet(
103       instance_->pp_instance(), &utf16[0], static_cast<uint32_t>(utf16.size()),
104       "poopiepants", PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf8result_len);
105   ASSERT_TRUE(!utf8result);
106   ASSERT_TRUE(utf8result_len == 0);
107
108   PASS();
109 }
110
111 std::string TestCharSet::TestUTF16ToCharSet() {
112   // Empty string.
113   std::vector<uint16_t> utf16;
114   utf16.push_back(0);
115   std::string output_buffer;
116   output_buffer.resize(1);
117   uint32_t utf8result_len = 0;
118   PP_Bool result = char_set_trusted_interface_->UTF16ToCharSet(
119       &utf16[0], 0, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
120       &output_buffer[0], &utf8result_len);
121   ASSERT_TRUE(result == PP_TRUE);
122   ASSERT_TRUE(utf8result_len == 0);
123
124   // No output buffer returns length of string.
125   utf16 = UTF8ToUTF16("hello");
126   utf8result_len = 0;
127   result = char_set_trusted_interface_->UTF16ToCharSet(
128       &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
129       PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE, NULL, &utf8result_len);
130   ASSERT_TRUE(result == PP_TRUE);
131   ASSERT_TRUE(utf8result_len == 5);
132
133   // Giving too small of a buffer just fills in that many items and gives us
134   // the desired size.
135   output_buffer.resize(100);
136   utf8result_len = 2;
137   output_buffer[utf8result_len] = '$';  // Barrier character.
138   result = char_set_trusted_interface_->UTF16ToCharSet(
139       &utf16[0], static_cast<uint32_t>(utf16.size()), "latin1",
140       PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
141       &output_buffer[0], &utf8result_len);
142   ASSERT_TRUE(result == PP_TRUE);
143   ASSERT_TRUE(utf8result_len == 5);
144   ASSERT_TRUE(output_buffer[0] == 'h' && output_buffer[1] == 'e' &&
145               output_buffer[2] == '$');
146
147   // Try round-tripping some English & Chinese from UTF-8 through UTF-16
148   std::string utf8source("Hello, world. \xe4\xbd\xa0\xe5\xa5\xbd");
149   utf16 = UTF8ToUTF16(utf8source);
150   output_buffer.resize(100);
151   utf8result_len = static_cast<uint32_t>(output_buffer.size());
152   result = char_set_trusted_interface_->UTF16ToCharSet(
153       &utf16[0], static_cast<uint32_t>(utf16.size()),
154       "Utf-8", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
155       &output_buffer[0], &utf8result_len);
156   ASSERT_TRUE(result == PP_TRUE);
157   output_buffer.resize(utf8result_len);
158   ASSERT_TRUE(utf8source == output_buffer);
159
160   // Test an un-encodable character with various modes.
161   utf16 = UTF8ToUTF16("h\xe4\xbd\xa0i");
162
163   // Fail mode, size should get 0'ed on failure.
164   output_buffer.resize(100);
165   utf8result_len = static_cast<uint32_t>(output_buffer.size());
166   result = char_set_trusted_interface_->UTF16ToCharSet(
167       &utf16[0], static_cast<uint32_t>(utf16.size()),
168       "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
169       &output_buffer[0], &utf8result_len);
170   ASSERT_TRUE(result == PP_FALSE);
171   ASSERT_TRUE(utf8result_len == 0);
172
173   // Skip mode.
174   output_buffer.resize(100);
175   utf8result_len = static_cast<uint32_t>(output_buffer.size());
176   result = char_set_trusted_interface_->UTF16ToCharSet(
177       &utf16[0], static_cast<uint32_t>(utf16.size()),
178       "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP,
179       &output_buffer[0], &utf8result_len);
180   ASSERT_TRUE(result == PP_TRUE);
181   ASSERT_TRUE(utf8result_len == 2);
182   ASSERT_TRUE(output_buffer[0] == 'h' && output_buffer[1] == 'i');
183
184   // Substitute mode.
185   output_buffer.resize(100);
186   utf8result_len = static_cast<uint32_t>(output_buffer.size());
187   result = char_set_trusted_interface_->UTF16ToCharSet(
188       &utf16[0], static_cast<uint32_t>(utf16.size()),
189       "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
190       &output_buffer[0], &utf8result_len);
191   ASSERT_TRUE(result == PP_TRUE);
192   ASSERT_TRUE(utf8result_len == 3);
193   output_buffer.resize(utf8result_len);
194   ASSERT_TRUE(output_buffer == "h?i");
195
196   // Try some invalid input encoding.
197   output_buffer.resize(100);
198   utf8result_len = static_cast<uint32_t>(output_buffer.size());
199   utf16.clear();
200   utf16.push_back(0xD800);  // High surrogate.
201   utf16.push_back('A');  // Not a low surrogate.
202   result = char_set_trusted_interface_->UTF16ToCharSet(
203       &utf16[0], static_cast<uint32_t>(utf16.size()),
204       "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
205       &output_buffer[0], &utf8result_len);
206   ASSERT_TRUE(result == PP_TRUE);
207   ASSERT_TRUE(utf8result_len == 2);
208   ASSERT_TRUE(output_buffer[0] == '?' && output_buffer[1] == 'A');
209
210   // Invalid encoding name.
211   output_buffer.resize(100);
212   utf8result_len = static_cast<uint32_t>(output_buffer.size());
213   result = char_set_trusted_interface_->UTF16ToCharSet(
214       &utf16[0], static_cast<uint32_t>(utf16.size()),
215       "poopiepants", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
216       &output_buffer[0], &utf8result_len);
217   ASSERT_TRUE(result == PP_FALSE);
218   ASSERT_TRUE(utf8result_len == 0);
219
220   PASS();
221 }
222
223 // TODO(brettw) remove this when the old interface is removed.
224 std::string TestCharSet::TestCharSetToUTF16Deprecated() {
225   pp::Memory_Dev memory;
226
227   // Empty string.
228   uint32_t utf16result_len;
229   uint16_t* utf16result = char_set_interface_->CharSetToUTF16(
230       instance_->pp_instance(), "", 0, "latin1",
231       PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
232   ASSERT_TRUE(utf16result);
233   ASSERT_TRUE(utf16result_len == 0);
234   ASSERT_TRUE(utf16result[0] == 0);
235   memory.MemFree(utf16result);
236
237   // Basic Latin1.
238   char latin1[] = "H\xef";
239   utf16result = char_set_interface_->CharSetToUTF16(
240       instance_->pp_instance(), latin1, 2, "latin1",
241       PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
242   ASSERT_TRUE(utf16result);
243   ASSERT_TRUE(utf16result_len == 2);
244   ASSERT_TRUE(utf16result[0] == 'H' && utf16result[1] == 0xef &&
245               utf16result[2] == 0);
246   memory.MemFree(utf16result);
247
248   // Invalid input encoding with FAIL.
249   char badutf8[] = "A\xe4Z";
250   utf16result = char_set_interface_->CharSetToUTF16(
251       instance_->pp_instance(), badutf8, 3, "utf8",
252       PP_CHARSET_CONVERSIONERROR_FAIL, &utf16result_len);
253   ASSERT_TRUE(!utf16result);
254   ASSERT_TRUE(utf16result_len == 0);
255   memory.MemFree(utf16result);
256
257   // Invalid input with SKIP.
258   utf16result = char_set_interface_->CharSetToUTF16(
259       instance_->pp_instance(), badutf8, 3, "utf8",
260       PP_CHARSET_CONVERSIONERROR_SKIP, &utf16result_len);
261   ASSERT_TRUE(utf16result);
262   ASSERT_TRUE(utf16result_len == 2);
263   ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 'Z' &&
264               utf16result[2] == 0);
265   memory.MemFree(utf16result);
266
267   // Invalid input with SUBSTITUTE.
268   utf16result = char_set_interface_->CharSetToUTF16(
269       instance_->pp_instance(), badutf8, 3, "utf8",
270       PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf16result_len);
271   ASSERT_TRUE(utf16result);
272   ASSERT_TRUE(utf16result_len == 3);
273   ASSERT_TRUE(utf16result[0] == 'A' && utf16result[1] == 0xFFFD &&
274               utf16result[2] == 'Z' && utf16result[3] == 0);
275   memory.MemFree(utf16result);
276
277   // Invalid encoding name.
278   utf16result = char_set_interface_->CharSetToUTF16(
279       instance_->pp_instance(), badutf8, 3, "poopiepants",
280       PP_CHARSET_CONVERSIONERROR_SUBSTITUTE, &utf16result_len);
281   ASSERT_TRUE(!utf16result);
282   ASSERT_TRUE(utf16result_len == 0);
283   memory.MemFree(utf16result);
284
285   PASS();
286 }
287
288 std::string TestCharSet::TestCharSetToUTF16() {
289   std::vector<uint16_t> output_buffer;
290   output_buffer.resize(100);
291
292   // Empty string.
293   output_buffer.resize(100);
294   uint32_t utf16result_len = static_cast<uint32_t>(output_buffer.size());
295   PP_Bool result = char_set_trusted_interface_->CharSetToUTF16(
296       "", 0, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
297       &output_buffer[0], &utf16result_len);
298   ASSERT_TRUE(result);
299   ASSERT_TRUE(utf16result_len == 0);
300   ASSERT_TRUE(output_buffer[0] == 0);
301
302   // Basic Latin1.
303   output_buffer.resize(100);
304   utf16result_len = static_cast<uint32_t>(output_buffer.size());
305   char latin1[] = "H\xef";
306   result = char_set_trusted_interface_->CharSetToUTF16(
307       latin1, 2, "latin1", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
308       &output_buffer[0], &utf16result_len);
309   ASSERT_TRUE(result);
310   ASSERT_TRUE(utf16result_len == 2);
311   ASSERT_TRUE(output_buffer[0] == 'H' && output_buffer[1] == 0xef);
312
313   // Invalid input encoding with FAIL.
314   output_buffer.resize(100);
315   utf16result_len = static_cast<uint32_t>(output_buffer.size());
316   char badutf8[] = "A\xe4Z";
317   result = char_set_trusted_interface_->CharSetToUTF16(
318       badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_FAIL,
319       &output_buffer[0], &utf16result_len);
320   ASSERT_TRUE(!result);
321   ASSERT_TRUE(utf16result_len == 0);
322
323   // Invalid input with SKIP.
324   output_buffer.resize(100);
325   utf16result_len = static_cast<uint32_t>(output_buffer.size());
326   result = char_set_trusted_interface_->CharSetToUTF16(
327       badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_SKIP,
328       &output_buffer[0], &utf16result_len);
329   ASSERT_TRUE(result);
330   ASSERT_TRUE(utf16result_len == 2);
331   ASSERT_TRUE(output_buffer[0] == 'A' && output_buffer[1] == 'Z');
332
333   // Invalid input with SUBSTITUTE.
334   output_buffer.resize(100);
335   utf16result_len = static_cast<uint32_t>(output_buffer.size());
336   result = char_set_trusted_interface_->CharSetToUTF16(
337       badutf8, 3, "utf8", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
338       &output_buffer[0], &utf16result_len);
339   ASSERT_TRUE(result);
340   ASSERT_TRUE(utf16result_len == 3);
341   ASSERT_TRUE(output_buffer[0] == 'A' && output_buffer[1] == 0xFFFD &&
342               output_buffer[2] == 'Z');
343
344   // Invalid encoding name.
345   output_buffer.resize(100);
346   utf16result_len = static_cast<uint32_t>(output_buffer.size());
347   result = char_set_trusted_interface_->CharSetToUTF16(
348       badutf8, 3, "poopiepants", PP_CHARSET_TRUSTED_CONVERSIONERROR_SUBSTITUTE,
349       &output_buffer[0], &utf16result_len);
350   ASSERT_TRUE(!result);
351   ASSERT_TRUE(utf16result_len == 0);
352
353   PASS();
354 }
355
356 std::string TestCharSet::TestGetDefaultCharSet() {
357   // Test invalid instance.
358   pp::Var result(pp::PASS_REF, char_set_interface_->GetDefaultCharSet(0));
359   ASSERT_TRUE(result.is_undefined());
360
361   // Just make sure the default char set is a nonempty string.
362   result = pp::Var(pp::PASS_REF,
363       char_set_interface_->GetDefaultCharSet(instance_->pp_instance()));
364   ASSERT_TRUE(result.is_string());
365   ASSERT_FALSE(result.AsString().empty());
366
367   PASS();
368 }
369
370 std::vector<uint16_t> TestCharSet::UTF8ToUTF16(const std::string& utf8) {
371   uint32_t result_len = 0;
372   uint16_t* result = char_set_interface_->CharSetToUTF16(
373       instance_->pp_instance(), utf8.c_str(),
374       static_cast<uint32_t>(utf8.size()),
375       "utf-8", PP_CHARSET_CONVERSIONERROR_FAIL, &result_len);
376
377   std::vector<uint16_t> result_vector;
378   if (!result)
379     return result_vector;
380
381   result_vector.assign(result, &result[result_len]);
382   pp::Memory_Dev memory;
383   memory.MemFree(result);
384   return result_vector;
385 }